def inference_flipped_old(cfg, model, test_dataloader, num_query): logger = logging.getLogger("reid_baseline.inference") logger.info("Start inferencing") model.eval() feats, feats_flipped, pids, camids = [], [], [], [] local_feats, local_feats_flipped = [], [] test_prefetcher = data_prefetcher(test_dataloader) batch = test_prefetcher.next() while batch[0] is not None: img, pid, camid = batch with torch.no_grad(): feat = model(img) feat_flipped = model(torch.flip(img, [3])) if isinstance(feat, tuple): feats.append(feat[0]) local_feats.append(feat[1]) feats_flipped.append(feat_flipped[0]) local_feats_flipped.append(feat_flipped[1]) else: feats.append(feat) feats_flipped.append(feat_flipped) pids.extend(pid.cpu().numpy()) camids.extend(np.asarray(camid)) batch = test_prefetcher.next() feats = torch.cat(feats, dim=0) feats_flipped = torch.cat(feats_flipped, dim=0) if len(local_feats) > 0: local_feats = torch.cat(local_feats, dim=0) local_feats_flipped = torch.cat(local_feats_flipped, dim=0) #print('feats_flipped', len(feats_flipped), feats_flipped[0]) if cfg.TEST.NORM: feats = F.normalize(feats, p=2, dim=1) feats_flipped = F.normalize(feats_flipped, p=2, dim=1) # query qf = feats[:num_query] qf_flipped = feats_flipped[:num_query] if len(local_feats) > 0: lqf = local_feats[:num_query] lqf_flipped = local_feats_flipped[:num_query] q_pids = np.asarray(pids[:num_query]) q_camids = np.asarray(camids[:num_query]) # gallery gf = feats[num_query:] gf_flipped = feats_flipped[num_query:] if len(local_feats) > 0: lgf = local_feats[num_query:] lgf_flipped = local_feats_flipped[num_query:] g_pids = np.asarray(pids[num_query:]) g_camids = np.asarray(camids[num_query:]) # cosine distance #distmat = torch.mm(qf, gf.t()).cpu().numpy() if len(local_feats) > 0: #if True: # calculate the local distance lqf = lqf.permute(0, 2, 1) lgf = lgf.permute(0, 2, 1) local_qg_distmat = low_memory_local_dist(lqf.cpu().numpy(), lgf.cpu().numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqf.cpu().numpy(), lqf.cpu().numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgf.cpu().numpy(), lgf.cpu().numpy(), aligned=True) local_distmat = np.concatenate([ np.concatenate([local_qq_distmat, local_qg_distmat], axis=1), np.concatenate([local_qg_distmat.T, local_gg_distmat], axis=1) ], axis=0) # flipped lqf = lqf_flipped.permute(0, 2, 1) lgf = lgf_flipped.permute(0, 2, 1) local_qg_distmat = low_memory_local_dist(lqf.cpu().numpy(), lgf.cpu().numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqf.cpu().numpy(), lqf.cpu().numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgf.cpu().numpy(), lgf.cpu().numpy(), aligned=True) local_distmat_flipped = np.concatenate([ np.concatenate([local_qq_distmat, local_qg_distmat], axis=1), np.concatenate([local_qg_distmat.T, local_gg_distmat], axis=1) ], axis=0) else: local_distmat = None local_distmat_flipped = None # use reranking logger.info("use reranking") #distmat = re_ranking(qf, gf, k1=14, k2=4, lambda_value=0.4) search_theta = True if search_theta: best_score = 0 #for theta in np.linspace(0.9, 1.0, 11): for theta in np.linspace(0, 1.0, 21): distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, theta_value=theta, only_local=False) # (current best) distmat_flipped = re_ranking(qf_flipped, gf_flipped, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat_flipped, theta_value=theta, only_local=False) # (current best) distmat = (distmat + distmat_flipped) / 2 #cmc, mAP = evaluate(distmat + distmat_flipped, q_pids, g_pids, q_camids, g_camids) cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) score = (cmc[0] + mAP) / 2 print('theta', np.around(theta, 2), 'r1, mAP, score', np.around(cmc[0], 4), np.around(mAP, 4), np.around(score, 4)) if score > best_score: best_score = score best_param = theta best_distmat = distmat # saving strtime = time.strftime("%Y%m%d_%H%M%S", time.localtime()) if cfg.MODEL.NAME.endswith('abd'): target_theta = 0.45 # abd网络的参数 else: target_theta = 0.95 # 非abd网络的参数 if abs(theta - target_theta) < 1e-4: # saving dist_mats f = h5py.File( 'dist_mats/val_%s_%s_t%.2f_flip.h5' % (cfg.MODEL.NAME, strtime, theta), 'w') f.create_dataset('dist_mat', data=distmat, compression='gzip') f.close() print('Best Param', best_param) distmat = best_distmat else: distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, only_local=False, theta_value=0.95) #(current best) distmat_flipped = re_ranking(qf_flipped, gf_flipped, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat_flipped, theta_value=0.95, only_local=False) # (current best) distmat = (distmat + distmat_flipped) / 2 cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) logger.info(f"mAP: {mAP:.1%}") for r in [1, 5, 10]: logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}") logger.info(f"Score: {(mAP + cmc[0]) / 2.:.1%}")
def inference(cfg, model, test_dataloader, num_query): logger = logging.getLogger("reid_baseline.inference") logger.info("Start inferencing") model.eval() feats, pids, camids = [], [], [] local_feats = [] test_prefetcher = data_prefetcher(test_dataloader) batch = test_prefetcher.next() while batch[0] is not None: img, pid, camid = batch with torch.no_grad(): #feat = model(img) feat = model(torch.flip(img, [3])) if isinstance(feat, tuple): feats.append(feat[0]) local_feats.append(feat[1]) else: feats.append(feat) pids.extend(pid.cpu().numpy()) camids.extend(np.asarray(camid)) batch = test_prefetcher.next() feats = torch.cat(feats, dim=0) if len(local_feats) > 0: local_feats = torch.cat(local_feats, dim=0) if cfg.TEST.NORM: feats = F.normalize(feats, p=2, dim=1) # 局部特征是三维的,不做归一化 (对结果没影响) #if len(local_feats) > 0: # local_feats = F.normalize(local_feats, p=2, dim=1) # query qf = feats[:num_query] if len(local_feats) > 0: lqf = local_feats[:num_query] q_pids = np.asarray(pids[:num_query]) q_camids = np.asarray(camids[:num_query]) # gallery gf = feats[num_query:] if len(local_feats) > 0: lgf = local_feats[num_query:] g_pids = np.asarray(pids[num_query:]) g_camids = np.asarray(camids[num_query:]) if len(local_feats) > 0: #if True: # calculate the local distance lqf = lqf.permute(0, 2, 1) lgf = lgf.permute(0, 2, 1) local_qg_distmat = low_memory_local_dist(lqf.cpu().numpy(), lgf.cpu().numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqf.cpu().numpy(), lqf.cpu().numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgf.cpu().numpy(), lgf.cpu().numpy(), aligned=True) local_distmat = np.concatenate([ np.concatenate([local_qq_distmat, local_qg_distmat], axis=1), np.concatenate([local_qg_distmat.T, local_gg_distmat], axis=1) ], axis=0) else: local_distmat = None # use reranking logger.info("use reranking") #distmat = re_ranking(qf, gf, k1=14, k2=4, lambda_value=0.4) search_param = False search_theta = True if search_param: best_score = 0 best_param = [] for k1 in range(5, 9): for k2 in range(1, k1): for l in np.linspace(0, 0.5, 11): distmat = re_ranking(qf, gf, k1=k1, k2=k2, lambda_value=l) cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) score = (cmc[0] + mAP) / 2 #logger.info(f"mAP: {mAP:.1%}") print('k1, k2, l', k1, k2, np.around(l, 2), 'r1, mAP, score', np.around(cmc[0], 4), np.around(mAP, 4), np.around(score, 4)) if score > best_score: best_score = score best_param = [k1, k2, l] print('Best Param', best_param) distmat = re_ranking(qf, gf, k1=best_param[0], k2=best_param[1], lambda_value=best_param[2], local_distmat=local_distmat, only_local=False) elif search_theta: best_score = 0 for theta in np.linspace(0, 1.0, 11): distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, theta_value=theta, only_local=False) # (current best) cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) score = (cmc[0] + mAP) / 2 print('theta', theta, 'r1, mAP, score', np.around(cmc[0], 4), np.around(mAP, 4), np.around(score, 4)) if score > best_score: best_score = score best_param = theta print('Best Param', best_param) distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, theta_value=best_param, only_local=False) # (current best) else: distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, only_local=False, theta_value=0.9) #(current best) #distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.4) # try cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) logger.info(f"mAP: {mAP:.1%}") for r in [1, 5, 10]: logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}") logger.info(f"Score: {(mAP + cmc[0]) / 2.:.1%}")
def inference_flipped(cfg, model, test_dataloader, num_query, use_re_ranking=True, distance_metric='global_local'): logger = logging.getLogger("reid_baseline.inference") logger.info("Start inferencing") model.eval() g_feats, l_feats, gf_feats, lf_feats, pids, camids = [], [], [], [], [], [] val_prefetcher = data_prefetcher(test_dataloader) batch = val_prefetcher.next() while batch[0] is not None: img, pid, camid = batch with torch.no_grad(): g_feat, l_feat = model(img) gf_feat, lf_feat = model(torch.flip(img, [3])) g_feats.append(g_feat.data.cpu()) l_feats.append(l_feat.data.cpu()) gf_feats.append(gf_feat.data.cpu()) lf_feats.append(lf_feat.data.cpu()) pids.extend(pid.cpu().numpy()) camids.extend(np.asarray(camid)) batch = val_prefetcher.next() g_feats = torch.cat(g_feats, dim=0) l_feats = torch.cat(l_feats, dim=0) gf_feats = torch.cat(gf_feats, dim=0) lf_feats = torch.cat(lf_feats, dim=0) if cfg.TEST.NORM: g_feats = F.normalize(g_feats, p=2, dim=1) gf_feats = F.normalize(gf_feats, p=2, dim=1) # query qf = g_feats[:num_query] lqf = l_feats[:num_query] qff = gf_feats[:num_query] lqff = lf_feats[:num_query] q_pids = np.asarray(pids[:num_query]) q_camids = np.asarray(camids[:num_query]) # gallery gf = g_feats[num_query:] lgf = l_feats[num_query:] gff = gf_feats[num_query:] lgff = lf_feats[num_query:] g_pids = np.asarray(pids[num_query:]) g_camids = np.asarray(camids[num_query:]) # calculate the global distance if not use_re_ranking: m, n = qf.shape[0], gf.shape[0] global_distmat = torch.pow(qf, 2).sum(dim=1, keepdim=True).expand(m, n) + \ torch.pow(gf, 2).sum(dim=1, keepdim=True).expand(n, m).t() global_distmat.addmm_(1, -2, qf, gf.t()) global_distmat = global_distmat.numpy() # calculate the local distance lqf = lqf.permute(0, 2, 1) lgf = lgf.permute(0, 2, 1) local_distmat = low_memory_local_dist(lqf.numpy(), lgf.numpy(), aligned=True) if distance_metric == 'global': logger.info("--------use global features--------") distmat = global_distmat elif distance_metric == 'local': logger.info("--------use local features--------") distmat = local_distmat elif distance_metric == 'global_local': logger.info("--------use global and local features--------") distmat = global_distmat + local_distmat else: logger.info("--------use re-ranking--------") lqf = lqf.permute(0, 2, 1) lgf = lgf.permute(0, 2, 1) local_distmat = low_memory_local_dist(lqf.numpy(), lgf.numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqf.numpy(), lqf.numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgf.numpy(), lgf.numpy(), aligned=True) local_dist = np.concatenate([ np.concatenate([local_qq_distmat, local_distmat], axis=1), np.concatenate([local_distmat.T, local_gg_distmat], axis=1) ], axis=0) logger.info("--------use re-ranking flipped--------") lqff = lqff.permute(0, 2, 1) lgff = lgff.permute(0, 2, 1) local_distmat = low_memory_local_dist(lqff.numpy(), lgff.numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqff.numpy(), lqff.numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgff.numpy(), lgff.numpy(), aligned=True) local_dist_flipped = np.concatenate([ np.concatenate([local_qq_distmat, local_distmat], axis=1), np.concatenate([local_distmat.T, local_gg_distmat], axis=1) ], axis=0) # for theta in np.arange(0.0,1.0,0.05): # distmat = re_ranking(qf,gf,k1=6,k2=2,lambda_value=0.3,local_distmat=local_dist,theta=theta,only_local=False) # distmat_flip = re_ranking(qff,gff,k1=6,k2=2,lambda_value=0.3,local_distmat=local_dist_flipped,theta=theta,only_local=False) # distmat = distmat + distmat_flip # cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) # logger.info(f"mAP: {mAP:.1%}") # for r in [1, 5, 10]: # logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}") # logger.info("Theta:{}; Score: {}".format(theta, (mAP+cmc[0])/2.)) theta = 0.45 distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_dist, theta_value=theta, only_local=False) distmat_flip = re_ranking(qff, gff, k1=6, k2=2, lambda_value=0.3, local_distmat=local_dist_flipped, theta_value=theta, only_local=False) distmat = (distmat + distmat_flip) / 2 score = distmat index = np.argsort(score, axis=1) # from small to large cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) logger.info(f"mAP: {mAP:.1%}") for r in [1, 5, 10]: logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}") logger.info(f"Score: {(mAP + cmc[0]) / 2.:.1%}")
def inference( cfg, model, test_dataloader, num_query ): logger = logging.getLogger("reid_baseline.inference") logger.info("Start inferencing") model.eval() feats, pids, camids = [], [], [] #local_feats = [] test_prefetcher = data_prefetcher(test_dataloader, cfg) batch = test_prefetcher.next() while batch[0] is not None: img, pid, camid = batch with torch.no_grad(): feat = model(img) #feat = model(torch.flip(img, [3])) if isinstance(feat, tuple): feats.append(feat[0]) #local_feats.append(feat[1]) else: feats.append(feat) pids.extend(pid.cpu().numpy()) camids.extend(np.asarray(camid)) batch = test_prefetcher.next() feats = torch.cat(feats, dim=0) if cfg.TEST.NORM: feats = F.normalize(feats, p=2, dim=1) # query qf = feats[:num_query] q_pids = np.asarray(pids[:num_query]) q_camids = np.asarray(camids[:num_query]) # gallery gf = feats[num_query:] g_pids = np.asarray(pids[num_query:]) g_camids = np.asarray(camids[num_query:]) local_distmat = None # use reranking logger.info("use reranking") #distmat = re_ranking(qf, gf, k1=14, k2=4, lambda_value=0.4) search_param = False if search_param: best_score = 0 best_param = [] for k1 in range(5, 9): for k2 in range(1, k1): for l in np.linspace(0, 0.5, 11): distmat = re_ranking(qf, gf, k1=k1, k2=k2, lambda_value=l) cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) score = (cmc[0] + mAP) / 2 #logger.info(f"mAP: {mAP:.1%}") print('k1, k2, l', k1, k2, np.around(l,2), 'r1, mAP, score', np.around(cmc[0], 4), np.around(mAP, 4), np.around(score, 4)) if score > best_score: best_score = score best_param = [k1, k2, l] print('Best Param', best_param) distmat = re_ranking(qf, gf, k1=best_param[0], k2=best_param[1], lambda_value=best_param[2], local_distmat=local_distmat, only_local=False) else: distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, only_local=False, theta_value=0.9) #(current best) #distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.4) # try cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) logger.info(f"mAP: {mAP:.1%}") for r in [1, 5, 10]: logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}") logger.info(f"Score: {(mAP + cmc[0]) / 2.:.1%}")
def inference_aligned( cfg, model, test_dataloader, num_query, ): logger = logging.getLogger("reid_baseline.inference") logger.info("Start inferencing") model.eval() g_feats, l_feats, pids, camids = [], [], [], [] val_prefetcher = data_prefetcher(test_dataloader) batch = val_prefetcher.next() while batch[0] is not None: img, pid, camid = batch with torch.no_grad(): g_feat, l_feat = model(img) #g_feat, l_feat = model(torch.flip(img, [3])) # better g_feats.append(g_feat.data.cpu()) l_feats.append(l_feat.data.cpu()) pids.extend(pid.cpu().numpy()) camids.extend(np.asarray(camid)) batch = val_prefetcher.next() g_feats = torch.cat(g_feats, dim=0) l_feats = torch.cat(l_feats, dim=0) if cfg.TEST.NORM: g_feats = F.normalize(g_feats, p=2, dim=1) # query qf = g_feats[:num_query] lqf = l_feats[:num_query] q_pids = np.asarray(pids[:num_query]) q_camids = np.asarray(camids[:num_query]) # gallery gf = g_feats[num_query:] lgf = l_feats[num_query:] g_pids = np.asarray(pids[num_query:]) g_camids = np.asarray(camids[num_query:]) # calculate the global distance if True: logger.info("--------use re-ranking--------") lqf = lqf.permute(0, 2, 1) lgf = lgf.permute(0, 2, 1) local_distmat = low_memory_local_dist(lqf.numpy(), lgf.numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqf.numpy(), lqf.numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgf.numpy(), lgf.numpy(), aligned=True) local_dist = np.concatenate([ np.concatenate([local_qq_distmat, local_distmat], axis=1), np.concatenate([local_distmat.T, local_gg_distmat], axis=1) ], axis=0) distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_dist, theta_value=0.5, only_local=False) ## theta hyer-patameters # for theta in np.arange(0,1.1,0.1): # distmat = re_ranking(qf,gf,k1=6,k2=2,lambda_value=0.3,local_distmat=local_dist,theta=theta,only_local=False) # cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) # logger.info(f"mAP: {mAP:.1%}") # for r in [1, 5, 10]: # logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}") # logger.info("Theta:{}; Score: {}".format(theta, (mAP+cmc[0])/2.)) #score = distmat #index = np.argsort(score, axis=1) # from small to large cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) logger.info(f"mAP: {mAP:.1%}") for r in [1, 5, 10]: logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}") logger.info(f"Score: {(mAP + cmc[0]) / 2.:.1%}")
def retrieval(self): epoch = self.scheduler.last_epoch + 1 self.ckpt.write_log('\n[INFO] Test:') self.model.eval() self.ckpt.add_log(torch.zeros(1, 5)) qf, q_image_paths = self.extract_feature(self.query_loader) gf, g_image_paths = self.extract_feature(self.test_loader) qf = qf.numpy() # (31, 2048) for debug gf = gf.numpy() # (154, 2048) for debug if self.args.re_rank: q_g_dist = np.dot(qf, np.transpose(gf)) q_q_dist = np.dot(qf, np.transpose(qf)) g_g_dist = np.dot(gf, np.transpose(gf)) dist = re_ranking(q_g_dist, q_q_dist, g_g_dist) else: dist = cdist(qf, gf) # (31, 154) for debug if self.args.multi_query: # Suitable for boxes dataset only # Use several same id query samples to retrieval one gallery print(dist.shape) # (31, 154) for debug ids = [ int(x.split(os.sep)[-1].split('_')[0]) for x in q_image_paths ] ids_set = set(ids) ids_np = np.asarray(ids, dtype=np.int32) for id in ids_set: indices = np.where(ids_np == id)[0] mean = np.mean(dist[indices, :], axis=0) for index in indices: dist[index, :] = mean if self.args.multi_gallery: # Suitable for boxes dataset only # query samples to retrieval images and mean the same id of gallery print(dist.shape) # (31, 154) for debug ids = [ int(x.split(os.sep)[-1].split('_')[0]) for x in g_image_paths ] ids_set = set(ids) ids_np = np.asarray(ids, dtype=np.int32) for i, q_image_path in enumerate(q_image_paths): for id in ids_set: indices = np.where(ids_np == id)[0] mean = np.mean(dist[i, indices], axis=0) dist[i, indices] = mean # Output csv file indices = np.argsort(dist, axis=1) import csv with open(os.path.join('retrieval.csv'), 'w') as csvfile: spamwriter = csv.writer(csvfile, delimiter=',') for i, q_image_path in enumerate(q_image_paths): row_string = [os.path.basename(q_image_path)] for j, index in enumerate(indices[i]): row_string.append(os.path.basename(g_image_paths[index])) row_string.append(str(-np.log(dist[i, index] + 1e-6))) spamwriter.writerow(row_string)
def compute_distmat(cfg, num_query, feats, local_feats, theta, use_local_feature, use_rerank): """ Given a pair of global feature and local feature, compute distmat. :param cfg: :param num_query: :param pids: :param camids: :param feats: :param feats_flipped: :param local_feats: :param local_feats_flipped: :param theta: :param use_local_feature: :return: """ feats = torch.cat(feats, dim=0) if len(local_feats) > 0 and use_local_feature: local_feats = torch.cat(local_feats, dim=0) if cfg.TEST.NORM: feats = F.normalize(feats, p=2, dim=1) ## torch to numpy to save memory in re_ranking #feats = feats.numpy() #feats_flipped = feats_flipped.numpy() ########### # query qf = feats[:num_query] if len(local_feats) > 0 and use_local_feature: lqf = local_feats[:num_query] # gallery gf = feats[num_query:] if len(local_feats) > 0: lgf = local_feats[num_query:] #g_pids = np.asarray(pids[num_query:]) #g_camids = np.asarray(camids[num_query:]) if len(local_feats) > 0 and use_local_feature: # if True: # calculate the local distance lqf = lqf.permute(0, 2, 1) lgf = lgf.permute(0, 2, 1) local_qg_distmat = low_memory_local_dist(lqf.numpy(), lgf.numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqf.numpy(), lqf.numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgf.numpy(), lgf.numpy(), aligned=True) local_distmat = np.concatenate([ np.concatenate([local_qq_distmat, local_qg_distmat], axis=1), np.concatenate([local_qg_distmat.T, local_gg_distmat], axis=1) ], axis=0) else: local_distmat = None local_distmat_flipped = None if use_rerank: distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, theta_value=theta, only_local=False) # (current best) del qf, gf else: distmat = -torch.mm(qf, gf.t()).cpu().numpy() return distmat
def eval( self, normalize_feat=True, to_re_rank=True, pool_type='average', verbose=True): """Evaluate using metric CMC and mAP. Args: normalize_feat: whether to normalize features before computing distance to_re_rank: whether to also report re-ranking scores pool_type: 'average' or 'max', only for multi-query case verbose: whether to print the intermediate information """ with measure_time('Extracting feature...', verbose=verbose): feat, ids, cams, im_names, marks = self.extract_feat( normalize_feat, verbose) # query, gallery, multi-query indices q_inds = marks == 0 g_inds = marks == 1 mq_inds = marks == 2 # A helper function just for avoiding code duplication. def compute_score( dist_mat, query_ids=ids[q_inds], gallery_ids=ids[g_inds], query_cams=cams[q_inds], gallery_cams=cams[g_inds]): # Compute mean AP mAP = mean_ap( distmat=dist_mat, query_ids=query_ids, gallery_ids=gallery_ids, query_cams=query_cams, gallery_cams=gallery_cams) # Compute CMC scores cmc_scores = cmc( distmat=dist_mat, query_ids=query_ids, gallery_ids=gallery_ids, query_cams=query_cams, gallery_cams=gallery_cams, separate_camera_set=self.separate_camera_set, single_gallery_shot=self.single_gallery_shot, first_match_break=self.first_match_break, topk=10) return mAP, cmc_scores def print_scores(mAP, cmc_scores): print('[mAP: {:5.2%}], [cmc1: {:5.2%}], [cmc5: {:5.2%}], [cmc10: {:5.2%}]' .format(mAP, *cmc_scores[[0, 4, 9]])) ################ # Single Query # ################ with measure_time('Computing distance...', verbose=verbose): # query-gallery distance q_g_dist = compute_dist(feat[q_inds], feat[g_inds], type='euclidean') with measure_time('Computing scores...', verbose=verbose): mAP, cmc_scores = compute_score(q_g_dist) print('{:<30}'.format('Single Query:'), end='') print_scores(mAP, cmc_scores) ############### # Multi Query # ############### mq_mAP, mq_cmc_scores = None, None if any(mq_inds): mq_ids = ids[mq_inds] mq_cams = cams[mq_inds] mq_feat = feat[mq_inds] unique_mq_ids_cams = defaultdict(list) for ind, (id, cam) in enumerate(zip(mq_ids, mq_cams)): unique_mq_ids_cams[(id, cam)].append(ind) keys = list(unique_mq_ids_cams.keys()) assert pool_type in ['average', 'max'] pool = np.mean if pool_type == 'average' else np.max mq_feat = np.stack([pool(mq_feat[unique_mq_ids_cams[k]], axis=0) for k in keys]) with measure_time('Multi Query, Computing distance...', verbose=verbose): # multi_query-gallery distance mq_g_dist = compute_dist(mq_feat, feat[g_inds], type='euclidean') with measure_time('Multi Query, Computing scores...', verbose=verbose): mq_mAP, mq_cmc_scores = compute_score( mq_g_dist, query_ids=np.array(list(zip(*keys))[0]), gallery_ids=ids[g_inds], query_cams=np.array(list(zip(*keys))[1]), gallery_cams=cams[g_inds] ) print('{:<30}'.format('Multi Query:'), end='') print_scores(mq_mAP, mq_cmc_scores) if to_re_rank: ########################## # Re-ranked Single Query # ########################## with measure_time('Re-ranking distance...', verbose=verbose): # query-query distance q_q_dist = compute_dist(feat[q_inds], feat[q_inds], type='euclidean') # gallery-gallery distance g_g_dist = compute_dist(feat[g_inds], feat[g_inds], type='euclidean') # re-ranked query-gallery distance re_r_q_g_dist = re_ranking(q_g_dist, q_q_dist, g_g_dist) with measure_time('Computing scores for re-ranked distance...', verbose=verbose): mAP, cmc_scores = compute_score(re_r_q_g_dist) print('{:<30}'.format('Re-ranked Single Query:'), end='') print_scores(mAP, cmc_scores) ######################### # Re-ranked Multi Query # ######################### if any(mq_inds): with measure_time('Multi Query, Re-ranking distance...', verbose=verbose): # multi_query-multi_query distance mq_mq_dist = compute_dist(mq_feat, mq_feat, type='euclidean') # re-ranked multi_query-gallery distance re_r_mq_g_dist = re_ranking(mq_g_dist, mq_mq_dist, g_g_dist) with measure_time( 'Multi Query, Computing scores for re-ranked distance...', verbose=verbose): mq_mAP, mq_cmc_scores = compute_score( re_r_mq_g_dist, query_ids=np.array(list(zip(*keys))[0]), gallery_ids=ids[g_inds], query_cams=np.array(list(zip(*keys))[1]), gallery_cams=cams[g_inds] ) print('{:<30}'.format('Re-ranked Multi Query:'), end='') print_scores(mq_mAP, mq_cmc_scores) return mAP, cmc_scores, mq_mAP, mq_cmc_scores
def inference(cfg, model, test_dataloader, num_query, thetas): logger = logging.getLogger("reid_baseline.inference") logger.info("Start inferencing") model.eval() feats, pids, camids = [], [], [] local_feats = [] test_prefetcher = data_prefetcher(test_dataloader) batch = test_prefetcher.next() while batch[0] is not None: img, pid, camid = batch with torch.no_grad(): feat = model(img) if isinstance(feat, tuple): feats.append(feat[0]) local_feats.append(feat[1]) else: feats.append(feat) pids.extend(pid.cpu().numpy()) camids.extend(np.asarray(camid)) batch = test_prefetcher.next() feats = torch.cat(feats, dim=0) if len(local_feats) > 0: local_feats = torch.cat(local_feats, dim=0) if cfg.TEST.NORM: feats = F.normalize(feats, p=2, dim=1) if len(local_feats) > 0: local_feats = F.normalize(local_feats, p=2, dim=1) # query qf = feats[:num_query] if len(local_feats) > 0: lqf = local_feats[:num_query] # gallery gf = feats[num_query:] if len(local_feats) > 0: lgf = local_feats[num_query:] if len(local_feats) > 0: # calculate the local distance lqf = lqf.permute(0, 2, 1) lgf = lgf.permute(0, 2, 1) #logger.info('Computing local_qg_distmat ...') local_qg_distmat = low_memory_local_dist(lqf.cpu().numpy(), lgf.cpu().numpy(), aligned=True) #logger.info('Computing local_qq_distmat ...') local_qq_distmat = low_memory_local_dist(lqf.cpu().numpy(), lqf.cpu().numpy(), aligned=True) #logger.info('Computing local_gg_distmat ...') local_gg_distmat = low_memory_local_dist(lgf.cpu().numpy(), lgf.cpu().numpy(), aligned=True) local_distmat = np.concatenate([ np.concatenate([local_qq_distmat, local_qg_distmat], axis=1), np.concatenate([local_qg_distmat.T, local_gg_distmat], axis=1) ], axis=0) else: local_distmat = None use_rerank = True if use_rerank: #thetas = [0.4, 0.5, 0.9, 0.95, 1.0] scores, indices, dist_mats = [], [], [] logger.info("use reranking") for theta in thetas: distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, theta_value=theta) score = distmat index = np.argsort(score, axis=1) # from small to large scores.append(score) indices.append(index) dist_mats.append(distmat) return scores, indices, dist_mats else: logger.info("No reranking") distmat = -torch.mm(qf, gf.t()).cpu().numpy() score = distmat index = np.argsort(score, axis=1) # from small to large return score, index
def re_rank(qf, gf): return re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.4)
def test(self): epoch = self.scheduler.last_epoch + 1 self.ckpt.write_log('\n[INFO] Test:') self.model.eval() self.ckpt.add_log(torch.zeros(1, 5)) qf = self.extract_feature(self.query_loader).numpy() gf = self.extract_feature(self.test_loader).numpy() # no rerank dist = cdist(qf, gf) r = cmc(dist, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras, separate_camera_set=False, single_gallery_shot=False, first_match_break=True) m_ap = mean_ap(dist, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras) self.ckpt.log[-1, 0] = m_ap self.ckpt.log[-1, 1] = r[0] self.ckpt.log[-1, 2] = r[2] self.ckpt.log[-1, 3] = r[4] self.ckpt.log[-1, 4] = r[9] best = self.ckpt.log.max(0) self.ckpt.write_log( '[INFO]( ^_^ ) mAP: {:.4f} rank1: {:.4f} rank3: {:.4f} rank5: {:.4f} rank10: {:.4f} (Best: {:.4f} @epoch {})' .format(m_ap, r[0], r[2], r[4], r[9], best[0][0], (best[1][0] + 1) * self.args.test_every)) # rerank if self.args.re_rank: q_g_dist = np.dot(qf, np.transpose(gf)) q_q_dist = np.dot(qf, np.transpose(qf)) g_g_dist = np.dot(gf, np.transpose(gf)) dist_rerank = re_ranking(q_g_dist, q_q_dist, g_g_dist) r_rerank = cmc(dist_rerank, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras, separate_camera_set=False, single_gallery_shot=False, first_match_break=True) map_rerank = mean_ap(dist_rerank, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras) self.ckpt.log[-1, 0] = map_rerank self.ckpt.log[-1, 1] = r_rerank[0] self.ckpt.log[-1, 2] = r_rerank[2] self.ckpt.log[-1, 3] = r_rerank[4] self.ckpt.log[-1, 4] = r_rerank[9] best = self.ckpt.log.max(0) self.ckpt.write_log( '[INFO](rerank) mAP: {:.4f} rank1: {:.4f} rank3: {:.4f} rank5: {:.4f} rank10: {:.4f} (Best: {:.4f} @epoch {})' .format(map_rerank, r_rerank[0], r_rerank[2], r_rerank[4], r_rerank[9], best[0][0], (best[1][0] + 1) * self.args.test_every)) if not self.args.test_only: self.ckpt.save(self, epoch, is_best=((best[1][0] + 1) * self.args.test_every == epoch))
def inference_flipped_deprecated( cfg, model, test_dataloader, num_query, theta=0.95, use_local_feature=False # 是否使用local特征 ): logger = logging.getLogger("reid_baseline.inference") logger.info("Start inferencing") model.eval() g_feats, l_feats, gf_feats, lf_feats, pids, camids = [], [], [], [], [], [] val_prefetcher = data_prefetcher(test_dataloader, cfg) batch = val_prefetcher.next() while batch[0] is not None: img, pid, camid = batch with torch.no_grad(): g_feat, bn_gf, lf, l_feat = model(img) gf_feat, bn_gff, lff, lf_feat = model(torch.flip(img, [3])) g_feats.append(g_feat.data.cpu()) l_feats.append(l_feat.data.cpu()) gf_feats.append(gf_feat.data.cpu()) lf_feats.append(lf_feat.data.cpu()) pids.extend(pid.cpu().numpy()) camids.extend(np.asarray(camid)) batch = val_prefetcher.next() g_feats = torch.cat(g_feats, dim=0) l_feats = torch.cat(l_feats, dim=0) gf_feats = torch.cat(gf_feats, dim=0) lf_feats = torch.cat(lf_feats, dim=0) if cfg.TEST.NORM: g_feats = F.normalize(g_feats, p=2, dim=1) gf_feats = F.normalize(gf_feats, p=2, dim=1) # query qf = g_feats[:num_query] lqf = l_feats[:num_query] qff = gf_feats[:num_query] lqff = lf_feats[:num_query] q_pids = np.asarray(pids[:num_query]) q_camids = np.asarray(camids[:num_query]) # gallery gf = g_feats[num_query:] lgf = l_feats[num_query:] gff = gf_feats[num_query:] lgff = lf_feats[num_query:] g_pids = np.asarray(pids[num_query:]) g_camids = np.asarray(camids[num_query:]) # calculate the global distance scores, indices, dist_mats = [], [], [] #use_local_feature = True if use_local_feature: logger.info("--------computing local features ...--------") lqf = lqf.permute(0, 2, 1) lgf = lgf.permute(0, 2, 1) local_distmat = low_memory_local_dist(lqf.numpy(), lgf.numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqf.numpy(), lqf.numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgf.numpy(), lgf.numpy(), aligned=True) local_dist = np.concatenate([ np.concatenate([local_qq_distmat, local_distmat], axis=1), np.concatenate([local_distmat.T, local_gg_distmat], axis=1) ], axis=0) logger.info("--------computing flipped local features ...--------") lqff = lqff.permute(0, 2, 1) lgff = lgff.permute(0, 2, 1) local_distmat = low_memory_local_dist(lqff.numpy(), lgff.numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqff.numpy(), lqff.numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgff.numpy(), lgff.numpy(), aligned=True) local_dist_flip = np.concatenate([ np.concatenate([local_qq_distmat, local_distmat], axis=1), np.concatenate([local_distmat.T, local_gg_distmat], axis=1) ], axis=0) else: local_dist = None local_dist_flip = None logger.info("use reranking") #for theta in thetas: if True: distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_dist, theta_value=theta, only_local=False) distmat_flip = re_ranking(qff, gff, k1=6, k2=2, lambda_value=0.3, local_distmat=local_dist_flip, theta_value=theta, only_local=False) # 合并距离 distmat = (distmat + distmat_flip) / 2 score = distmat index = np.argsort(score, axis=1) # from small to large scores.append(score) indices.append(index) dist_mats.append(distmat) return scores, indices, dist_mats
def generate_submit_and_visualize_files(cfg, txt_dir, feats, num_query, dataset, directory, feat_norm, max_rank=100): dist_directory = os.path.join(directory, 'generate_feats_for_visual') if not os.path.exists(dist_directory): os.makedirs(dist_directory) if cfg['DATASETS.TRACKS']: # feats = torch.cat(feats, dim=0) if feat_norm == 'yes': print("The test feature is normalized") feats_normed = torch.nn.functional.normalize(feats, dim=1, p=2) # query qf = feats_normed[:num_query] # gallery ## für tracks test_name_track_indice = list( dataset.test_track_indice_from_test_name.items()) test_name_track_indice.sort() track_indice = np.array([item[1] for item in test_name_track_indice]) gf_tracks = feats_normed[num_query:] gf = gf_tracks[track_indice] ## m, n = qf.shape[0], gf.shape[0] distmat = torch.pow(qf, 2).sum(dim=1, keepdim=True).expand(m, n) + \ torch.pow(gf, 2).sum(dim=1, keepdim=True).expand(n, m).t() distmat.addmm_(1, -2, qf, gf.t()) distmat = distmat.cpu().numpy() print(123) else: # feats = torch.cat(feats, dim=0) if feat_norm == 'yes': print("The test feature is normalized") feats_normed = torch.nn.functional.normalize(feats, dim=1, p=2) # query qf = feats_normed[:num_query] # gallery gf = feats_normed[num_query:] m, n = qf.shape[0], gf.shape[0] distmat = torch.pow(qf, 2).sum(dim=1, keepdim=True).expand(m, n) + \ torch.pow(gf, 2).sum(dim=1, keepdim=True).expand(n, m).t() distmat.addmm_(1, -2, qf, gf.t()) distmat = distmat.cpu().numpy() if cfg['DATASETS.TRACKS']: statistic_name = 'direct_track' else: statistic_name = 'direct' generate_image_dir_and_txt(cfg, dataset, txt_dir, distmat, statistic_name=statistic_name, dist_directory=dist_directory, max_rank=100) np.save(os.path.join(dist_directory, 'feat' + statistic_name + '.npy'), np.array(feats.cpu())) if cfg['DATASETS.TRACKS']: distmat_rerank_track = re_ranking(qf, gf_tracks, k1=6, k2=3, lambda_value=0.3) statistic_name = 'rerank_track' distmat_rerank = distmat_rerank_track[:, track_indice] else: distmat_rerank = re_ranking(qf, gf, k1=20, k2=6, lambda_value=0.3) statistic_name = 'rerank' generate_image_dir_and_txt(cfg, dataset, txt_dir, distmat_rerank, statistic_name=statistic_name, dist_directory=dist_directory, max_rank=100)
def cal_cos_dis_2_matrix(a1, a2, a3, a4, b1, b2, b3, b4): a = a1 b = b1 a_norm = np.sqrt(np.sum(a**2, axis=1)).reshape(a.shape[0], 1) b_norm = np.sqrt(np.sum(b**2, axis=1)).reshape(b.shape[0], 1) a_normed = a / a_norm b_normed = b / b_norm query_feature = a_normed gallery_feature = b_normed ''' a_norm = np.sqrt(np.sum(a1 ** 2, axis=1)).reshape(a1.shape[0], 1) b_norm = np.sqrt(np.sum(b1 ** 2, axis=1)).reshape(b1.shape[0], 1) a1_normed = a1 / a_norm b1_normed = b1 / b_norm a_norm = np.sqrt(np.sum(a2 ** 2, axis=1)).reshape(a2.shape[0], 1) b_norm = np.sqrt(np.sum(b2 ** 2, axis=1)).reshape(b2.shape[0], 1) a2_normed = a2 / a_norm b2_normed = b2 / b_norm query_feature = a1_normed+a2_normed gallery_feature = b1_normed+b2_normed ''' q_g_dist = np.dot(query_feature, np.transpose(gallery_feature)) q_q_dist = np.dot(query_feature, np.transpose(query_feature)) g_g_dist = np.dot(gallery_feature, np.transpose(gallery_feature)) cos_mat = re_ranking(q_g_dist, q_q_dist, g_g_dist) a = a2 b = b2 a_norm = np.sqrt(np.sum(a**2, axis=1)).reshape(a.shape[0], 1) b_norm = np.sqrt(np.sum(b**2, axis=1)).reshape(b.shape[0], 1) a_normed = a / a_norm b_normed = b / b_norm query_feature = a_normed gallery_feature = b_normed ''' a_norm = np.sqrt(np.sum(a1 ** 2, axis=1)).reshape(a1.shape[0], 1) b_norm = np.sqrt(np.sum(b1 ** 2, axis=1)).reshape(b1.shape[0], 1) a1_normed = a1 / a_norm b1_normed = b1 / b_norm a_norm = np.sqrt(np.sum(a2 ** 2, axis=1)).reshape(a2.shape[0], 1) b_norm = np.sqrt(np.sum(b2 ** 2, axis=1)).reshape(b2.shape[0], 1) a2_normed = a2 / a_norm b2_normed = b2 / b_norm query_feature = a1_normed+a2_normed gallery_feature = b1_normed+b2_normed ''' q_g_dist = np.dot(query_feature, np.transpose(gallery_feature)) q_q_dist = np.dot(query_feature, np.transpose(query_feature)) g_g_dist = np.dot(gallery_feature, np.transpose(gallery_feature)) cos_mat2 = re_ranking(q_g_dist, q_q_dist, g_g_dist) a = a3 b = b3 a_norm = np.sqrt(np.sum(a**2, axis=1)).reshape(a.shape[0], 1) b_norm = np.sqrt(np.sum(b**2, axis=1)).reshape(b.shape[0], 1) a_normed = a / a_norm b_normed = b / b_norm query_feature = a_normed gallery_feature = b_normed ''' a_norm = np.sqrt(np.sum(a1 ** 2, axis=1)).reshape(a1.shape[0], 1) b_norm = np.sqrt(np.sum(b1 ** 2, axis=1)).reshape(b1.shape[0], 1) a1_normed = a1 / a_norm b1_normed = b1 / b_norm a_norm = np.sqrt(np.sum(a2 ** 2, axis=1)).reshape(a2.shape[0], 1) b_norm = np.sqrt(np.sum(b2 ** 2, axis=1)).reshape(b2.shape[0], 1) a2_normed = a2 / a_norm b2_normed = b2 / b_norm query_feature = a1_normed+a2_normed gallery_feature = b1_normed+b2_normed ''' q_g_dist = np.dot(query_feature, np.transpose(gallery_feature)) q_q_dist = np.dot(query_feature, np.transpose(query_feature)) g_g_dist = np.dot(gallery_feature, np.transpose(gallery_feature)) cos_mat3 = re_ranking(q_g_dist, q_q_dist, g_g_dist) a = a4 b = b4 a_norm = np.sqrt(np.sum(a**2, axis=1)).reshape(a.shape[0], 1) b_norm = np.sqrt(np.sum(b**2, axis=1)).reshape(b.shape[0], 1) a_normed = a / a_norm b_normed = b / b_norm query_feature = a_normed gallery_feature = b_normed ''' a_norm = np.sqrt(np.sum(a1 ** 2, axis=1)).reshape(a1.shape[0], 1) b_norm = np.sqrt(np.sum(b1 ** 2, axis=1)).reshape(b1.shape[0], 1) a1_normed = a1 / a_norm b1_normed = b1 / b_norm a_norm = np.sqrt(np.sum(a2 ** 2, axis=1)).reshape(a2.shape[0], 1) b_norm = np.sqrt(np.sum(b2 ** 2, axis=1)).reshape(b2.shape[0], 1) a2_normed = a2 / a_norm b2_normed = b2 / b_norm query_feature = a1_normed+a2_normed gallery_feature = b1_normed+b2_normed ''' q_g_dist = np.dot(query_feature, np.transpose(gallery_feature)) q_q_dist = np.dot(query_feature, np.transpose(query_feature)) g_g_dist = np.dot(gallery_feature, np.transpose(gallery_feature)) cos_mat4 = re_ranking(q_g_dist, q_q_dist, g_g_dist) cos_mat = (cos_mat + cos_mat2 + cos_mat3 + cos_mat4) / 4.0 return cos_mat
def test(self): epoch = self.scheduler.last_epoch self.ckpt.write_log('\n[INFO] Test:') self.model.eval() self.ckpt.add_log(torch.zeros(1, 6)) # qf = self.extract_feature(self.query_loader,self.args).numpy() # gf = self.extract_feature(self.test_loader,self.args).numpy() qf = self.extract_feature(self.query_loader, self.args) gf = self.extract_feature(self.test_loader, self.args) # qf = self.extract_feature(self.query_loader) # gf = self.extract_feature(self.test_loader) query_ids = np.asarray(self.queryset.ids) gallery_ids = np.asarray(self.testset.ids) query_cams = np.asarray(self.queryset.cameras) gallery_cams = np.asarray(self.testset.cameras) # print(query_ids.shape) # print(gallery_ids.shape) # print(query_cams.shape) # print(gallery_cams.shape) # np.save('gf',gf.numpy()) # np.save('qf',qf.numpy()) # np.save('qc',query_cams) # np.save('gc',gallery_cams) # np.save('qi',query_ids) # np.save('gi',gallery_ids) # qf=np.load('/content/qf.npy') # gf=np.load('/content/gf.npy') # print('save') # result = scipy.io.loadmat('pytorch_result.mat') # qf = torch.FloatTensor(result['query_f']).cuda() # query_cam = result['query_cam'][0] # query_label = result['query_label'][0] # gf = torch.FloatTensor(result['gallery_f']).cuda() # gallery_cam = result['gallery_cam'][0] # gallery_label = result['gallery_label'][0] # print(query_cam.shape) # print(gallery_cam.shape) # print(query_label.shape) # print(gallery_label.shape) if self.args.re_rank: q_g_dist = np.dot(qf, np.transpose(gf)) q_q_dist = np.dot(qf, np.transpose(qf)) g_g_dist = np.dot(gf, np.transpose(gf)) dist = re_ranking(q_g_dist, q_q_dist, g_g_dist) else: # dist = cdist(qf, gf,metric='cosine') # cosine distance dist = 1 - torch.mm(qf, gf.t()).cpu().numpy() # m, n = qf.shape[0], gf.shape[0] # dist = torch.pow(qf, 2).sum(dim=1, keepdim=True).expand(m, n) + \ # torch.pow(gf, 2).sum(dim=1, keepdim=True).expand(n, m).t() # dist.addmm_(1, -2, qf, gf.t()) # dist = np.dot(qf,np.transpose(gf)) # print('2') # r = cmc(dist, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras, # separate_camera_set=False, # single_gallery_shot=False, # first_match_break=True) # m_ap = mean_ap(dist, self.queryset.ids, self.testset.ids, # self.queryset.cameras, self.testset.cameras) # r = cmc(dist, query_label, gallery_label, query_cam, gallery_cam, # separate_camera_set=False, # single_gallery_shot=False, # first_match_break=True) # m_ap = mean_ap(dist, query_label, gallery_label, query_cam, gallery_cam) # r, m_ap = cmc_baseline(dist, query_label, gallery_label, query_cam, gallery_cam, # separate_camera_set=False, # single_gallery_shot=False, # first_match_break=True) # r, m_ap = cmc_baseline(dist, query_ids, gallery_ids, query_cams, gallery_cams, # separate_camera_set=False, # single_gallery_shot=False, # first_match_break=True) # r,m_ap=eval_liaoxingyu(dist, query_label, gallery_label, query_cam, gallery_cam, 50) r, m_ap = eval_liaoxingyu( dist, query_ids, gallery_ids, query_cams, gallery_cams, 50) self.ckpt.log[-1, 0] = epoch self.ckpt.log[-1, 1] = m_ap self.ckpt.log[-1, 2] = r[0] self.ckpt.log[-1, 3] = r[2] self.ckpt.log[-1, 4] = r[4] self.ckpt.log[-1, 5] = r[9] best = self.ckpt.log.max(0) # self.ckpt.write_log( # '[INFO] mAP: {:.4f} rank1: {:.4f} rank3: {:.4f} rank5: {:.4f} rank10: {:.4f} (Best: {:.4f} @epoch {})'.format( # m_ap, # r[0], r[2], r[4], r[9], # best[0][0], # (best[1][0] + 1) * self.args.test_every # ) # ) self.ckpt.write_log( '[INFO] mAP: {:.4f} rank1: {:.4f} rank3: {:.4f} rank5: {:.4f} rank10: {:.4f} (Best: {:.4f} @epoch {})'.format( m_ap, r[0], r[2], r[4], r[9], best[0][1], self.ckpt.log[best[1][1], 0] ) ) # if not self.args.test_only: # self.ckpt.save(self, epoch, is_best=( # (best[1][0] + 1) * self.args.test_every == epoch)) if not self.args.test_only: self.ckpt.save(self, epoch, is_best=( self.ckpt.log[best[1][1], 0] == epoch))
def inference_flipped(cfg, model, test_dataloader, num_query): logger = logging.getLogger("reid_baseline.inference") logger.info("Start inferencing") model.eval() feats, feats_flipped, pids, camids = [], [], [], [] local_feats, local_feats_flipped = [], [] local_feats2, local_feats2_flipped = [], [] test_prefetcher = data_prefetcher(test_dataloader) batch = test_prefetcher.next() while batch[0] is not None: img, pid, camid = batch with torch.no_grad(): feat = model(img) feat_flipped = model(torch.flip(img, [3])) if isinstance(feat, tuple): feats.append(feat[0]) feats_flipped.append(feat_flipped[0]) #print('feat[1]', feat[1][0].size(), feat[1][1].size()) if len(feat[1]) > 1: local_feats.append(feat[1][0]) local_feats2.append(feat[1][1]) local_feats_flipped.append(feat_flipped[1][0]) local_feats2_flipped.append(feat_flipped[1][1]) else: local_feats.append(feat[1]) local_feats_flipped.append(feat_flipped[1]) else: feats.append(feat) feats_flipped.append(feat_flipped) pids.extend(pid.cpu().numpy()) camids.extend(np.asarray(camid)) batch = test_prefetcher.next() feats = torch.cat(feats, dim=0) feats_flipped = torch.cat(feats_flipped, dim=0) if len(local_feats) > 0: local_feats = torch.cat(local_feats, dim=0) local_feats_flipped = torch.cat(local_feats_flipped, dim=0) if len(local_feats2) > 0: local_feats2 = torch.cat(local_feats2, dim=0) local_feats2_flipped = torch.cat(local_feats2_flipped, dim=0) if cfg.TEST.NORM: feats = F.normalize(feats, p=2, dim=1) feats_flipped = F.normalize(feats_flipped, p=2, dim=1) # query qf = feats[:num_query] qf_flipped = feats_flipped[:num_query] if len(local_feats) > 0: lqf = local_feats[:num_query] lqf_flipped = local_feats_flipped[:num_query] if len(local_feats2) > 0: lqf2 = local_feats2[:num_query] lqf2_flipped = local_feats2_flipped[:num_query] q_pids = np.asarray(pids[:num_query]) q_camids = np.asarray(camids[:num_query]) # gallery gf = feats[num_query:] gf_flipped = feats_flipped[num_query:] if len(local_feats) > 0: lgf = local_feats[num_query:] lgf_flipped = local_feats_flipped[num_query:] if len(local_feats2) > 0: lgf2 = local_feats2[num_query:] lgf2_flipped = local_feats2_flipped[num_query:] g_pids = np.asarray(pids[num_query:]) g_camids = np.asarray(camids[num_query:]) # cosine distance #distmat = torch.mm(qf, gf.t()).cpu().numpy() if len(local_feats) > 0: local_distmat = compute_local_distmat(lqf, lgf) local_distmat_flipped = compute_local_distmat(lqf_flipped, lgf_flipped) else: local_distmat = None local_distmat_flipped = None if len(local_feats2) > 0: local_distmat2 = compute_local_distmat(lqf2, lgf2) local_distmat2_flipped = compute_local_distmat(lqf2_flipped, lgf2_flipped) else: local_distmat2 = None local_distmat2_flipped = None # use reranking logger.info("use reranking") #distmat = re_ranking(qf, gf, k1=14, k2=4, lambda_value=0.4) search_theta = True if search_theta: best_score = 0 #for theta in np.linspace(0.9, 1.0, 11): for theta in np.linspace(0.5, 1.0, 11): for theta2 in np.linspace(0.75, 1.0, 11): distmat = re_ranking_v3(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, theta_value=theta, local_distmat2=local_distmat2, theta_value2=theta2, only_local=False) distmat_flipped = re_ranking_v3( qf_flipped, gf_flipped, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat_flipped, theta_value=theta, local_distmat2=local_distmat2_flipped, theta_value2=1.0, only_local=False) distmat = (distmat + distmat_flipped) / 2 #cmc, mAP = evaluate(distmat + distmat_flipped, q_pids, g_pids, q_camids, g_camids) cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) score = (cmc[0] + mAP) / 2 print('theta, theta2', np.around(theta, 2), np.around(theta2, 3), 'r1, mAP, score', np.around(cmc[0], 4), np.around(mAP, 4), np.around(score, 4)) if score > best_score: best_score = score best_param = [theta, theta2] best_distmat = distmat # saving strtime = time.strftime("%Y%m%d_%H%M%S", time.localtime()) if False and abs(theta - 0.95) < 1e-4: # saving dist_mats f = h5py.File( 'dist_mats/val_%s_%s_t0.95_flip.h5' % (cfg.MODEL.NAME, strtime), 'w') f.create_dataset('dist_mat', data=distmat, compression='gzip') f.close() print('Best Param', best_param) distmat = best_distmat else: distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, only_local=False, theta_value=0.95) #(current best) distmat_flipped = re_ranking(qf_flipped, gf_flipped, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat_flipped, theta_value=0.95, only_local=False) # (current best) distmat = (distmat + distmat_flipped) / 2 cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) logger.info(f"mAP: {mAP:.1%}") for r in [1, 5, 10]: logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}") logger.info(f"Score: {(mAP + cmc[0]) / 2.:.1%}")
def test(self): epoch = self.scheduler.last_epoch + 1 self.ckpt.write_log('\n[INFO] Test:') self.model.eval() self.ckpt.add_log(torch.zeros(1, 5)) qf = self.extract_feature(self.query_loader).numpy() gf = self.extract_feature(self.test_loader).numpy() # distence threshold norms_q = np.linalg.norm(qf, axis=1) # axis=1, l1范数 norms_g = np.linalg.norm(gf, axis=1) qf = qf / np.reshape(norms_q, ((qf.shape)[0], 1)) gf = gf / np.reshape(norms_g, ((gf.shape)[0], 1)) # no rerank dist = cdist( qf, gf) # metric='cosine',计算两个矩阵行间的所有向量对的距离,默认:euclidean; 3368*15913 m_ap = mean_ap(dist, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras) r = cmc(dist, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras, separate_camera_set=False, single_gallery_shot=False, first_match_break=True) self.ckpt.log[-1, 0] = m_ap self.ckpt.log[-1, 1] = r[0] self.ckpt.log[-1, 2] = r[2] self.ckpt.log[-1, 3] = r[4] self.ckpt.log[-1, 4] = r[9] best = self.ckpt.log.max(0) self.ckpt.write_log( '[INFO]( ^_^ ) mAP: {:.4f} rank1: {:.4f} rank3: {:.4f} rank5: {:.4f} rank10: {:.4f} (Best: {:.4f} @epoch {})' .format(m_ap, r[0], r[2], r[4], r[9], best[0][0], (best[1][0] + 1) * self.args.test_every)) # rerank if self.args.re_rank: q_g_dist = np.dot(qf, np.transpose(gf)) q_q_dist = np.dot(qf, np.transpose(qf)) g_g_dist = np.dot(gf, np.transpose(gf)) dist_rerank = re_ranking(q_g_dist, q_q_dist, g_g_dist) r_rerank = cmc(dist_rerank, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras, separate_camera_set=False, single_gallery_shot=False, first_match_break=True) map_rerank = mean_ap(dist_rerank, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras) self.ckpt.log[-1, 0] = map_rerank self.ckpt.log[-1, 1] = r_rerank[0] self.ckpt.log[-1, 2] = r_rerank[2] self.ckpt.log[-1, 3] = r_rerank[4] self.ckpt.log[-1, 4] = r_rerank[9] best = self.ckpt.log.max(0) self.ckpt.write_log( '[INFO](rerank) mAP: {:.4f} rank1: {:.4f} rank3: {:.4f} rank5: {:.4f} rank10: {:.4f} (Best: {:.4f} @epoch {})' .format(map_rerank, r_rerank[0], r_rerank[2], r_rerank[4], r_rerank[9], best[0][0], (best[1][0] + 1) * self.args.test_every)) if not self.args.test_only: self.ckpt.save(self, epoch, is_best=((best[1][0] + 1) * self.args.test_every == epoch))
def compute_distmat(cfg, num_query, feats, feats_flipped, local_feats, local_feats_flipped, theta, use_local_feature, use_rerank): """ Given a pair of global feature and local feature, compute distmat. :param cfg: :param num_query: :param pids: :param camids: :param feats: :param feats_flipped: :param local_feats: :param local_feats_flipped: :param theta: :param use_local_feature: :return: """ feats = torch.cat(feats, dim=0) feats_flipped = torch.cat(feats_flipped, dim=0) if len(local_feats) > 0 and use_local_feature: local_feats = torch.cat(local_feats, dim=0) local_feats_flipped = torch.cat(local_feats_flipped, dim=0) # print('feats_flipped', len(feats_flipped), feats_flipped[0]) if cfg.TEST.NORM: feats = F.normalize(feats, p=2, dim=1) feats_flipped = F.normalize(feats_flipped, p=2, dim=1) ## torch to numpy to save memory in re_ranking #feats = feats.numpy() #feats_flipped = feats_flipped.numpy() ########### # query qf = feats[:num_query] qf_flipped = feats_flipped[:num_query] if len(local_feats) > 0 and use_local_feature: lqf = local_feats[:num_query] lqf_flipped = local_feats_flipped[:num_query] #q_pids = np.asarray(pids[:num_query]) #q_camids = np.asarray(camids[:num_query]) # gallery gf = feats[num_query:] gf_flipped = feats_flipped[num_query:] if len(local_feats) > 0: lgf = local_feats[num_query:] lgf_flipped = local_feats_flipped[num_query:] #g_pids = np.asarray(pids[num_query:]) #g_camids = np.asarray(camids[num_query:]) ############### # 初步筛选gallery中合适的样本 (有问题) if False: distmat = -torch.mm(qf, gf.t()).numpy() index = np.argsort(distmat, axis=1) # from small to large new_gallery_index = np.unique(index[:, :top_k].reshape(-1)) print('new_gallery_index', len(new_gallery_index)) original_distmat = distmat gf = gf[new_gallery_index] gf_flipped = gf_flipped[new_gallery_index] lgf = lgf[new_gallery_index] lgf_flipped = lgf_flipped[new_gallery_index] ############## if len(local_feats) > 0 and use_local_feature: # if True: # calculate the local distance lqf = lqf.permute(0, 2, 1) lgf = lgf.permute(0, 2, 1) local_qg_distmat = low_memory_local_dist(lqf.numpy(), lgf.numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqf.numpy(), lqf.numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgf.numpy(), lgf.numpy(), aligned=True) local_distmat = np.concatenate( [np.concatenate([local_qq_distmat, local_qg_distmat], axis=1), np.concatenate([local_qg_distmat.T, local_gg_distmat], axis=1)], axis=0) # flipped lqf = lqf_flipped.permute(0, 2, 1) lgf = lgf_flipped.permute(0, 2, 1) local_qg_distmat = low_memory_local_dist(lqf.numpy(), lgf.numpy(), aligned=True) local_qq_distmat = low_memory_local_dist(lqf.numpy(), lqf.numpy(), aligned=True) local_gg_distmat = low_memory_local_dist(lgf.numpy(), lgf.numpy(), aligned=True) local_distmat_flipped = np.concatenate( [np.concatenate([local_qq_distmat, local_qg_distmat], axis=1), np.concatenate([local_qg_distmat.T, local_gg_distmat], axis=1)], axis=0) else: local_distmat = None local_distmat_flipped = None if use_rerank: distmat = re_ranking(qf, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat, theta_value=theta, only_local=False) # (current best) distmat += re_ranking(qf_flipped, gf_flipped, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat_flipped, theta_value=theta, only_local=False) # (current best) distmat += re_ranking(qf, gf_flipped, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat_flipped, theta_value=theta, only_local=False) # (current best) distmat += re_ranking(qf_flipped, gf, k1=6, k2=2, lambda_value=0.3, local_distmat=local_distmat_flipped, theta_value=theta, only_local=False) # (current best) del qf, gf del qf_flipped, gf_flipped distmat /= 4 else: distmat = -torch.mm(qf, gf.t()).cpu().numpy() distmat_flipped = -torch.mm(qf_flipped, gf_flipped.t()).cpu().numpy() distmat = (distmat + distmat_flipped) / 2 #if True: # cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids) # score = (cmc[0] + mAP) / 2 #return qf, gf, local_distmat, qf_flipped, gf_flipped, local_distmat_flipped return distmat
def test(self): epoch = self.scheduler.last_epoch + 1 self.ckpt.write_log('\n[INFO] Test:') self.model.eval() self.ckpt.add_log(torch.zeros(1, 5)) qf, q_image_paths = self.extract_feature(self.query_loader) gf, g_image_paths = self.extract_feature(self.test_loader) qf = qf.numpy() # (31, 2048) for debug gf = gf.numpy() # (154, 2048) for if self.args.re_rank: q_g_dist = np.dot(qf, np.transpose(gf)) q_q_dist = np.dot(qf, np.transpose(qf)) g_g_dist = np.dot(gf, np.transpose(gf)) dist = re_ranking(q_g_dist, q_q_dist, g_g_dist) else: dist = cdist(qf, gf, metric='euclidean') if self.args.multi_query: # Suitable for boxes dataset only # Use several same id query samples to retrieval one gallery print(dist.shape) # (31, 154) ids = [ int(x.split(os.sep)[-1].split('_')[0]) for x in q_image_paths ] ids_set = set(ids) ids_np = np.asarray(ids, dtype=np.int32) for id in ids_set: indices = np.where(ids_np == id)[0] mean = np.mean(dist[indices, :], axis=0) for index in indices: dist[index, :] = mean if self.args.multi_gallery: # Suitable for boxes dataset only # query samples to retrieval images and mean the same id of gallery print(dist.shape) # (31, 154) for debug ids = [ int(x.split(os.sep)[-1].split('_')[0]) for x in g_image_paths ] ids_set = set(ids) ids_np = np.asarray(ids, dtype=np.int32) for i, q_image_path in enumerate(q_image_paths): for id in ids_set: indices = np.where(ids_np == id)[0] mean = np.mean(dist[i, indices], axis=0) dist[i, indices] = mean r = cmc(dist, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras, separate_camera_set=False, single_gallery_shot=False, first_match_break=True) m_ap = mean_ap(dist, self.queryset.ids, self.testset.ids, self.queryset.cameras, self.testset.cameras) self.ckpt.log[-1, 0] = m_ap self.ckpt.log[-1, 1] = r[0] self.ckpt.log[-1, 2] = r[2] self.ckpt.log[-1, 3] = r[4] self.ckpt.log[-1, 4] = r[9] best = self.ckpt.log.max(0) self.ckpt.write_log( '[INFO] mAP: {:.4f} rank1: {:.4f} rank3: {:.4f} rank5: {:.4f} rank10: {:.4f} (Best: {:.4f} @epoch {})' .format(m_ap, r[0], r[2], r[4], r[9], best[0][0], (best[1][0] + 1) * self.args.test_every)) # Another method to calculate cmc and mAP, it get the same result! # print(eval_market1501(dist, self.queryset.ids, self.testset.ids, # self.queryset.cameras, self.testset.cameras, 100)) if not self.args.test_only: self.ckpt.save(self, epoch, is_best=((best[1][0] + 1) * self.args.test_every == epoch))
def my_inference(model, transform, batch_size): # 传入模型,数据预处理方法,batch_size query_list = list() # with open(data_root + 'query_a_list.txt', 'r') as f: # # 测试集中txt文件 # lines = f.readlines() # for i, line in enumerate(lines): # data = line.split(" ") # image_name = data[0].split("/")[1] # img_file = os.path.join(data_root + 'query_b', image_name) # 测试集query文件夹 # query_list.append(img_file) query_list = [ os.path.join(data_root + 'query_b', x) for x in # 测试集gallery文件夹 os.listdir(data_root + 'query_b') ] gallery_list = [ os.path.join(data_root + 'gallery_b', x) for x in # 测试集gallery文件夹 os.listdir(data_root + 'gallery_b') ] query_num = len(query_list) img_list = list() for q_img in query_list: q_img = read_image(q_img) q_img = transform(q_img) img_list.append(q_img) for g_img in gallery_list: g_img = read_image(g_img) g_img = transform(g_img) img_list.append(g_img) # img_list = img_list[:1000] iter_n = int(len(img_list) / batch_size) # batch_size if len(img_list) % batch_size != 0: iter_n += 1 # img_list = img_list[0:iter_n*batch_size] print(iter_n) img_data = torch.Tensor([t.numpy() for t in img_list]).cuda() # img_data = torch.Tensor([t.numpy() for t in img_list]).cpu model = model.to(device) model.eval() all_feature = list() for i in range(iter_n): print("batch ----%d----" % (i)) batch_data = img_data[i * batch_size:(i + 1) * batch_size] with torch.no_grad(): batch_feature = model(batch_data).detach().cpu() # print(batch_feature) # batch_feature = model( batch_data ).detach().cuda() all_feature.append(batch_feature) print('done') all_feature = torch.cat(all_feature) gallery_feat = all_feature[query_num:] query_feat = all_feature[:query_num] distmat = re_ranking(query_feat, gallery_feat, k1=20, k2=6, lambda_value=0.3) # rerank方法 # distmat = distmat # 如果使用 euclidean_dist,不使用rerank改为:distamt = distamt.numpy() num_q, num_g = distmat.shape print(num_q) indices = np.argsort(distmat, axis=1) max_200_indices = indices[:, :200] print(max_200_indices) res_dict = dict() for q_idx in range(num_q): print(query_list[q_idx]) filename = query_list[q_idx][query_list[q_idx].rindex("/") + 1:] max_200_files = [ gallery_list[i][gallery_list[i].rindex("/") + 1:] for i in max_200_indices[q_idx] ] res_dict[filename] = max_200_files with open(r'submission_B_4.json', 'w', encoding='utf-8') as f: # 提交文件 json.dump(res_dict, f)