def model_eval(self, preds, gts): # 1) IoU iou = gen_utils.iou(preds, gts) iou_pos = gen_utils.iou(preds, gts, True) # TODO: 2) Recall # 3) pixel-level accuracy (may not be suitable) accuracy = gen_utils.accuracy(preds, gts) return iou, iou_pos, accuracy
def validate_model(model, criterion, valid_loader, device): top1 = AverageMeter('Acc@1', ':6.2f') jacc1 = AverageMeter('Jacc_sim@1', ':6.2f') avgloss = AverageMeter('Loss', '1.5f') val_loss = 0.0 model.eval() with torch.no_grad(): for data in valid_loader: image, target = data['image'].to( device, dtype=torch.float), data['label'].to(device) output = model(image) loss = criterion(output, target) val_loss += loss.cpu().detach().numpy() acc1, jacc = iou(output, target) top1.update(acc1, image.size(0)) avgloss.update(loss, image.size(0)) jacc1.update(jacc, image.size(0)) return avgloss.avg, top1.avg, jacc1.avg
def train_one_epoch(model, criterion, optimizer, data_loader, device): top1 = AverageMeter('Acc@1', ':6.2f') avgloss = AverageMeter('Loss', '1.5f') jacc1 = AverageMeter('Jacc_sim@1', ':6.2f') train_loss = 0.0 model.train() for data in tqdm(data_loader): model.to(device) image, target = data['image'].to( device, dtype=torch.float), data['label'].to(device) output = model(image) loss = criterion(output, target) optimizer.zero_grad() loss.backward() optimizer.step() train_loss += loss.cpu().detach().numpy() acc1, jacc = iou(output, target) top1.update(acc1, image.size(0)) avgloss.update(loss, image.size(0)) jacc1.update(jacc, image.size(0)) return avgloss.avg, top1.avg, jacc1.avg
def validate(net, Dataloader): ''' Test on validation dataset :param net: net to evaluate :param Dataloader: data to evaluate :return: ''' dtype = torch.cuda.FloatTensor dtype_t = torch.cuda.LongTensor dir_name = 'save_img/validate/' if not os.path.exists(dir_name): os.makedirs(dir_name) len_dl = len(Dataloader) print(len_dl) nu = 0 de = 0 for step, data in enumerate(Dataloader): labels = data[4].numpy() xx = Variable(data[0].type(dtype)) re = net.module.test(xx, 60) for i in range(len(re)): labels_p = re.cpu().numpy()[i] vertices1 = label2vertex(labels_p) vertices2 = label2vertex(labels[i]) color = [np.random.randint(0, 255) for _ in range(3)] color += [100] color = tuple(color) img_array = tensor2img(data[0][i]) img = Image.fromarray(img_array) drw = ImageDraw.Draw(img, 'RGBA') drw.polygon(vertices1, color) img.save(dir_name + str(step) + '_' + str(i) + '_pred.png', 'PNG') img = Image.fromarray(img_array) drw = ImageDraw.Draw(img, 'RGBA') drw.polygon(vertices2, color) img.save(dir_name + str(step) + '_' + str(i) + '_gt.png', 'PNG') _, nu_this, de_this = iou(vertices1, vertices2, 224, 224) nu += nu_this de += de_this print('iou: {}'.format(nu * 1.0 / de))
def encode(self, gt_data, overlap_threshold=0.5, debug=False): # calculation is done with normalized sizes # TODO: empty ground truth if gt_data.shape[0] == 0: print('gt_data', type(gt_data), gt_data.shape) num_classes = 2 num_priors = self.priors.shape[0] gt_polygons = np.copy(gt_data[:, :8]) # normalized quadrilaterals gt_rboxes = np.array( [polygon_to_rbox3(np.reshape(p, (-1, 2))) for p in gt_data[:, :8]]) # minimum horizontal bounding rectangles gt_xmin = np.min(gt_data[:, 0:8:2], axis=1) gt_ymin = np.min(gt_data[:, 1:8:2], axis=1) gt_xmax = np.max(gt_data[:, 0:8:2], axis=1) gt_ymax = np.max(gt_data[:, 1:8:2], axis=1) gt_boxes = self.gt_boxes = np.array( [gt_xmin, gt_ymin, gt_xmax, gt_ymax]).T # normalized xmin, ymin, xmax, ymax gt_class_idx = np.asarray(gt_data[:, -1] + 0.5, dtype=np.int) gt_one_hot = np.zeros([len(gt_class_idx), num_classes]) gt_one_hot[range(len(gt_one_hot)), gt_class_idx] = 1 # one_hot classes including background gt_iou = np.array([iou(b, self.priors_norm) for b in gt_boxes]).T # assign gt to priors max_idxs = np.argmax(gt_iou, axis=1) max_val = gt_iou[np.arange(num_priors), max_idxs] prior_mask = max_val > overlap_threshold match_indices = max_idxs[prior_mask] self.match_indices = dict( zip(list(np.ix_(prior_mask)[0]), list(match_indices))) # prior labels confidence = np.zeros((num_priors, num_classes)) confidence[:, 0] = 1 confidence[prior_mask] = gt_one_hot[match_indices] gt_xy = (gt_boxes[:, 2:4] + gt_boxes[:, 0:2]) / 2. gt_wh = gt_boxes[:, 2:4] - gt_boxes[:, 0:2] gt_xy = gt_xy[match_indices] gt_wh = gt_wh[match_indices] gt_polygons = gt_polygons[match_indices] gt_rboxes = gt_rboxes[match_indices] priors_xy = self.priors_xy[prior_mask] / self.image_size priors_wh = self.priors_wh[prior_mask] / self.image_size variances_xy = self.priors_variances[prior_mask, 0:2] variances_wh = self.priors_variances[prior_mask, 2:4] # compute local offsets for offsets = np.zeros((num_priors, 4)) offsets[prior_mask, 0:2] = (gt_xy - priors_xy) / priors_wh offsets[prior_mask, 2:4] = np.log(gt_wh / priors_wh) offsets[prior_mask, 0:2] /= variances_xy offsets[prior_mask, 2:4] /= variances_wh # compute local offsets for quadrilaterals offsets_quads = np.zeros((num_priors, 8)) priors_xy_minmax = np.hstack( [priors_xy - priors_wh / 2, priors_xy + priors_wh / 2]) # ref = np.tile(priors_xy, (1,4)) ref = priors_xy_minmax[:, (0, 1, 2, 1, 2, 3, 0, 3)] # corner points offsets_quads[prior_mask, :] = (gt_polygons - ref) / np.tile( priors_wh, (1, 4)) / np.tile(variances_xy, (1, 4)) # compute local offsets for rotated bounding boxes offsets_rboxs = np.zeros((num_priors, 5)) offsets_rboxs[prior_mask, 0:2] = (gt_rboxes[:, 0:2] - priors_xy) / priors_wh / variances_xy offsets_rboxs[prior_mask, 2:4] = (gt_rboxes[:, 2:4] - priors_xy) / priors_wh / variances_xy offsets_rboxs[prior_mask, 4] = np.log( gt_rboxes[:, 4] / priors_wh[:, 1]) / variances_wh[:, 1] return np.concatenate( [offsets, offsets_quads, offsets_rboxs, confidence], axis=1)
def test(net, dataset, num=float('inf')): ''' Test on validation dataset :param net: net to evaluate :param mode: full image or cropped image :param Dataloader: data to evaluate :return: ''' dtype = torch.cuda.FloatTensor dtype_t = torch.cuda.LongTensor dir_name = 'save_img/test/' if not os.path.exists(dir_name): os.makedirs(dir_name) selected_classes = [ 'person', 'car', 'truck', 'bicycle', 'motorcycle', 'rider', 'bus', 'train' ] iou_score = {} nu = {} de = {} for cls in selected_classes: iou_score[cls] = 0.0 nu[cls] = 0.0 de[cls] = 0.0 count = 0 files = glob('img/{}/*/*.png'.format(dataset)) for ind, file in enumerate(files): json_file = 'label' + file[3:-15] + 'gtFine_polygons.json' json_object = json.load(open(json_file)) h = json_object['imgHeight'] w = json_object['imgWidth'] objects = json_object['objects'] img = Image.open(file).convert('RGB') I = np.array(img) img_gt = Image.open(file).convert('RGB') for obj in objects: if obj['label'] in selected_classes: min_row, min_col, max_row, max_col = getbboxfromkps( obj['polygon'], h, w) object_h = max_row - min_row object_w = max_col - min_col scale_h = 224.0 / object_h scale_w = 224.0 / object_w I_obj = I[min_row:max_row, min_col:max_col, :] I_obj_img = Image.fromarray(I_obj) I_obj_img = I_obj_img.resize((224, 224), Image.BILINEAR) I_obj_new = np.array(I_obj_img) xx = img2tensor(I_obj_new) xx = xx.unsqueeze(0).type(dtype) xx = Variable(xx) re = net.module.test(xx, 60) labels_p = re.cpu().numpy()[0] vertices1 = [] vertices2 = [] color = [np.random.randint(0, 255) for _ in range(3)] color += [100] color = tuple(color) for label in labels_p: if (label == 784): break vertex = (((label % 28) * 8.0 + 4) / scale_w + min_col, ((int(label / 28)) * 8.0 + 4) / scale_h + min_row) vertices1.append(vertex) try: drw = ImageDraw.Draw(img, 'RGBA') drw.polygon(vertices1, color) except TypeError: continue for points in obj['polygon']: vertex = (points[0], points[1]) vertices2.append(vertex) drw_gt = ImageDraw.Draw(img_gt, 'RGBA') drw_gt.polygon(vertices2, color) _, nu_this, de_this = iou(vertices1, vertices2, h, w) nu[obj['label']] += nu_this de[obj['label']] += de_this count += 1 img.save(dir_name + str(ind) + '_pred.png', 'PNG') img_gt.save(dir_name + str(ind) + '_gt.png', 'PNG') if count >= num: break for cls in iou_score: iou_score[cls] = nu[cls] * 1.0 / de[cls] if de[cls] != 0 else 0 return iou_score