예제 #1
0
    def on_epoch_begin(self):
        self.batch_nb = 0
        self.current_epoch += 1
        self.t0 = time.time()
        self.running_loss.reset()

        self.tng_prefetcher = data_prefetcher(self.tng_dataloader)
예제 #2
0
def inference_with_distmat(
    cfg,
    test_dataloader,
    num_query,
    distmat,
):
    logger = logging.getLogger("reid_baseline.inference")
    logger.info("Start inferencing")

    pids, camids = [], []
    test_prefetcher = data_prefetcher(test_dataloader, cfg)
    batch = test_prefetcher.next()
    while batch[0] is not None:
        img, pid, camid = batch
        pids.extend(pid.cpu().numpy())
        camids.extend(np.asarray(camid))
        batch = test_prefetcher.next()

    # query
    q_pids = np.asarray(pids[:num_query])
    q_camids = np.asarray(camids[:num_query])
    # gallery
    g_pids = np.asarray(pids[num_query:])
    g_camids = np.asarray(camids[num_query:])

    #distmat = re_ranking(qf, gf, k1=14, k2=4, lambda_value=0.4)

    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%}")
예제 #3
0
    def get_distmat(self):
        m = self.model.eval()
        feats = []
        pids = []
        camids = []
        val_prefetcher = data_prefetcher(self.val_dataloader)
        batch = val_prefetcher.next()
        while batch[0] is not None:
            img, pid, camid = batch
            with torch.no_grad():
                feat = m(img.cuda())
            feats.append(feat)
            pids.extend(pid.cpu().numpy())
            camids.extend(np.asarray(camid))
        feats = torch.cat(feats, dim=0)
        if self.cfg.TEST.NORM:
            feats = F.normalize(feats)
        qf = feats[:self.num_query]
        gf = feats[self.num_query:]
        self.q_pids = np.asarray(pids[:self.num_query])
        self.g_pids = np.asarray(pids[self.num_query:])
        self.q_camids = np.asarray(camids[:self.num_query])
        self.g_camids = np.asarray(camids[self.num_query:])

        # Cosine distance
        distmat = torch.mm(qf, gf.t())
        self.distmat = distmat.cpu().numpy()
        self.indices = np.argsort(-self.distmat, axis=1)
        self.matches = (
            self.g_pids[self.indices] == self.q_pids[:, np.newaxis]).astype(
                np.int32)
예제 #4
0
    def test(self):
        # convert to eval mode
        self.model.eval()

        feats, pids, camids = [], [], []
        val_prefetcher = data_prefetcher(self.val_dataloader, self.cfg)
        batch = val_prefetcher.next()
        while batch[0] is not None:
            img, pid, camid = batch
            with torch.no_grad():
                feat = self.model(img)
            if isinstance(feat, tuple):
                feats.append(feat[0])
            else:
                feats.append(feat)

            pids.extend(pid.cpu().numpy())
            camids.extend(np.asarray(camid))

            batch = val_prefetcher.next()

        ####
        feats = torch.cat(feats, dim=0)
        if self.cfg.TEST.NORM:
            feats = F.normalize(feats, p=2, dim=1)

        # query
        qf = feats[:self.num_query]

        q_pids = np.asarray(pids[:self.num_query])
        q_camids = np.asarray(camids[:self.num_query])
        # gallery
        gf = feats[self.num_query:]

        g_pids = np.asarray(pids[self.num_query:])
        g_camids = np.asarray(camids[self.num_query:])

        # TODO: 添加rerank的测评结果
        # m, n = qf.shape[0], gf.shape[0]
        distmat = -torch.mm(qf, gf.t()).cpu().numpy()

        # 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.numpy()
        cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids)
        self.logger.info(f"Test Results - Epoch: {self.current_epoch}")
        self.logger.info(f"mAP: {mAP:.1%}")
        for r in [1, 5, 10]:
            self.logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}")

        self.writer.add_scalar('rank1', cmc[0], self.global_step)
        self.writer.add_scalar('mAP', mAP, self.global_step)
        metric_dict = {'rank1': cmc[0], 'mAP': mAP}
        # convert to train mode
        self.model.train()
        return metric_dict
예제 #5
0
    def on_epoch_begin(self):
        self.batch_nb = 0
        self.current_epoch += 1
        self.t0 = time.time()
        self.running_loss.reset()

        if 'InsDis' in list(self.cfg.SOLVER.LOSSTYPE):
            self.tng_prefetcher = instance_prefetcher(self.tng_dataloader)
        else:
            self.tng_prefetcher = data_prefetcher(self.tng_dataloader)
예제 #6
0
def inference_no_rerank(cfg, model, test_dataloader, num_query):
    logger = logging.getLogger("reid_baseline.inference")
    logger.info("Start inferencing")

    model.eval()

    feats, pids, camids = [], [], []
    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:])

    distmat = -torch.mm(qf, gf.t()).cpu().numpy()

    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%}")

    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))

    return new_gallery_index
