Spaces:
Runtime error
Runtime error
| import torch | |
| import torch.nn as nn | |
| import numpy as np | |
| # let us run this cell only if CUDA is available | |
| # We will use ``torch.device`` objects to move tensors in and out of GPU | |
| if torch.cuda.is_available(): | |
| x = torch.randn(1) | |
| device = torch.device("cuda") # a CUDA device object | |
| y = torch.ones_like(x, device=device) # directly create a tensor on GPU | |
| x = x.to(device) # or just use strings ``.to("cuda")`` | |
| z = x + y | |
| print(z) | |
| print(z.to("cpu", torch.double)) # ``.to`` can also change dtype together! | |
| class YoloLayer(nn.Module): | |
| def __init__(self, anchor_mask=[], num_classes=0, anchors=[], num_anchors=1): | |
| super(YoloLayer, self).__init__() | |
| self.anchor_mask = anchor_mask | |
| self.num_classes = num_classes | |
| self.anchors = anchors | |
| self.num_anchors = num_anchors | |
| self.anchor_step = len(anchors)/num_anchors | |
| self.coord_scale = 1 | |
| self.noobject_scale = 1 | |
| self.object_scale = 5 | |
| self.class_scale = 1 | |
| self.thresh = 0.6 | |
| self.stride = 32 | |
| self.seen = 0 | |
| def forward(self, output, nms_thresh): | |
| self.thresh = nms_thresh | |
| masked_anchors = [] | |
| for m in self.anchor_mask: | |
| masked_anchors += self.anchors[m*self.anchor_step:(m+1)*self.anchor_step] | |
| masked_anchors = [anchor/self.stride for anchor in masked_anchors] | |
| boxes = get_region_boxes(output.data, self.thresh, self.num_classes, masked_anchors, len(self.anchor_mask)) | |
| return boxes | |
| class Upsample(nn.Module): | |
| def __init__(self, stride=2): | |
| super(Upsample, self).__init__() | |
| self.stride = stride | |
| def forward(self, x): | |
| stride = self.stride | |
| assert(x.data.dim() == 4) | |
| B = x.data.size(0) | |
| C = x.data.size(1) | |
| H = x.data.size(2) | |
| W = x.data.size(3) | |
| ws = stride | |
| hs = stride | |
| x = x.view(B, C, H, 1, W, 1).expand(B, C, H, stride, W, stride).contiguous().view(B, C, H*stride, W*stride) | |
| return x | |
| #for route and shortcut | |
| class EmptyModule(nn.Module): | |
| def __init__(self): | |
| super(EmptyModule, self).__init__() | |
| def forward(self, x): | |
| return x | |
| # support route shortcut | |
| class Darknet(nn.Module): | |
| def __init__(self, cfgfile): | |
| super(Darknet, self).__init__() | |
| self.blocks = parse_cfg(cfgfile) | |
| self.models = self.create_network(self.blocks) # merge conv, bn,leaky | |
| self.loss = self.models[len(self.models)-1] | |
| self.width = int(self.blocks[0]['width']) | |
| self.height = int(self.blocks[0]['height']) | |
| self.header = torch.IntTensor([0,0,0,0]) | |
| self.seen = 0 | |
| def forward(self, x, nms_thresh): | |
| ind = -2 | |
| self.loss = None | |
| outputs = dict() | |
| out_boxes = [] | |
| for block in self.blocks: | |
| ind = ind + 1 | |
| if block['type'] == 'net': | |
| continue | |
| elif block['type'] in ['convolutional', 'upsample']: | |
| x = self.models[ind](x) | |
| outputs[ind] = x | |
| elif block['type'] == 'route': | |
| layers = block['layers'].split(',') | |
| layers = [int(i) if int(i) > 0 else int(i)+ind for i in layers] | |
| if len(layers) == 1: | |
| x = outputs[layers[0]] | |
| outputs[ind] = x | |
| elif len(layers) == 2: | |
| x1 = outputs[layers[0]] | |
| x2 = outputs[layers[1]] | |
| x = torch.cat((x1,x2),1) | |
| outputs[ind] = x | |
| elif block['type'] == 'shortcut': | |
| from_layer = int(block['from']) | |
| activation = block['activation'] | |
| from_layer = from_layer if from_layer > 0 else from_layer + ind | |
| x1 = outputs[from_layer] | |
| x2 = outputs[ind-1] | |
| x = x1 + x2 | |
| outputs[ind] = x | |
| elif block['type'] == 'yolo': | |
| boxes = self.models[ind](x, nms_thresh) | |
| out_boxes.append(boxes) | |
| else: | |
| print('unknown type %s' % (block['type'])) | |
| return out_boxes | |
| def print_network(self): | |
| print_cfg(self.blocks) | |
| def create_network(self, blocks): | |
| models = nn.ModuleList() | |
| prev_filters = 3 | |
| out_filters =[] | |
| prev_stride = 1 | |
| out_strides = [] | |
| conv_id = 0 | |
| for block in blocks: | |
| if block['type'] == 'net': | |
| prev_filters = int(block['channels']) | |
| continue | |
| elif block['type'] == 'convolutional': | |
| conv_id = conv_id + 1 | |
| batch_normalize = int(block['batch_normalize']) | |
| filters = int(block['filters']) | |
| kernel_size = int(block['size']) | |
| stride = int(block['stride']) | |
| is_pad = int(block['pad']) | |
| pad = (kernel_size-1)//2 if is_pad else 0 | |
| activation = block['activation'] | |
| model = nn.Sequential() | |
| if batch_normalize: | |
| model.add_module('conv{0}'.format(conv_id), nn.Conv2d(prev_filters, filters, kernel_size, stride, pad, bias=False)) | |
| model.add_module('bn{0}'.format(conv_id), nn.BatchNorm2d(filters)) | |
| else: | |
| model.add_module('conv{0}'.format(conv_id), nn.Conv2d(prev_filters, filters, kernel_size, stride, pad)) | |
| if activation == 'leaky': | |
| model.add_module('leaky{0}'.format(conv_id), nn.LeakyReLU(0.1, inplace=True)) | |
| prev_filters = filters | |
| out_filters.append(prev_filters) | |
| prev_stride = stride * prev_stride | |
| out_strides.append(prev_stride) | |
| models.append(model) | |
| elif block['type'] == 'upsample': | |
| stride = int(block['stride']) | |
| out_filters.append(prev_filters) | |
| prev_stride = prev_stride // stride | |
| out_strides.append(prev_stride) | |
| models.append(Upsample(stride)) | |
| elif block['type'] == 'route': | |
| layers = block['layers'].split(',') | |
| ind = len(models) | |
| layers = [int(i) if int(i) > 0 else int(i)+ind for i in layers] | |
| if len(layers) == 1: | |
| prev_filters = out_filters[layers[0]] | |
| prev_stride = out_strides[layers[0]] | |
| elif len(layers) == 2: | |
| assert(layers[0] == ind - 1) | |
| prev_filters = out_filters[layers[0]] + out_filters[layers[1]] | |
| prev_stride = out_strides[layers[0]] | |
| out_filters.append(prev_filters) | |
| out_strides.append(prev_stride) | |
| models.append(EmptyModule()) | |
| elif block['type'] == 'shortcut': | |
| ind = len(models) | |
| prev_filters = out_filters[ind-1] | |
| out_filters.append(prev_filters) | |
| prev_stride = out_strides[ind-1] | |
| out_strides.append(prev_stride) | |
| models.append(EmptyModule()) | |
| elif block['type'] == 'yolo': | |
| yolo_layer = YoloLayer() | |
| anchors = block['anchors'].split(',') | |
| anchor_mask = block['mask'].split(',') | |
| yolo_layer.anchor_mask = [int(i) for i in anchor_mask] | |
| yolo_layer.anchors = [float(i) for i in anchors] | |
| yolo_layer.num_classes = int(block['classes']) | |
| yolo_layer.num_anchors = int(block['num']) | |
| yolo_layer.anchor_step = len(yolo_layer.anchors)//yolo_layer.num_anchors | |
| yolo_layer.stride = prev_stride | |
| out_filters.append(prev_filters) | |
| out_strides.append(prev_stride) | |
| models.append(yolo_layer) | |
| else: | |
| print('unknown type %s' % (block['type'])) | |
| return models | |
| def load_weights(self, weightfile): | |
| print() | |
| fp = open(weightfile, 'rb') | |
| header = np.fromfile(fp, count=5, dtype=np.int32) | |
| self.header = torch.from_numpy(header) | |
| self.seen = self.header[3] | |
| buf = np.fromfile(fp, dtype = np.float32) | |
| fp.close() | |
| start = 0 | |
| ind = -2 | |
| counter = 3 | |
| for block in self.blocks: | |
| if start >= buf.size: | |
| break | |
| ind = ind + 1 | |
| if block['type'] == 'net': | |
| continue | |
| elif block['type'] == 'convolutional': | |
| model = self.models[ind] | |
| batch_normalize = int(block['batch_normalize']) | |
| if batch_normalize: | |
| start = load_conv_bn(buf, start, model[0], model[1]) | |
| else: | |
| start = load_conv(buf, start, model[0]) | |
| elif block['type'] == 'upsample': | |
| pass | |
| elif block['type'] == 'route': | |
| pass | |
| elif block['type'] == 'shortcut': | |
| pass | |
| elif block['type'] == 'yolo': | |
| pass | |
| else: | |
| print('unknown type %s' % (block['type'])) | |
| percent_comp = (counter / len(self.blocks)) * 100 | |
| print('Loading weights. Please Wait...{:.2f}% Complete'.format(percent_comp), end = '\r', flush = True) | |
| counter += 1 | |
| def convert2cpu(gpu_matrix): | |
| return torch.FloatTensor(gpu_matrix.size()).copy_(gpu_matrix) | |
| def convert2cpu_long(gpu_matrix): | |
| return torch.LongTensor(gpu_matrix.size()).copy_(gpu_matrix) | |
| def get_region_boxes(output, conf_thresh, num_classes, anchors, num_anchors, only_objectness = 1, validation = False): | |
| anchor_step = len(anchors)//num_anchors | |
| if output.dim() == 3: | |
| output = output.unsqueeze(0) | |
| batch = output.size(0) | |
| assert(output.size(1) == (5+num_classes)*num_anchors) | |
| h = output.size(2) | |
| w = output.size(3) | |
| all_boxes = [] | |
| output = output.view(batch*num_anchors, 5+num_classes, h*w).transpose(0,1).contiguous().view(5+num_classes, batch*num_anchors*h*w) | |
| grid_x = torch.linspace(0, w-1, w).repeat(h,1).repeat(batch*num_anchors, 1, 1).view(batch*num_anchors*h*w).type_as(output) #cuda() | |
| grid_y = torch.linspace(0, h-1, h).repeat(w,1).t().repeat(batch*num_anchors, 1, 1).view(batch*num_anchors*h*w).type_as(output) #cuda() | |
| xs = torch.sigmoid(output[0]) + grid_x | |
| ys = torch.sigmoid(output[1]) + grid_y | |
| anchor_w = torch.Tensor(anchors).view(num_anchors, anchor_step).index_select(1, torch.LongTensor([0])) | |
| anchor_h = torch.Tensor(anchors).view(num_anchors, anchor_step).index_select(1, torch.LongTensor([1])) | |
| anchor_w = anchor_w.repeat(batch, 1).repeat(1, 1, h*w).view(batch*num_anchors*h*w).type_as(output) #cuda() | |
| anchor_h = anchor_h.repeat(batch, 1).repeat(1, 1, h*w).view(batch*num_anchors*h*w).type_as(output) #cuda() | |
| ws = torch.exp(output[2]) * anchor_w | |
| hs = torch.exp(output[3]) * anchor_h | |
| det_confs = torch.sigmoid(output[4]) | |
| cls_confs = torch.nn.Softmax(dim=1)(output[5:5+num_classes].transpose(0,1)).detach() | |
| cls_max_confs, cls_max_ids = torch.max(cls_confs, 1) | |
| cls_max_confs = cls_max_confs.view(-1) | |
| cls_max_ids = cls_max_ids.view(-1) | |
| sz_hw = h*w | |
| sz_hwa = sz_hw*num_anchors | |
| det_confs = convert2cpu(det_confs) | |
| cls_max_confs = convert2cpu(cls_max_confs) | |
| cls_max_ids = convert2cpu_long(cls_max_ids) | |
| xs = convert2cpu(xs) | |
| ys = convert2cpu(ys) | |
| ws = convert2cpu(ws) | |
| hs = convert2cpu(hs) | |
| if validation: | |
| cls_confs = convert2cpu(cls_confs.view(-1, num_classes)) | |
| for b in range(batch): | |
| boxes = [] | |
| for cy in range(h): | |
| for cx in range(w): | |
| for i in range(num_anchors): | |
| ind = b*sz_hwa + i*sz_hw + cy*w + cx | |
| det_conf = det_confs[ind] | |
| if only_objectness: | |
| conf = det_confs[ind] | |
| else: | |
| conf = det_confs[ind] * cls_max_confs[ind] | |
| if conf > conf_thresh: | |
| bcx = xs[ind] | |
| bcy = ys[ind] | |
| bw = ws[ind] | |
| bh = hs[ind] | |
| cls_max_conf = cls_max_confs[ind] | |
| cls_max_id = cls_max_ids[ind] | |
| box = [bcx/w, bcy/h, bw/w, bh/h, det_conf, cls_max_conf, cls_max_id] | |
| if (not only_objectness) and validation: | |
| for c in range(num_classes): | |
| tmp_conf = cls_confs[ind][c] | |
| if c != cls_max_id and det_confs[ind]*tmp_conf > conf_thresh: | |
| box.append(tmp_conf) | |
| box.append(c) | |
| boxes.append(box) | |
| all_boxes.append(boxes) | |
| return all_boxes | |
| def parse_cfg(cfgfile): | |
| blocks = [] | |
| fp = open(cfgfile, 'r') | |
| block = None | |
| line = fp.readline() | |
| while line != '': | |
| line = line.rstrip() | |
| if line == '' or line[0] == '#': | |
| line = fp.readline() | |
| continue | |
| elif line[0] == '[': | |
| if block: | |
| blocks.append(block) | |
| block = dict() | |
| block['type'] = line.lstrip('[').rstrip(']') | |
| # set default value | |
| if block['type'] == 'convolutional': | |
| block['batch_normalize'] = 0 | |
| else: | |
| key,value = line.split('=') | |
| key = key.strip() | |
| if key == 'type': | |
| key = '_type' | |
| value = value.strip() | |
| block[key] = value | |
| line = fp.readline() | |
| if block: | |
| blocks.append(block) | |
| fp.close() | |
| return blocks | |
| def print_cfg(blocks): | |
| print('layer filters size input output') | |
| prev_width = 416 | |
| prev_height = 416 | |
| prev_filters = 3 | |
| out_filters =[] | |
| out_widths =[] | |
| out_heights =[] | |
| ind = -2 | |
| for block in blocks: | |
| ind = ind + 1 | |
| if block['type'] == 'net': | |
| prev_width = int(block['width']) | |
| prev_height = int(block['height']) | |
| continue | |
| elif block['type'] == 'convolutional': | |
| filters = int(block['filters']) | |
| kernel_size = int(block['size']) | |
| stride = int(block['stride']) | |
| is_pad = int(block['pad']) | |
| pad = (kernel_size-1)//2 if is_pad else 0 | |
| width = (prev_width + 2*pad - kernel_size)//stride + 1 | |
| height = (prev_height + 2*pad - kernel_size)//stride + 1 | |
| print('%5d %-6s %4d %d x %d / %d %3d x %3d x%4d -> %3d x %3d x%4d' % (ind, 'conv', filters, kernel_size, kernel_size, stride, prev_width, prev_height, prev_filters, width, height, filters)) | |
| prev_width = width | |
| prev_height = height | |
| prev_filters = filters | |
| out_widths.append(prev_width) | |
| out_heights.append(prev_height) | |
| out_filters.append(prev_filters) | |
| elif block['type'] == 'upsample': | |
| stride = int(block['stride']) | |
| filters = prev_filters | |
| width = prev_width*stride | |
| height = prev_height*stride | |
| print('%5d %-6s * %d %3d x %3d x%4d -> %3d x %3d x%4d' % (ind, 'upsample', stride, prev_width, prev_height, prev_filters, width, height, filters)) | |
| prev_width = width | |
| prev_height = height | |
| prev_filters = filters | |
| out_widths.append(prev_width) | |
| out_heights.append(prev_height) | |
| out_filters.append(prev_filters) | |
| elif block['type'] == 'route': | |
| layers = block['layers'].split(',') | |
| layers = [int(i) if int(i) > 0 else int(i)+ind for i in layers] | |
| if len(layers) == 1: | |
| print('%5d %-6s %d' % (ind, 'route', layers[0])) | |
| prev_width = out_widths[layers[0]] | |
| prev_height = out_heights[layers[0]] | |
| prev_filters = out_filters[layers[0]] | |
| elif len(layers) == 2: | |
| print('%5d %-6s %d %d' % (ind, 'route', layers[0], layers[1])) | |
| prev_width = out_widths[layers[0]] | |
| prev_height = out_heights[layers[0]] | |
| assert(prev_width == out_widths[layers[1]]) | |
| assert(prev_height == out_heights[layers[1]]) | |
| prev_filters = out_filters[layers[0]] + out_filters[layers[1]] | |
| out_widths.append(prev_width) | |
| out_heights.append(prev_height) | |
| out_filters.append(prev_filters) | |
| elif block['type'] in ['region', 'yolo']: | |
| print('%5d %-6s' % (ind, 'detection')) | |
| out_widths.append(prev_width) | |
| out_heights.append(prev_height) | |
| out_filters.append(prev_filters) | |
| elif block['type'] == 'shortcut': | |
| from_id = int(block['from']) | |
| from_id = from_id if from_id > 0 else from_id+ind | |
| print('%5d %-6s %d' % (ind, 'shortcut', from_id)) | |
| prev_width = out_widths[from_id] | |
| prev_height = out_heights[from_id] | |
| prev_filters = out_filters[from_id] | |
| out_widths.append(prev_width) | |
| out_heights.append(prev_height) | |
| out_filters.append(prev_filters) | |
| else: | |
| print('unknown type %s' % (block['type'])) | |
| def load_conv(buf, start, conv_model): | |
| num_w = conv_model.weight.numel() | |
| num_b = conv_model.bias.numel() | |
| conv_model.bias.data.copy_(torch.from_numpy(buf[start:start+num_b])); start = start + num_b | |
| conv_model.weight.data.copy_(torch.from_numpy(buf[start:start+num_w]).view_as(conv_model.weight.data)); start = start + num_w | |
| return start | |
| def load_conv_bn(buf, start, conv_model, bn_model): | |
| num_w = conv_model.weight.numel() | |
| num_b = bn_model.bias.numel() | |
| bn_model.bias.data.copy_(torch.from_numpy(buf[start:start+num_b])); start = start + num_b | |
| bn_model.weight.data.copy_(torch.from_numpy(buf[start:start+num_b])); start = start + num_b | |
| bn_model.running_mean.copy_(torch.from_numpy(buf[start:start+num_b])); start = start + num_b | |
| bn_model.running_var.copy_(torch.from_numpy(buf[start:start+num_b])); start = start + num_b | |
| conv_model.weight.data.copy_(torch.from_numpy(buf[start:start+num_w]).view_as(conv_model.weight.data)); start = start + num_w | |
| return start | |