def test(self, test_loader, log_interval=100, res_fpath=None): self.model.eval() losses = 0 correct = 0 miss = 0 all_res_list = [] t0 = time.time() for batch_idx, (data, target, (frame, pid, grid_x, grid_y)) in enumerate(test_loader): data, target = data.cuda(), target.cuda() with torch.no_grad(): output = self.model(data) output = F.softmax(output, dim=1) pred = torch.argmax(output, 1) correct += pred.eq(target).sum().item() miss += target.numel() - pred.eq(target).sum().item() loss = self.criterion(output, target) losses += loss.item() if res_fpath is not None: indices = output[:, 1] > self.cls_thres all_res_list.append( torch.stack([ frame[indices].float(), grid_x[indices].float(), grid_y[indices].float(), output[indices, 1].cpu() ], dim=1)) if (batch_idx + 1) % log_interval == 0: # print(cyclic_scheduler.last_epoch, optimizer.param_groups[0]['lr']) t1 = time.time() t_epoch = t1 - t0 print( 'Test Batch:{}, \tLoss: {:.6f}, Prec: {:.1f}%, Time: {:.3f}' .format((batch_idx + 1), losses / (batch_idx + 1), 100. * correct / (correct + miss), t_epoch)) t1 = time.time() t_epoch = t1 - t0 print( 'Test, Batch:{}, Loss: {:.6f}, Prec: {:.1f}%, Time: {:.3f}'.format( len(test_loader), losses / (len(test_loader) + 1), 100. * correct / (correct + miss), t_epoch)) if res_fpath is not None: all_res_list = torch.cat(all_res_list, dim=0) np.savetxt( os.path.dirname(res_fpath) + '/all_res.txt', all_res_list.numpy(), '%.8f') res_list = [] for frame in np.unique(all_res_list[:, 0]): res = all_res_list[all_res_list[:, 0] == frame, :] positions, scores = res[:, 1:3], res[:, 3] ids, count = nms( positions, scores, ) res_list.append( torch.cat([ torch.ones([count, 1]) * frame, positions[ids[:count], :] ], dim=1)) res_list = torch.cat(res_list, dim=0).numpy() np.savetxt(res_fpath, res_list, '%d') return losses / len(test_loader), correct / (correct + miss)
def test(self, data_loader, res_fpath=None, gt_fpath=None, visualize=False): self.model.eval() losses = 0 precision_s, recall_s = AverageMeter(), AverageMeter() all_res_list = [] t0 = time.time() if res_fpath is not None: assert gt_fpath is not None for batch_idx, (data, map_gt, imgs_gt, frame) in enumerate(data_loader): with torch.no_grad(): map_res, imgs_res = self.model(data) if res_fpath is not None: map_grid_res = map_res.detach().cpu().squeeze() v_s = map_grid_res[map_grid_res > self.cls_thres].unsqueeze(1) grid_ij = (map_grid_res > self.cls_thres).nonzero() if data_loader.dataset.base.indexing == 'xy': grid_xy = grid_ij[:, [1, 0]] else: grid_xy = grid_ij all_res_list.append( torch.cat([ torch.ones_like(v_s) * frame, grid_xy.float() * data_loader.dataset.grid_reduce, v_s ], dim=1)) loss = 0 for img_res, img_gt in zip(imgs_res, imgs_gt): loss += self.criterion(img_res, img_gt.to(img_res.device), data_loader.dataset.img_kernel) loss = self.criterion(map_res, map_gt.to(map_res.device), data_loader.dataset.map_kernel) + \ loss / len(imgs_gt) * self.alpha losses += loss.item() pred = (map_res > self.cls_thres).int().to(map_gt.device) true_positive = (pred.eq(map_gt) * pred.eq(1)).sum().item() false_positive = pred.sum().item() - true_positive false_negative = map_gt.sum().item() - true_positive precision = true_positive / (true_positive + false_positive + 1e-4) recall = true_positive / (true_positive + false_negative + 1e-4) precision_s.update(precision) recall_s.update(recall) t1 = time.time() t_epoch = t1 - t0 if visualize: fig = plt.figure() subplt0 = fig.add_subplot(211, title="output") subplt1 = fig.add_subplot(212, title="target") subplt0.imshow(map_res.cpu().detach().numpy().squeeze()) subplt1.imshow( self.criterion._traget_transform( map_res, map_gt, data_loader.dataset.map_kernel).cpu(). detach().numpy().squeeze()) plt.savefig(os.path.join(self.logdir, 'map.jpg')) plt.close(fig) # visualizing the heatmap for per-view estimation heatmap0_head = imgs_res[0][0, 0].detach().cpu().numpy().squeeze() heatmap0_foot = imgs_res[0][0, 1].detach().cpu().numpy().squeeze() img0 = self.denormalize( data[0, 0]).cpu().numpy().squeeze().transpose([1, 2, 0]) img0 = Image.fromarray((img0 * 255).astype('uint8')) head_cam_result = add_heatmap_to_image(heatmap0_head, img0) head_cam_result.save(os.path.join(self.logdir, 'cam1_head.jpg')) foot_cam_result = add_heatmap_to_image(heatmap0_foot, img0) foot_cam_result.save(os.path.join(self.logdir, 'cam1_foot.jpg')) moda = 0 if res_fpath is not None: all_res_list = torch.cat(all_res_list, dim=0) np.savetxt( os.path.abspath(os.path.dirname(res_fpath)) + '/all_res.txt', all_res_list.numpy(), '%.8f') res_list = [] for frame in np.unique(all_res_list[:, 0]): res = all_res_list[all_res_list[:, 0] == frame, :] positions, scores = res[:, 1:3], res[:, 3] ids, count = nms(positions, scores, 20, np.inf) res_list.append( torch.cat([ torch.ones([count, 1]) * frame, positions[ids[:count], :] ], dim=1)) res_list = torch.cat( res_list, dim=0).numpy() if res_list else np.empty([0, 3]) np.savetxt(res_fpath, res_list, '%d') recall, precision, moda, modp = evaluate( os.path.abspath(res_fpath), os.path.abspath(gt_fpath), data_loader.dataset.base.__name__) # If you want to use the unofiicial python evaluation tool for convenient purposes. # recall, precision, modp, moda = python_eval(os.path.abspath(res_fpath), os.path.abspath(gt_fpath), # data_loader.dataset.base.__name__) print( 'moda: {:.1f}%, modp: {:.1f}%, precision: {:.1f}%, recall: {:.1f}%' .format(moda, modp, precision, recall)) print( 'Test, Loss: {:.6f}, Precision: {:.1f}%, Recall: {:.1f}, \tTime: {:.3f}' .format(losses / (len(data_loader) + 1), precision_s.avg * 100, recall_s.avg * 100, t_epoch)) return losses / len(data_loader), precision_s.avg * 100, moda