예제 #7
0
    def test(self):
        # convert to eval mode
        self.model.eval()
        
        metric_dict = list()
        for val_dataset_name, val_dataloader, num_query in zip(self.cfg.DATASETS.TEST_NAMES, self.val_dataloader_collection, self.num_query_len_collection):
            feats,pids,camids = [],[],[]
            val_prefetcher = data_prefetcher(val_dataloader)
            batch = val_prefetcher.next()
            while batch[0] is not None:
                img, pid, camid = batch
                with torch.no_grad():
                    _, feat = self.model(img)
                feats.append(feat)
                pids.extend(pid.cpu().numpy())
                camids.extend(np.asarray(camid))

                batch = val_prefetcher.next()

            feats = torch.cat(feats, dim=0)
            if self.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:])

            # m, n = qf.shape[0], gf.shape[0]
            distmat = torch.mm(qf, gf.t()).cpu().numpy()
            # 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.numpy()
            cmc, mAP = evaluate(-distmat, q_pids, g_pids, q_camids, g_camids)
            self.logger.info(f"Test Results on {val_dataset_name} - Epoch: {self.current_epoch}")
            self.logger.info(f"mAP: {mAP:.1%}")
            for r in [1, 5, 10]:
                self.logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}")

            self.writer.add_scalar('rank1', cmc[0], self.global_step)
            self.writer.add_scalar('mAP', mAP, self.global_step)
            metric_dict.append({'rank1': cmc[0], 'mAP': mAP})
        # convert to train mode
        self.model.train()
        return metric_dict[0]
예제 #8
0
def inference(cfg, model, test_dataloader, num_query):
    logger = logging.getLogger("reid_baseline.inference")
    logger.info("Start inferencing")

    model.eval()

    feats, pids, camids = [], [], []
    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)
        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:])

    # cosine distance
    distmat = torch.mm(qf, gf.t()).cpu().numpy()

    # euclidean distance
    # 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.numpy()
    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%}")
예제 #9
0
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
예제 #10
0
def inference_aligned_flipped(cfg, model, test_dataloader, num_query,
                              use_local_feature, use_rerank,
                              use_cross_feature):
    logger = logging.getLogger("reid_baseline.inference")
    logger.info("Start inferencing aligned with flipping")

    model.eval()

    pids, camids = [], []
    gfs, bn_gfs, lfs, bn_lfs = [], [], [], []
    gfs_flipped, bn_gfs_flipped, lfs_flipped, bn_lfs_flipped = [], [], [], []

    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():
            ret = model(img)
            ret_flip = model(torch.flip(img, [3]))
            if len(ret) == 4:
                gf, bn_gf, lf, bn_lf = ret
                gff, bn_gff, lff, bn_lff = ret_flip
            elif len(ret) == 2:
                gf, bn_gf = ret
                gff, bn_gff = ret_flip
                lf, bn_lf = None, None
                lff, bn_lff = None, None
            elif ret is not tuple:
                gf = bn_gf = ret
                gff = bn_gff = ret_flip
                lf, bn_lf = None, None
                lff, bn_lff = None, None
            else:
                #print('ret', ret.size())
                raise Exception("Unknown model returns, length = ", len(ret))

        # 4 features
        gfs.append(gf.cpu())
        bn_gfs.append(bn_gf.cpu())

        if use_local_feature:
            lfs.append(lf.cpu())
            bn_lfs.append(bn_lf.cpu())

        # 4 features flipped
        gfs_flipped.append(gff.cpu())
        bn_gfs_flipped.append(bn_gff.cpu())

        if use_local_feature:
            lfs_flipped.append(lff.cpu())
            bn_lfs_flipped.append(bn_lff.cpu())

        pids.extend(pid.cpu().numpy())
        camids.extend(np.asarray(camid))

        batch = test_prefetcher.next()

    distmat1 = distmat2 = None
    logger.info(
        f"use_cross_feature = {use_cross_feature}, use_local_feature = {use_local_feature}, use_rerank = {use_rerank}"
    )
    if use_cross_feature:
        logger.info("Computing distmat with bn_gf (+ lf)")
        distmat2 = compute_distmat(cfg,
                                   num_query,
                                   bn_gfs,
                                   bn_gfs_flipped,
                                   lfs,
                                   lfs_flipped,
                                   theta=0.45,
                                   use_local_feature=use_local_feature,
                                   use_rerank=use_rerank)
        distmat = distmat2
        #distmat = (distmat1 + distmat2) / 2
    else:
        logger.info("Computing distmat with gf (+ bn_lf)")
        distmat1 = compute_distmat(cfg,
                                   num_query,
                                   gfs,
                                   gfs_flipped,
                                   bn_lfs,
                                   bn_lfs_flipped,
                                   theta=0.95,
                                   use_local_feature=use_local_feature,
                                   use_rerank=use_rerank)
        distmat = distmat1

    score = distmat
    index = np.argsort(score, axis=1)  # from small to large
    #index = mem_saving_argsort(score) # better for large matrix ?

    return distmat, index, distmat1, distmat2
