def forward(self, x, augment=False, profile=False): if augment: img_size = x.shape[-2:] # height, width s = [1, 0.83, 0.67] # scales f = [None, 3, None] # flips (2-ud, 3-lr) y = [] # outputs for si, fi in zip(s, f): xi = scale_img(x.flip(fi) if fi else x, si, gs=int(self.stride.max())) yi = self.forward_once(xi)[0] # forward # cv2.imwrite(f'img_{si}.jpg', 255 * xi[0].cpu().numpy().transpose((1, 2, 0))[:, :, ::-1]) # save yi[..., :4] /= si # de-scale if fi == 2: yi[..., 1] = img_size[0] - yi[..., 1] # de-flip ud elif fi == 3: yi[..., 0] = img_size[1] - yi[..., 0] # de-flip lr y.append(yi) return torch.cat(y, 1), None # augmented inference, train else: return self.forward_once(x, profile) # single-scale inference, train
def forward_once(self, x, augment=False, verbose=False): img_size = x.shape[-2:] # height, width yolo_out, out = [], [] if verbose: print('0', x.shape) str = '' # Augment images (inference and test only) if augment: # https://github.com/ultralytics/yolov3/issues/931 nb = x.shape[0] # batch size s = [0.83, 0.67] # scales x = torch.cat( ( x, torch_utils.scale_img(x.flip(3), s[0]), # flip-lr and scale torch_utils.scale_img(x, s[1]), # scale ), 0) for i, module in enumerate(self.module_list): name = module.__class__.__name__ if name in [ 'WeightedFeatureFusion', 'FeatureConcat', 'FeatureConcat2', 'FeatureConcat3', 'FeatureConcat_l' ]: # sum, concat if verbose: l = [i - 1] + module.layers # layers sh = [list(x.shape) ] + [list(out[i].shape) for i in module.layers] # shapes str = ' >> ' + ' + '.join( ['layer %g %s' % x for x in zip(l, sh)]) x = module(x, out) # WeightedFeatureFusion(), FeatureConcat() elif name == 'YOLOLayer': yolo_out.append(module(x, out)) else: # run module directly, i.e. mtype = 'convolutional', 'upsample', 'maxpool', 'batchnorm2d' etc. x = module(x) out.append(x if self.routs[i] else []) if verbose: print('%g/%g %s -' % (i, len(self.module_list), name), list(x.shape), str) str = '' if self.training: # train return yolo_out elif ONNX_EXPORT: # export x = [torch.cat(x, 0) for x in zip(*yolo_out)] return x[0], x[1], torch.cat( x[2:4], 1) # scores, cls, boxes: 3780x80, 3780x4 else: # inference or test x, p = zip(*yolo_out) # inference output, training output x = torch.cat(x, 1) # cat yolo outputs if augment: # de-augment results x = torch.split(x, nb, dim=0) x[1][..., :4] /= s[0] # scale x[1][..., 0] = img_size[1] - x[1][..., 0] # flip lr x[2][..., :4] /= s[1] # scale x = torch.cat(x, 1) return x, p