예제 #11
0
def inference(
        cfg,
        model,
        test_dataloader_collection,
        num_query_collection,
        is_vis=False,
        test_collection=None,
        use_mask=True,
        num_parts=10,
        mask_image=False
):
    logger = logging.getLogger("reid_baseline.inference")
    logger.info("Start inferencing")

    model.eval()

    adj = torch.from_numpy(coarse_adj_npy).float()
    idx = -1
    for test_dataset_name, test_dataloader, num_query in zip(cfg.DATASETS.TEST_NAMES, test_dataloader_collection, num_query_collection):
        idx += 1
        feats, pids, camids = [], [], []
        if use_mask:
            test_prefetcher = data_prefetcher_mask(test_dataloader)
        else:
            test_prefetcher = data_prefetcher(test_dataloader)
        batch = test_prefetcher.next()
        while batch[0] is not None:
            if use_mask:
                img, mask, pid, camid = batch
                adj_batch = adj.repeat(img.size(0), 1, 1)
            
            with torch.no_grad():
                output = model(img, img, mask, adj_batch)
#                 feat = output[1]
#                 feat = output[3]
                feat = torch.cat([output[1], output[3]], dim=1)
                
            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:])

        # cosine distance
        distmat = torch.mm(qf, gf.t()).cpu().numpy()

        # euclidean distance
        # 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.numpy()
        cmc, mAP = evaluate(-distmat, q_pids, g_pids, q_camids, g_camids)
        logger.info(f"Results on {test_dataset_name} : ")
        logger.info(f"mAP: {mAP:.1%}")
        for r in [1, 5, 10]:
            logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}")
            
        if is_vis:
            query_rand = 10
            topK = 10
            is_save_all = True
            query_rand_idx = range(0, num_query) if is_save_all else random.sample(range(0, num_query), query_rand)
            print(f'|-------- Randomly saving top-{topK} results of {len(query_rand_idx)} queries for {test_dataset_name} --------|')
            
            qf_rand = qf[query_rand_idx]
            q_pids_rand = q_pids[query_rand_idx]
            q_camids_rand = q_camids[query_rand_idx]
            
            q_items = test_collection[idx][:num_query]
            q_items_rand = list()
            for i in query_rand_idx:
                q_items_rand.append(q_items[i])
            g_items = test_collection[idx][num_query:]
            
            distmat_rand = torch.mm(qf_rand, gf.t()).cpu().numpy()
            distmat_rand = -distmat_rand
            
            indices = np.argsort(distmat_rand, axis=1)
            matches = (g_pids[indices] == q_pids_rand[:, np.newaxis]).astype(np.int32)
            
            save_img_size = (256, 256)
            
            if test_dataset_name == 'market1501':
                save_img_size = (128, 256)
            
            for q_idx in range(len(query_rand_idx)):
                savefilename = ''
                # get query pid and camid
                q_path = q_items_rand[q_idx][0]
                q_pid = q_items_rand[q_idx][1]
                q_camid = q_items_rand[q_idx][2]
                
                savefilename += 'q-'+q_path.split('/')[-1]+'_g'

                # remove gallery samples that have the same pid and camid with query
                order = indices[q_idx]
                remove = (g_pids[order] == q_pid) & (g_camids[order] == q_camid)
                keep = np.invert(remove)

                print('Query Path : ', q_path)
                print('Result idx : ', order[:topK])
                
                img_list = list()
                q_img = cv2.imread(q_path)
                q_img = cv2.resize(q_img, save_img_size)
                cv2.rectangle(q_img, (0,0), save_img_size, (255,0,0), 4)
                img_list.append(q_img)
                
                for g_idx in order[:topK]:
                    g_img = cv2.imread(g_items[g_idx][0])
                    g_img = cv2.resize(g_img, save_img_size)
                    if q_pid == g_items[g_idx][1] and q_camid == g_items[g_idx][2]:
                        cv2.rectangle(g_img, (0,0), save_img_size, (255,255,0), 4)
                    elif q_pid == g_items[g_idx][1] and q_camid != g_items[g_idx][2]:
                        cv2.rectangle(g_img, (0,0), save_img_size, (0,255,0), 4)
                    else:
                        cv2.rectangle(g_img, (0,0), save_img_size, (0,0,255), 4)
                    img_list.append(g_img)
                    savefilename += '-'+str(g_items[g_idx][1])
                
                pic = np.concatenate(img_list, 1)
                picsavedir = os.path.join(cfg.OUTPUT_DIR, '-'.join(cfg.DATASETS.TEST_NAMES), 'examples', test_dataset_name)
                if not os.path.exists(picsavedir): os.makedirs(picsavedir)
                savefilepath = os.path.join(picsavedir, savefilename+'.jpg')
                cv2.imwrite(savefilepath, pic)
                print('Save example picture to ', savefilepath)
예제 #12
0
def update_bn_stats(model, data_loader, num_iters: int = 200):
    """
    Recompute and update the batch norm stats to make them more precise. During
    training both BN stats and the weight are changing after every iteration, so
    the running average can not precisely reflect the actual stats of the
    current model.
    In this function, the BN stats are recomputed with fixed weights, to make
    the running average more precise. Specifically, it computes the true average
    of per-batch mean/variance instead of the running average.
    Args:
        model (nn.Module): the model whose bn stats will be recomputed.
            Note that:
            1. This function will not alter the training mode of the given model.
               Users are responsible for setting the layers that needs
               precise-BN to training mode, prior to calling this function.
            2. Be careful if your models contain other stateful layers in
               addition to BN, i.e. layers whose state can change in forward
               iterations.  This function will alter their state. If you wish
               them unchanged, you need to either pass in a submodule without
               those layers, or backup the states.
        data_loader (iterator): an iterator. Produce data as inputs to the model.
        num_iters (int): number of iterations to compute the stats.
    """
    bn_layers = get_bn_modules(model)

    if len(bn_layers) == 0:
        return

    # In order to make the running stats only reflect the current batch, the
    # momentum is disabled.
    # bn.running_mean = (1 - momentum) * bn.running_mean + momentum * batch_mean
    # Setting the momentum to 1.0 to compute the stats without momentum.
    momentum_actual = [bn.momentum for bn in bn_layers]
    for bn in bn_layers:
        bn.momentum = 1.0

    # Note that running_var actually means "running average of variance"
    running_mean = [torch.zeros_like(bn.running_mean) for bn in bn_layers]
    running_var = [torch.zeros_like(bn.running_var) for bn in bn_layers]

    ind = 0
    num_epoch = num_iters // len(data_loader) + 1
    for _ in range(num_epoch):
        prefetcher = data_prefetcher(data_loader)
        batch = prefetcher.next()
        while batch[0] is not None:
            model(batch[0], batch[1])

            for i, bn in enumerate(bn_layers):
                # Accumulates the bn stats.
                running_mean[i] += (bn.running_mean - running_mean[i]) / (ind +
                                                                          1)
                running_var[i] += (bn.running_var - running_var[i]) / (ind + 1)
                # We compute the "average of variance" across iterations.

            if ind == (num_iters - 1):
                print(
                    f"update_bn_stats is running for {num_iters} iterations.")
                break

            ind += 1
            batch = prefetcher.next()

    for i, bn in enumerate(bn_layers):
        # Sets the precise bn stats.
        bn.running_mean = running_mean[i]
        bn.running_var = running_var[i]
        bn.momentum = momentum_actual[i]
예제 #13
0
def inference_flipped(
        cfg,
        model,
        test_dataloader,
        num_query,
        thetas,
        use_local_feature=True  # 是否使用local特征
):
    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])

            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")
    theta = 0.95
    scores, indices, dist_mats = [], [], []
    for theta2 in thetas:
        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_flip = 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=theta2,
                                     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
예제 #14
0
def inference_aligned_flipped(cfg, model, test_dataloader, num_query,
                              use_local_feature, use_rerank,
                              use_cross_feature):
    """
    inference an aligned net with flipping and two pairs of global feature and local feature
    :param cfg:
    :param model:
    :param test_dataloader:
    :param num_query:
    :return:
    """
    logger = logging.getLogger("reid_baseline.inference")
    logger.info("Start inferencing aligned with flipping")

    model.eval()

    pids, camids = [], []
    gfs, bn_gfs, lfs, bn_lfs = [], [], [], []
    gfs_flipped, bn_gfs_flipped, lfs_flipped, bn_lfs_flipped = [], [], [], []

    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():
            ret = model(img)
            ret_flip = model(torch.flip(img, [3]))
            if len(ret) == 4:
                gf, bn_gf, lf, bn_lf = ret
                gff, bn_gff, lff, bn_lff = ret_flip
            elif len(ret) == 2:
                gf, bn_gf = ret
                gff, bn_gff = ret_flip
                lf, bn_lf = None, None
                lff, bn_lff = None, None
            elif ret is not tuple:
                bn_gf = ret[:, :2048]
                gf = ret[:, 2048:]

                gff = ret_flip[:, :2048]
                bn_gff = ret_flip[:, 2048:]
                lf, bn_lf = None, None
                lff, bn_lff = None, None
            else:
                # print('ret', ret.size())
                raise Exception("Unknown model returns, length = ", len(ret))

        # 4 features
        gfs.append(gf.cpu())
        bn_gfs.append(bn_gf.cpu())

        if use_local_feature:
            if use_cross_feature:
                lfs.append(lf.cpu())
            else:
                bn_lfs.append(bn_lf.cpu())

        # 4 features flipped
        gfs_flipped.append(gff.cpu())
        bn_gfs_flipped.append(bn_gff.cpu())

        if use_local_feature:
            if use_cross_feature:
                lfs_flipped.append(lff.cpu())
            else:
                bn_lfs_flipped.append(bn_lff.cpu())

        pids.extend(pid.cpu().numpy())
        camids.extend(np.asarray(camid))

        batch = test_prefetcher.next()

    q_pids = np.asarray(pids[:num_query])
    q_camids = np.asarray(camids[:num_query])
    g_pids = np.asarray(pids[num_query:])
    g_camids = np.asarray(camids[num_query:])

    logger.info(
        f"use_local_feature = {use_local_feature}, use_rerank = {use_rerank}")

    logger.info("Computing distmat with bn_gf")
    distmat2 = compute_distmat(cfg,
                               num_query,
                               bn_gfs,
                               bn_gfs_flipped,
                               lfs,
                               lfs_flipped,
                               theta=0.45,
                               use_local_feature=use_local_feature,
                               use_rerank=use_rerank)

    logger.info("Computing distmat with gf + bn_lf")
    distmat1 = compute_distmat(cfg,
                               num_query,
                               gfs,
                               gfs_flipped,
                               bn_lfs,
                               bn_lfs_flipped,
                               theta=0.95,
                               use_local_feature=use_local_feature,
                               use_rerank=use_rerank)

    for theta in np.linspace(0, 1, 21):
        #theta = 0.55
        distmat = distmat1 * (1 - theta) + distmat2 * theta

        cmc, mAP = evaluate(distmat, q_pids, g_pids, q_camids, g_camids)
        logger.info(f"theta: {theta:.2%} 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%}")
예제 #15
0
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 = [], []
    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

    # 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 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%}")
예제 #16
0
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%}")
예제 #17
0
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%}")
예제 #18
0
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
예제 #19
0
def inference_aligned(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%}")
예제 #20
0
def estimate_distance(
    cfg,
    model,
    data_loader,
    sample_number=None
):

    model.eval()

    savedir = os.path.join(cfg.OUTPUT_DIR, '-'.join(cfg.DATASETS.TEST_NAMES), 'estimate_dist')
    if not os.path.exists(savedir): os.makedirs(savedir)
    if len(data_loader) > 10:
        print('Estimate distance on train data...')
        outfile = open(os.path.join(savedir, cfg.DATASETS.TEST_NAMES[0]+'_train.txt'), 'w')
        feats, pids, camids, pos_dists, mean_dists, neg_dists = [], [], [], [], [], []
        prefetcher = data_prefetcher(data_loader)
        batch = prefetcher.next()
        batchi = 0
        while batch[0] is not None:
            print(f'Extracting feature for batch {batchi}')
            img, pid, camid = batch
            with torch.no_grad():
                logit, feat = model(img)
            feats.append(feat)
            pids.extend(pid.cpu().numpy().tolist())
            camids.extend(np.asarray(camid))

            batch = prefetcher.next()
            batchi += 1
            
        feats = torch.cat(feats, dim=0)
        pids = np.asarray(pids)
        camids = np.asarray(camids)
            
        if cfg.TEST.NORM:
            feats = F.normalize(feats, p=2, dim=1)
        
        batchN = feats.shape[0]//cfg.TEST.IMS_PER_BATCH
        print('batchN : ', batchN+1)
        for batch_i in range(batchN+1):
            print(f'Processing batch : {batch_i}')
            if batch_i != batchN:
                feats_split = feats[batch_i*cfg.TEST.IMS_PER_BATCH:(batch_i+1)*cfg.TEST.IMS_PER_BATCH]
                pids_split = pids[batch_i*cfg.TEST.IMS_PER_BATCH:(batch_i+1)*cfg.TEST.IMS_PER_BATCH]
                camids_split = camids[batch_i*cfg.TEST.IMS_PER_BATCH:(batch_i+1)*cfg.TEST.IMS_PER_BATCH]
            else:
                feats_split = feats[batch_i*cfg.TEST.IMS_PER_BATCH:]
                pids_split = pids[batch_i*cfg.TEST.IMS_PER_BATCH:]
                camids_split = camids[batch_i*cfg.TEST.IMS_PER_BATCH:]

            # cosine distance
            distmat_split = torch.mm(feats_split, feats.t()).cpu().numpy()
            distmat_split = -distmat_split

            for sample_i in range(len(pids_split)):
                dist = -distmat_split[sample_i]
                pid = pids_split[sample_i]
                camid = camids_split[sample_i]

                # remove gallery samples that have the same pid and camid with query
                positive = (pids == pid) & (camids != camid)
                negtive = (pids != pid)
                if not np.any(positive):
                    # this condition is true when query identity does not appear in gallery
                    continue
                dist_pos = dist[positive]
                dist_neg = dist[negtive]
                pos_dists.append(np.max(dist_pos))
                neg_dists.append(np.max(dist_neg))
                mean_dists.append(np.mean(dist_pos))
        
        item = 0
        max_sample = 1000000
        if len(pids) > max_sample:
            sample_rand = random.sample(range(len(pids)), max_sample)
            for sample_i in sample_rand:
                outfile.write(f'Item {item:6d} : id = {pids[sample_i]:6d} , pos_dist = {pos_dists[sample_i]:.6f}, mean_dist = {mean_dists[sample_i]:.6f}, neg_dist = {neg_dists[sample_i]:.6f}\n')
                item += 1
        else:
            for a, b, c, d in zip(pids, pos_dists, mean_dists, neg_dists):
                outfile.write(f'Item {item:6d} : id = {a:6d} , pos_dist = {b:.6f} , mean_dist = {c:.6f}, neg_dist = {d:.6f}\n')
                item += 1

    else:
        idx = -1

        for test_dataset_name, dataloader, num_query in zip(cfg.DATASETS.TEST_NAMES, data_loader, sample_number):
            print(f'Estimate distance on test data of {test_dataset_name}')
            idx += 1
            outfile = open(os.path.join(savedir, test_dataset_name+'_test.txt'), 'w')
            feats, pids, camids, pos_dists, mean_dists, neg_dists = [], [], [], [], [], []
            prefetcher = data_prefetcher(dataloader)
            batch = prefetcher.next()
            batchi = 0
            while batch[0] is not None:
                print(f'Extracting feature for batch {batchi}')
                img, pid, camid = batch
                with torch.no_grad():
                    logit, feat = model(img)
                feats.append(feat)
                pids.extend(pid.cpu().numpy().tolist())
                camids.extend(np.asarray(camid))

                batch = prefetcher.next()
                batchi += 1

            feats = torch.cat(feats, dim=0)
            pids = np.asarray(pids)
            camids = np.asarray(camids)

            if 'veri' == test_dataset_name:
                feats = feats[1678:]
                pids = pids[1678:]
                camids = camids[1678:]

            if cfg.TEST.NORM:
                feats = F.normalize(feats, p=2, dim=1)

            batchN = feats.shape[0]//cfg.TEST.IMS_PER_BATCH
            print('batchN : ', batchN+1)
            for batch_i in range(batchN+1):
                print(f'Processing batch : {batch_i}')
                if batch_i != batchN:
                    feats_split = feats[batch_i*cfg.TEST.IMS_PER_BATCH:(batch_i+1)*cfg.TEST.IMS_PER_BATCH]
                    pids_split = pids[batch_i*cfg.TEST.IMS_PER_BATCH:(batch_i+1)*cfg.TEST.IMS_PER_BATCH]
                    camids_split = camids[batch_i*cfg.TEST.IMS_PER_BATCH:(batch_i+1)*cfg.TEST.IMS_PER_BATCH]
                else:
                    feats_split = feats[batch_i*cfg.TEST.IMS_PER_BATCH:]
                    pids_split = pids[batch_i*cfg.TEST.IMS_PER_BATCH:]
                    camids_split = camids[batch_i*cfg.TEST.IMS_PER_BATCH:]

                # cosine distance
                distmat_split = torch.mm(feats_split, feats.t()).cpu().numpy()
                distmat_split = -distmat_split

                for sample_i in range(len(pids_split)):
                    dist = -distmat_split[sample_i]
                    pid = pids_split[sample_i]
                    camid = camids_split[sample_i]

                    # remove gallery samples that have the same pid and camid with query
                    positive = (pids == pid) & (camids != camid)
                    negtive = (pids != pid)
                    if not np.any(positive):
                        # this condition is true when query identity does not appear in gallery
                        continue
                    dist_pos = dist[positive]
                    dist_neg = dist[negtive]
                    pos_dists.append(np.max(dist_pos))
                    neg_dists.append(np.max(dist_neg))
                    mean_dists.append(np.mean(dist_pos))

                   
            item = 0
            max_sample = 1000000
            if len(pids) > max_sample:
                sample_rand = random.sample(range(len(pids)), max_sample)
                for sample_i in sample_rand:
                    outfile.write(f'Item {item:6d} : id = {pids[sample_i]:6d} , pos_dist = {pos_dists[sample_i]:.6f}, mean_dist = {mean_dists[sample_i]:.6f}, neg_dist = {neg_dists[sample_i]:.6f}\n')
                    item += 1
            else:
                for a, b, c, d in zip(pids, pos_dists, mean_dists, neg_dists):
                    outfile.write(f'Item {item:6d} : id = {a:6d} , pos_dist = {b:.6f} , mean_dist = {c:.6f}, neg_dist = {d:.6f}\n')
                    item += 1
예제 #21
0
def inference_aligned_flipped(cfg, model, test_dataloader, num_query,
                              use_local_feature, use_rerank,
                              use_cross_feature):
    """
    inference an aligned net with flipping and two pairs of global feature and local feature
    :param cfg:
    :param model:
    :param test_dataloader:
    :param num_query:
    :return:
    """
    logger = logging.getLogger("reid_baseline.inference")
    logger.info("Start inferencing aligned with flipping")

    model.eval()

    pids, camids = [], []
    gfs, bn_gfs, lfs, bn_lfs = [], [], [], []
    gfs_flipped, bn_gfs_flipped, lfs_flipped, bn_lfs_flipped = [], [], [], []

    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():
            gf, bn_gf, lf, bn_lf = model(img)
            gff, bn_gff, lff, bn_lff = model(torch.flip(img, [3]))

        # 4 features
        gfs.append(gf.cpu())
        bn_gfs.append(bn_gf.cpu())

        if use_local_feature:
            lfs.append(lf.cpu())
            bn_lfs.append(bn_lf.cpu())

        # 4 features flipped
        gfs_flipped.append(gff.cpu())
        bn_gfs_flipped.append(bn_gff.cpu())

        if use_local_feature:
            lfs_flipped.append(lff.cpu())
            bn_lfs_flipped.append(bn_lff.cpu())

        pids.extend(pid.cpu().numpy())
        camids.extend(np.asarray(camid))

        batch = test_prefetcher.next()

    q_pids = np.asarray(pids[:num_query])
    q_camids = np.asarray(camids[:num_query])
    g_pids = np.asarray(pids[num_query:])
    g_camids = np.asarray(camids[num_query:])

    logger.info(
        f"use_cross_feature = {use_cross_feature}, use_local_feature = {use_local_feature}, use_rerank = {use_rerank}"
    )

    if use_cross_feature:
        logger.info("Computing distmat with bn_gf (+ lf)")
        distmat2 = compute_distmat(cfg,
                                   num_query,
                                   bn_gfs,
                                   bn_gfs_flipped,
                                   lfs,
                                   lfs_flipped,
                                   theta=0.45,
                                   use_local_feature=use_local_feature,
                                   use_rerank=use_rerank)
        distmat = distmat2
        #distmat = (distmat1 + distmat2) / 2
    else:
        logger.info("Computing distmat with gf + bn_lf")
        distmat1 = compute_distmat(cfg,
                                   num_query,
                                   gfs,
                                   gfs_flipped,
                                   bn_lfs,
                                   bn_lfs_flipped,
                                   theta=0.95,
                                   use_local_feature=use_local_feature,
                                   use_rerank=use_rerank)
        distmat = distmat1
        #distmat1 = None
        #distmat2 = None

    #distmat = original_distmat
    #distmat[:, new_gallery_index] = distmat1 - 100

    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%}")
예제 #22
0
def estimate_logits(
    cfg, 
    model, 
    data_loader,
    sample_number=None
):

    model.eval()
    savedir = os.path.join(cfg.OUTPUT_DIR, '-'.join(cfg.DATASETS.TEST_NAMES), 'estimate_logits')
    if not os.path.exists(savedir): os.makedirs(savedir)

    if len(data_loader) > 10:
        print('Estimate logits on train data...')
        outfile = open(os.path.join(savedir, cfg.DATASETS.TEST_NAMES[0]+'_train.txt'), 'w')
        logits, feats, pids, camids, probs, max_probs, pred_ids = [], [], [], [], [], [], []
        prefetcher = data_prefetcher(data_loader)
        batch = prefetcher.next()
        while batch[0] is not None:
            img, pid, camid = batch
            with torch.no_grad():
                logit, feat = model(img)

            # logits.append(logit)
            prob = F.softmax(logit, dim=1)
            # probs.append(prob)
            max_prob, pred_id = torch.max(prob, dim=1)

            pred_ids.extend(pred_id.cpu().numpy().tolist())
            max_probs.extend(max_prob.cpu().numpy().tolist())
            pids.extend(pid.cpu().numpy().tolist())
            # camids.extend(np.asarray(camid))

            batch = prefetcher.next()
            
        item = 0
        max_sample = 1000000
        if len(pids) > max_sample:
            sample_rand = random.sample(range(len(pids)), max_sample)
            for sample_i in sample_rand:
                outfile.write(f'Item {item:6d} : id = {pids[sample_i]:6d} , pred = {pred_ids[sample_i]:6d} , prob = {max_probs[sample_i]:.4f}\n')
                item += 1
        else:
            for a, b, c in zip(pids, pred_ids, max_probs):
                # print(f'Item {item:6d} : id = {a:4d} , pred = {b:4d} , prob = {c:.4f}')
                outfile.write(f'Item {item:6d} : id = {a:6d} , pred = {b:6d} , prob = {c:.4f}\n')
                item += 1
    
    else:
        idx = -1

        for test_dataset_name, dataloader, num_query in zip(cfg.DATASETS.TEST_NAMES, data_loader, sample_number):
            print(f'Estimate logits on test data of {test_dataset_name}')
            idx += 1
            outfile = open(os.path.join(savedir, test_dataset_name+'_test.txt'), 'w')
            logits, feats, pids, camids, probs, max_probs, pred_ids = [], [], [], [], [], [], []
            prefetcher = data_prefetcher(dataloader)
            batch = prefetcher.next()
            while batch[0] is not None:
                img, pid, camid = batch
                with torch.no_grad():
                    logit, feat = model(img)

                # logits.append(logit)
                prob = F.softmax(logit, dim=1)
                # probs.append(prob)
                max_prob, pred_id = torch.max(prob, dim=1)
                
                pred_ids.extend(pred_id.cpu().numpy().tolist())
                max_probs.extend(max_prob.cpu().numpy().tolist())
                pids.extend(pid.cpu().numpy().tolist())
                # camids.extend(np.asarray(camid))

                batch = prefetcher.next()

            if 'veri' == test_dataset_name:
                pred_ids = pred_ids[1678:]
                pids = pids[1678:]
                max_probs = max_probs[1678:]

            item = 0            
            max_sample = 1000000
            if len(pids) > max_sample:
                sample_rand = random.sample(range(len(pids)), max_sample)
                for sample_i in sample_rand:
                    outfile.write(f'Item {item:6d} : id = {pids[sample_i]:6d} , pred = {pred_ids[sample_i]:6d} , prob = {max_probs[sample_i]:.4f}\n')
                    item += 1
            else:
                for a, b, c in zip(pids, pred_ids, max_probs):
                    # print(f'Item {item:6d} : id = {a:4d} , pred = {b:4d} , prob = {c:.4f}')
                    outfile.write(f'Item {item:6d} : id = {a:6d} , pred = {b:6d} , prob = {c:.4f}\n')
                    item += 1
예제 #23
0
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%}")
예제 #24
0
def inference(cfg, model, train_dataloader, test_dataloader, num_query):
    logger = logging.getLogger("reid_baseline.inference")
    logger.info("Start inferencing")

    logger.info("compute precise batchnorm ...")
    # model.train()
    # update_bn_stats(model, train_dataloader, num_iters=300)
    model.eval()

    cat_feats, feats, pids, camids = [], [], [], []
    test_prefetcher = data_prefetcher(test_dataloader)
    batch = test_prefetcher.next()
    while batch[0] is not None:
        img, pid, camid = batch
        cat_feat, feat = model(img)
        cat_feats.append(cat_feat.cpu())
        feats.append(feat.cpu())
        pids.extend(np.asarray(pid.cpu().numpy()))
        camids.extend(np.asarray(camid))

        batch = test_prefetcher.next()

    feats = torch.cat(feats, dim=0)
    cat_feats = torch.cat(cat_feats, dim=0)
    if cfg.TEST.NORM:
        feats = F.normalize(feats, p=2, dim=1)
        cat_feats = F.normalize(cat_feats, p=2, dim=1)
    # query
    cat_qf = cat_feats[:num_query]
    qf = feats[:num_query]
    q_pids = np.asarray(pids[:num_query])
    q_camids = np.asarray(camids[:num_query])
    # gallery
    cat_gf = cat_feats[num_query:]
    gf = feats[num_query:]
    g_pids = np.asarray(pids[num_query:])
    g_camids = np.asarray(camids[num_query:])

    # cosine distance
    cat_dist = torch.mm(cat_qf, cat_gf.t())
    distmat = torch.mm(qf, gf.t())

    # IIA post fusion strategy for all query and gallery
    # qf = qf
    # gf = gf
    # m = qf.shape[0]
    # n = gf.shape[0]
    # distmat = torch.zeros((m, n)).to(qf)
    # for i, q_f in enumerate(qf):
    #     print(i)
    #     D = torch.cat([q_f[None, :], gf], dim=0) # [1+g, 2048]
    #     S = torch.mm(D, D.t())  # [1+g, 1+g]
    #     for _ in range(5):
    #         S = S - torch.eye(S.shape[0]).to(S)
    #         s_v, s_i = torch.topk(S, 10, dim=1)
    #         s_v = F.softmax(s_v, dim=1)
    #         s = torch.zeros((S.size()[0], S.size()[0])).to(qf)  # [1+g, 1+g]
    #         for j in range(s_i.shape[0]):
    #             s[j, s_i[j]] = s_v[j]
    #         u = 0.8 * torch.eye(S.size()[0]).to(s) + 0.2 * s
    #         D = torch.mm(u, D)
    #         S = torch.mm(D, D.t())
    #     distmat[i] = S[0][1:]

    cmc, mAP = evaluate(1 - distmat.numpy(), 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%}")

    cmc, mAP = evaluate(1 - cat_dist.numpy(), q_pids, g_pids, q_camids,
                        g_camids)
    logger.info('cat feature')
    logger.info(f"mAP: {mAP:.1%}")
    for r in [1, 5, 10]:
        logger.info(f"CMC curve, Rank-{r:<3}:{cmc[r - 1]:.1%}")