Exemple #1
0
def _compute_whitening(whitening, net, image_size, transform, ms, msp):
    # compute whitening
    start = time.time()

    print('>> {}: Learning whitening...'.format(whitening))

    # loading db
    db_root = os.path.join(get_data_root(), 'train', whitening)
    ims_root = os.path.join(db_root, 'ims')
    db_fn = os.path.join(db_root, '{}-whiten.pkl'.format(whitening))
    with open(db_fn, 'rb') as f:
        db = pickle.load(f)
    images = [
        cid2filename(db['cids'][i], ims_root) for i in range(len(db['cids']))
    ]

    # extract whitening vectors
    print('>> {}: Extracting...'.format(whitening))
    wvecs = extract_vectors(net, images, image_size, transform, ms=ms, msp=msp)

    # learning whitening
    print('>> {}: Learning...'.format(whitening))
    wvecs = wvecs.numpy()
    m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
    Lw = {'m': m, 'P': P}

    elapsed = time.time() - start
    print('>> {}: elapsed time: {}'.format(whitening, htime(elapsed)))

    return Lw, elapsed
def main(unused_argv):
  tf.logging.set_verbosity(tf.logging.INFO)

  start = time.time()

  # Read features.
  locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(
      cmd_args.features_1_path)
  num_features_1 = locations_1.shape[0]
  tf.logging.info("Loaded image 1's %d features" % num_features_1)
  locations_2, _, descriptors_2, _, _ = feature_io.ReadFromFile(
      cmd_args.features_2_path)
  num_features_2 = locations_2.shape[0]
  tf.logging.info("Loaded image 2's %d features" % num_features_2)

  # Find nearest-neighbor matches using a KD tree.
  d1_tree = spatial.cKDTree(descriptors_1)
  _, indices = d1_tree.query(
      descriptors_2, distance_upper_bound=_DISTANCE_THRESHOLD)

  print('>> feature match elapsed time: {}'.format(htime(time.time() - start)))

  # Select feature locations for putative matches.
  locations_2_to_use = np.array([
      locations_2[i,]
      for i in range(num_features_2)
      if indices[i] != num_features_1
  ])
  locations_1_to_use = np.array([
      locations_1[indices[i],]
      for i in range(num_features_2)
      if indices[i] != num_features_1
  ])

  # Perform geometric verification using RANSAC.
  _, inliers = measure.ransac((locations_1_to_use, locations_2_to_use),
                              transform.AffineTransform,
                              min_samples=3,
                              residual_threshold=20,
                              max_trials=1000)

  tf.logging.info('Found %d inliers' % sum(inliers))

  # Visualize correspondences, and save to file.
  _, ax = plt.subplots()
  img_1 = mpimg.imread(cmd_args.image_1_path)
  img_2 = mpimg.imread(cmd_args.image_2_path)
  inlier_idxs = np.nonzero(inliers)[0]
  feature.plot_matches(
      ax,
      img_1,
      img_2,
      locations_1_to_use,
      locations_2_to_use,
      np.column_stack((inlier_idxs, inlier_idxs)),
      matches_color='b')
  ax.axis('off')
  ax.set_title('DELF correspondences')
  plt.savefig(cmd_args.output_image)
Exemple #3
0
def test(datasets, net):
    print(">> Evaluating network on test datasets...")
    image_size = 1024

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()
    # set up the transform
    normalize = transforms.Normalize(mean=net.meta["mean"],
                                     std=net.meta["std"])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    # Lw = None
    Lw = net.meta["Lw"]["retrieval-SfM-120k"]["ss"]

    # evaluate on test datasets
    # datasets = args.test_datasets.split(",")
    for dataset in datasets:
        start = time.time()

        print(">> {}: Extracting...".format(dataset))

        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join(get_data_root(), "test"))
        images = [cfg["im_fname"](cfg, i) for i in range(cfg["n"])]
        qimages = [cfg["qim_fname"](cfg, i) for i in range(cfg["nq"])]
        bbxs = [tuple(cfg["gnd"][i]["bbx"]) for i in range(cfg["nq"])]

        # extract database and query vectors
        print(">> {}: database images...".format(dataset))
        vecs = extract_vectors(net, images, image_size, transform)
        print(">> {}: query images...".format(dataset))
        qvecs = extract_vectors(net, qimages, image_size, transform, bbxs)

        print(">> {}: Evaluating...".format(dataset))

        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()

        # search, rank, and print
        scores = np.dot(vecs.T, qvecs)
        ranks = np.argsort(-scores, axis=0)
        compute_map_and_print(dataset, ranks, cfg["gnd"])

        if Lw is not None:
            # whiten the vectors
            vecs_lw = whitenapply(vecs, Lw["m"], Lw["P"])
            qvecs_lw = whitenapply(qvecs, Lw["m"], Lw["P"])

            # search, rank, and print
            scores = np.dot(vecs_lw.T, qvecs_lw)
            ranks = np.argsort(-scores, axis=0)
            compute_map_and_print(dataset + " + whiten", ranks, cfg["gnd"])

        print(">> {}: elapsed time: {}".format(dataset,
                                               htime(time.time() - start)))
def validate(val_loader, model, criterion, epoch):
    batch_time = AverageMeter()
    losses = AverageMeter()

    # create tuples for validation
    t_start = time.time()
    avg_neg_distance = val_loader.dataset.create_epoch_tuples(model)
    print("Mining time: {}".format(htime(time.time() - t_start)))

    # switch to evaluate mode
    model.eval()

    end = time.time()
    for i, (input, target) in enumerate(val_loader):

        nq = len(input)  # number of training tuples
        ni = len(input[0])  # number of images per tuple
        output = torch.zeros(model.meta['outputdim'], nq * ni).cuda()

        for q in range(nq):
            for imi in range(ni):

                # compute output vector for image imi of query q
                output[:, q * ni + imi] = model(input[q][imi].cuda()).squeeze()

        # no need to reduce memory consumption (no backward pass):
        # compute loss for the full batch
        loss = criterion(output, torch.cat(target).cuda())

        # record loss
        losses.update(loss.item() / nq, nq)

        # measure elapsed time
        batch_time.update(time.time() - end)
        end = time.time()

        if (i + 1) % args.print_freq == 0 or i == 0 or (i +
                                                        1) == len(val_loader):
            print('>> Val: [{0}][{1}/{2}]\t'
                  'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
                  'Loss {loss.val:.4f} ({loss.avg:.4f})'.format(
                      epoch + 1,
                      i + 1,
                      len(val_loader),
                      batch_time=batch_time,
                      loss=losses))

    return losses.avg
def train(train_loader, model, criterion, optimizer, epoch):
    batch_time = AverageMeter()
    data_time = AverageMeter()
    losses = AverageMeter()

    # create tuples for training
    t_start = time.time()
    avg_neg_distance = train_loader.dataset.create_epoch_tuples(model)
    print("Mining time: {}".format(htime(time.time() - t_start)))

    # switch to train mode
    model.train()
    model.apply(set_batchnorm_eval)

    end = time.time()
    for i, (input, target) in enumerate(train_loader):
        # measure data loading time
        data_time.update(time.time() - end)

        # zero out gradients so we can accumulate new ones over batches
        optimizer.zero_grad()

        nq = len(input)  # number of training tuples
        ni = len(input[0])  # number of images per tuple

        for q in range(nq):
            output = torch.zeros(model.meta['outputdim'], ni).cuda()
            for imi in range(ni):

                # compute output vector for image imi
                output[:, imi] = model(input[q][imi].cuda()).squeeze()

            # reducing memory consumption:
            # compute loss for this query tuple only
            # then, do backward pass for one tuple only
            # each backward pass gradients will be accumulated
            # the optimization step is performed for the full batch later
            loss = criterion(output, target[q].cuda())
            losses.update(loss.item())
            loss.backward()

        # do one step for multiple batches
        # accumulated gradients are used
        optimizer.step()

        # measure elapsed time
        batch_time.update(time.time() - end)
        end = time.time()

        if (i + 1) % args.print_freq == 0 or i == 0 or (
                i + 1) == len(train_loader):
            print('>> Train: [{0}][{1}/{2}]\t'
                  'Time {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
                  'Data {data_time.val:.3f} ({data_time.avg:.3f})\t'
                  'Loss {loss.val:.4f} ({loss.avg:.4f})'.format(
                      epoch + 1,
                      i + 1,
                      len(train_loader),
                      batch_time=batch_time,
                      data_time=data_time,
                      loss=losses),
                  flush=True)

    return losses.avg
Exemple #6
0
def main():
    args = parser.parse_args()

    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id
    using_cdvs = float(args.using_cdvs)
    # loading network from path
    if args.network_path is not None:

        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        if args.network_path in PRETRAINED:
            # pretrained networks (downloaded automatically)
            state = load_url(PRETRAINED[args.network_path], model_dir=os.path.join(get_data_root(), 'networks'))
        else:
            # fine-tuned network from path
            state = torch.load(args.network_path)

        # parsing net params from meta
        # architecture, pooling, mean, std required
        # the rest has default values, in case that is doesnt exist
        net_params = {}
        net_params['architecture'] = state['meta']['architecture']
        net_params['pooling'] = state['meta']['pooling']
        net_params['local_whitening'] = state['meta'].get('local_whitening', False)
        net_params['regional'] = state['meta'].get('regional', False)
        net_params['whitening'] = state['meta'].get('whitening', False)
        net_params['mean'] = state['meta']['mean']
        net_params['std'] = state['meta']['std']
        net_params['pretrained'] = False

        # load network
        net = init_network(net_params)
        net.load_state_dict(state['state_dict'])

        # if whitening is precomputed
        if 'Lw' in state['meta']:
            net.meta['Lw'] = state['meta']['Lw']

        print(">>>> loaded network: ")
        print(net.meta_repr())

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:

        # parse off-the-shelf parameters
        offtheshelf = args.network_offtheshelf.split('-')
        net_params = {}
        net_params['architecture'] = offtheshelf[0]
        net_params['pooling'] = offtheshelf[1]
        net_params['local_whitening'] = 'lwhiten' in offtheshelf[2:]
        net_params['regional'] = 'reg' in offtheshelf[2:]
        net_params['whitening'] = 'whiten' in offtheshelf[2:]
        net_params['pretrained'] = True

        # load off-the-shelf network
        print(">> Loading off-the-shelf network:\n>>>> '{}'".format(args.network_offtheshelf))
        net = init_network(net_params)
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = list(eval(args.multiscale))
    if len(ms) > 1 and net.meta['pooling'] == 'gem' and not net.meta['regional'] and not net.meta['whitening']:
        msp = net.pool.p.item()
        print(">> Set-up multiscale:")
        print(">>>> ms: {}".format(ms))
        print(">>>> msp: {}".format(msp))
    else:
        msp = 1

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()

    # set up the transform
    normalize = transforms.Normalize(
        mean=net.meta['mean'],
        std=net.meta['std']
    )
    transform = transforms.Compose([
        transforms.ToTensor(),
        normalize
    ])

    # compute whitening
    if args.whitening is not None:
        start = time.time()

        if 'Lw' in net.meta and args.whitening in net.meta['Lw']:

            print('>> {}: Whitening is precomputed, loading it...'.format(args.whitening))

            if len(ms) > 1:
                Lw = net.meta['Lw'][args.whitening]['ms']
            else:
                Lw = net.meta['Lw'][args.whitening]['ss']

        else:

            # if we evaluate networks from path we should save/load whitening
            # not to compute it every time
            if args.network_path is not None:
                whiten_fn = args.network_path + '_{}_whiten'.format(args.whitening)
                if len(ms) > 1:
                    whiten_fn += '_ms'
                whiten_fn += '.pth'
            else:
                whiten_fn = None

            if whiten_fn is not None and os.path.isfile(whiten_fn):
                print('>> {}: Whitening is precomputed, loading it...'.format(args.whitening))
                Lw = torch.load(whiten_fn)

            else:
                print('>> {}: Learning whitening...'.format(args.whitening))

                # loading db
                db_root = os.path.join(get_data_root(), 'train', args.whitening)
                ims_root = os.path.join(db_root, 'ims')
                db_fn = os.path.join(db_root, '{}-whiten.pkl'.format(args.whitening))
                with open(db_fn, 'rb') as f:
                    db = pickle.load(f)
                images = [cid2filename(db['cids'][i], ims_root) for i in range(len(db['cids']))]

                # extract whitening vectors
                print('>> {}: Extracting...'.format(args.whitening))
                wvecs = extract_vectors(net, images, args.image_size, transform, ms=ms, msp=msp)

                # learning whitening
                print('>> {}: Learning...'.format(args.whitening))
                wvecs = wvecs.numpy()
                m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
                Lw = {'m': m, 'P': P}

                # saving whitening if whiten_fn exists
                if whiten_fn is not None:
                    print('>> {}: Saving to {}...'.format(args.whitening, whiten_fn))
                    torch.save(Lw, whiten_fn)

        print('>> {}: elapsed time: {}'.format(args.whitening, htime(time.time() - start)))

    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.datasets.split(',')
    result_dir=args.network_path[0:-8]
    epoch_lun=args.network_path[0:-8].split('/')[-1].replace('model_epoch','')
    print(">> Creating directory if it does not exist:\n>> '{}'".format(result_dir))
    if not os.path.exists(result_dir):
        os.makedirs(result_dir)
    for dataset in datasets:
        start = time.time()
        # search, rank, and print
        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
        tuple_bbxs_qimlist=None
        tuple_bbxs_imlist=None
        images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
        qimages = [cfg['qim_fname'](cfg, i) for i in range(cfg['nq'])]
        # extract database and query vectors

        print('>> {}: query images...'.format(dataset))
        qvecs = extract_vectors(net, qimages, args.image_size, transform, bbxs=tuple_bbxs_qimlist, ms=ms, msp=msp, batchsize=1)
        qvecs = qvecs.numpy()
        qvecs = qvecs.astype(np.float32)
        np.save(os.path.join(result_dir, "{}_qvecs_ep{}_resize.npy".format(dataset,epoch_lun)), qvecs)
        print('>> {}: database images...'.format(dataset))
        vecs = extract_vectors(net, images, args.image_size, transform, ms=ms, bbxs=tuple_bbxs_imlist, msp=msp, batchsize=1)
        vecs = vecs.numpy()
        vecs = vecs.astype(np.float32)
        np.save(os.path.join(result_dir, "{}_vecs_ep{}_resize.npy".format(dataset,epoch_lun)), vecs)
        scores = np.dot(vecs.T, qvecs)
        if using_cdvs!=0:
            print('>> {}: cdvs global descriptor loading...'.format(dataset))
            qvecs_global = cfg['qimlist_global']
            vecs_global = cfg['imlist_global']
            scores_global = np.dot(vecs_global, qvecs_global.T)
            scores+=scores_global*using_cdvs
        ranks = np.argsort(-scores, axis=0)
        if args.ir_remove!='0':
            rank_len=10
            rank_re = np.loadtxt(os.path.join(result_dir, '{}_ranks_new_relevent.txt'.format(dataset)))
            ## the max value of rank_len
            MAX_RANK_LEN = int((rank_re.shape[0]) ** 0.5)
            rank_re=rank_re.reshape(MAX_RANK_LEN,MAX_RANK_LEN,rank_re.shape[1])
            for m in range(rank_re.shape[2]):
                for i in range(rank_re.shape[0]):
                    rank_re[i][i][m]=1.0
            quanzhong=[1,0.7,0.4]+[0.1]*(MAX_RANK_LEN-3)
            for m in range(rank_re.shape[2]):
                #if adaption, then change the rank_len to a adaption params according to the rank_re_q, q_aer, cons_n
                if args.ir_adaption:
                    using_local_query=True
                    cons_n = 5
                    q_aer = float(args.ir_adaption)
                    if using_local_query:
                        ## using local feature scores, please don't forget note the query_q belong to deep
                        rank_re_q = np.loadtxt(os.path.join(result_dir, '{}_ranks_new_query.txt'.format(dataset)))
                        query_q = rank_re_q[:, m]
                    else:
                        ## using deep feature scores
                        query_q = scores[ranks[:, m], m]

                    rank_len=0
                    jishu=0
                    for idx in range(min(len(query_q),MAX_RANK_LEN)-cons_n):
                        if jishu<cons_n:
                            if query_q[idx]>q_aer:
                                rank_len=idx+1
                            else:
                                jishu+=1
                        else:
                            break
                max_dim = min(rank_len, MAX_RANK_LEN)
                print (max_dim)
                if max_dim>2:
                    #put the image to the MAX_RANK_LEN2 location if equals max_dim then re rank in the maxdim length
                    list2 = []
                    list_hou = []
                    MAX_RANK_LEN2 = max_dim
                    for i in range(MAX_RANK_LEN2):
                        if i < max_dim:
                            fenshu = 0
                            for j in range(max_dim):
                                fenshu+=rank_re[min(i,j)][max(i,j)][m]*quanzhong[j]
                            fenshu = fenshu / (max_dim - 1)
                            if fenshu > float(args.ir_remove):
                                list2.append(ranks[i][m])
                            else:
                                list_hou.append(ranks[i][m])
                        else:
                            list2.append(ranks[i][m])
                    ranks[0:MAX_RANK_LEN2, m] = list2 + list_hou
        np.savetxt(os.path.join(result_dir, "{}_ranks.txt".format(dataset)), ranks.astype(np.int))
        if dataset == 'cdvs_test_retrieval':
            compute_map_and_print(dataset, ranks, cfg['gnd_id'])
        else:
            compute_map_and_print(dataset, ranks, cfg['gnd'])
                    # extract whitening vectors
                    print('>> {}: Extracting...'.format(whitening))
                    # wvecs = vecs
                    wvecs = np.hstack((vecs, qvecs))
                    # learning whitening
                    print('>> {}: Learning...'.format(whitening))
                    m, P = pcawhitenlearn(wvecs)
                    # m, P = whitenlearn(wvecs)
                    Lw = {'m': m, 'P': P}
                    # saving whitening if whiten_fn exists
                    if whiten_fn is not None:
                        print('>> {}: Saving to {}...'.format(
                            whitening, whiten_fn))
                        # torch.save(Lw, whiten_fn)
            print('>> {}: elapsed time: {}'.format(whitening,
                                                   htime(time.time() - start)))
        else:
            Lw = None

        if Lw is not None:
            for dim in param['pac_dims']:
                print('>>>> pac_dim: {}'.format(dim))
                # whiten the vectors
                vecs_lw = whitenapply(vecs, Lw['m'], Lw['P'], dim)
                qvecs_lw = whitenapply(qvecs, Lw['m'], Lw['P'], dim)

                # search, rank, and print
                scores = np.dot(vecs_lw.T, qvecs_lw)
                ranks_lw = np.argsort(-scores, axis=0)
                qvecs_lw_orig = qvecs_lw
                ranks_lw_orig = ranks_lw
Exemple #8
0
def main():
    args = parser.parse_args()

    # check if there are unknown datasets
    for dataset in args.datasets.split(','):
        if dataset not in datasets_names:
            raise ValueError(
                'Unsupported or unknown dataset: {}!'.format(dataset))

    # check if test dataset are downloaded
    # and download if they are not
    #download_train(get_data_root())
    download_test(get_data_root())

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path
    if args.network_path is not None:

        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        if args.network_path in PRETRAINED:
            # pretrained networks (downloaded automatically)
            state = load_url(PRETRAINED[args.network_path],
                             model_dir=os.path.join(get_data_root(),
                                                    'networks'))
        else:
            # fine-tuned network from path
            state = torch.load(args.network_path)

        # parsing net params from meta
        # architecture, pooling, mean, std required
        # the rest has default values, in case that is doesnt exist
        net_params = {}
        net_params['architecture'] = state['meta']['architecture']
        net_params['pooling'] = state['meta']['pooling']
        net_params['local_whitening'] = state['meta'].get(
            'local_whitening', False)
        net_params['regional'] = state['meta'].get('regional', False)
        net_params['whitening'] = state['meta'].get('whitening', False)
        net_params['mean'] = state['meta']['mean']
        net_params['std'] = state['meta']['std']
        net_params['pretrained'] = False

        # load network
        net = init_network(net_params)
        net.load_state_dict(state['state_dict'])

        # if whitening is precomputed
        if 'Lw' in state['meta']:
            net.meta['Lw'] = state['meta']['Lw']

        print(">>>> loaded network: ")
        print(net.meta_repr())

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:

        # parse off-the-shelf parameters
        offtheshelf = args.network_offtheshelf.split('-')
        net_params = {}
        net_params['architecture'] = offtheshelf[0]
        net_params['pooling'] = offtheshelf[1]
        net_params['local_whitening'] = 'lwhiten' in offtheshelf[2:]
        net_params['regional'] = 'reg' in offtheshelf[2:]
        net_params['whitening'] = 'whiten' in offtheshelf[2:]
        net_params['pretrained'] = True

        # load off-the-shelf network
        print(">> Loading off-the-shelf network:\n>>>> '{}'".format(
            args.network_offtheshelf))
        net = init_network(net_params)
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = list(eval(args.multiscale))
    if len(ms) > 1 and net.meta['pooling'] == 'gem' and not net.meta[
            'regional'] and not net.meta['whitening']:
        msp = net.pool.p.item()
        print(">> Set-up multiscale:")
        print(">>>> ms: {}".format(ms))
        print(">>>> msp: {}".format(msp))
    else:
        msp = 1

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()

    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    if args.whitening is not None:
        start = time.time()

        if 'Lw' in net.meta and args.whitening in net.meta['Lw']:

            print('>> {}: Whitening is precomputed, loading it...'.format(
                args.whitening))

            if len(ms) > 1:
                Lw = net.meta['Lw'][args.whitening]['ms']
            else:
                Lw = net.meta['Lw'][args.whitening]['ss']

        else:

            # if we evaluate networks from path we should save/load whitening
            # not to compute it every time
            if args.network_path is not None:
                whiten_fn = args.network_path + '_{}_whiten'.format(
                    args.whitening)
                if len(ms) > 1:
                    whiten_fn += '_ms'
                whiten_fn += '.pth'
            else:
                whiten_fn = None

            if whiten_fn is not None and os.path.isfile(whiten_fn):
                print('>> {}: Whitening is precomputed, loading it...'.format(
                    args.whitening))
                Lw = torch.load(whiten_fn)

            else:
                print('>> {}: Learning whitening...'.format(args.whitening))

                # loading db
                db_root = os.path.join(get_data_root(), 'train',
                                       args.whitening)
                ims_root = os.path.join(db_root, 'ims')
                db_fn = os.path.join(db_root,
                                     '{}-whiten.pkl'.format(args.whitening))
                with open(db_fn, 'rb') as f:
                    db = pickle.load(f)
                images = [
                    cid2filename(db['cids'][i], ims_root)
                    for i in range(len(db['cids']))
                ]

                # extract whitening vectors
                print('>> {}: Extracting...'.format(args.whitening))
                wvecs = extract_vectors(net,
                                        images,
                                        args.image_size,
                                        transform,
                                        ms=ms,
                                        msp=msp)

                # learning whitening
                print('>> {}: Learning...'.format(args.whitening))
                wvecs = wvecs.numpy()
                m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
                Lw = {'m': m, 'P': P}

                # saving whitening if whiten_fn exists
                if whiten_fn is not None:
                    print('>> {}: Saving to {}...'.format(
                        args.whitening, whiten_fn))
                    torch.save(Lw, whiten_fn)

        print('>> {}: elapsed time: {}'.format(args.whitening,
                                               htime(time.time() - start)))

    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.datasets.split(',')
    for dataset in datasets:
        start = time.time()
        """
        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
        images = [cfg['im_fname'](cfg,i) for i in range(cfg['n'])]
        qimages = [cfg['qim_fname'](cfg,i) for i in range(cfg['nq'])]
        try:
            bbxs = [tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])]
        except:
            bbxs = None  # for holidaysmanrot and copydays

        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        vecs = extract_vectors(net, images, args.image_size, transform, ms=ms, msp=msp)
        print('>> {}: query images...'.format(dataset))
        qvecs = extract_vectors(net, qimages, args.image_size, transform, bbxs=bbxs, ms=ms, msp=msp)
        
        print('>> {}: Evaluating...'.format(dataset))

        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()

        print (vecs.shape)
        print (qvecs.shape)

        # search, rank, and print
        scores = np.dot(vecs.T, qvecs)
        print (scores.shape)

        # to save scores (single query)
        # oxford
        #f = 'oxf_single.npy'
        # paris
        #f = 'par_single.npy'
        # roxford
        #f = 'roxf_single.npy'
        # rparis
        f = 'rpar_single.npy'

        ranks = np.argsort(-scores, axis=0)
        compute_map_and_print(dataset, ranks, cfg['gnd'])
    
        if Lw is not None:
            # whiten the vectors
            vecs_lw  = whitenapply(vecs, Lw['m'], Lw['P'])
            qvecs_lw = whitenapply(qvecs, Lw['m'], Lw['P'])

            # search, rank, and print
            scores = np.dot(vecs_lw.T, qvecs_lw)
            # save
            np.save(f, scores)

            ranks = np.argsort(-scores, axis=0)
            compute_map_and_print(dataset + ' + whiten', ranks, cfg['gnd'])
        """

        ############################################################
        # Test
        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
        images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
        qimages = [cfg['qim_fname'](cfg, i) for i in range(cfg['nq'])]

        print(qimages)

        # to load scores
        # oxford
        #f = 'oxf_single.npy'
        #f = 'oxf_mq_avg.npy'
        #f = 'oxf_mq_max.npy'
        #f = 'oxf_sc_imf.npy'

        # paris
        #f = 'par_single.npy'
        #f = 'par_mq_avg.npy'
        #f = 'par_mq_max.npy'
        f = 'par_sc_imf.npy'

        # roxford
        #f = 'roxf_single.npy'
        #f = 'roxf_mq_avg.npy'
        #f = 'roxf_mq_max.npy'
        #f = 'roxf_sc_imf.npy'

        # rparis
        #f = 'rpar_single.npy'
        #f = 'rpar_mq_avg.npy'
        #f = 'rpar_mq_max.npy'
        #f = 'rpar_sc_imf.npy'

        # load
        scores = np.load(f)
        ranks = np.argsort(-scores, axis=0)
        compute_map_and_print(dataset + ' + whiten', ranks, cfg['gnd'])

        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))
def main():
    args = parser.parse_args()

    # loading network from path
    if args.network_path is not None:

        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        if args.network_path in PRETRAINED:
            # pretrained networks (downloaded automatically)
            state = load_url(PRETRAINED[args.network_path],
                             model_dir=os.path.join(get_data_root(),
                                                    'networks'))
        else:
            # fine-tuned network from path
            state = torch.load(args.network_path)

        # parsing net params from meta
        # architecture, pooling, mean, std required
        # the rest has default values, in case that is doesnt exist
        net_params = {}
        net_params['architecture'] = state['meta']['architecture']
        net_params['pooling'] = state['meta']['pooling']
        net_params['local_whitening'] = state['meta'].get(
            'local_whitening', False)
        net_params['regional'] = state['meta'].get('regional', False)
        net_params['whitening'] = state['meta'].get('whitening', False)
        net_params['mean'] = state['meta']['mean']
        net_params['std'] = state['meta']['std']
        net_params['pretrained'] = False

        # load network
        net = init_network(net_params)
        net.load_state_dict(state['state_dict'])

        # if whitening is precomputed
        if 'Lw' in state['meta']:
            net.meta['Lw'] = state['meta']['Lw']

        print(">>>> loaded network: ")
        if "epoch" in state:
            print("Model after {} epochs".format(state["epoch"]))
        print(net.meta_repr())

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:

        # parse off-the-shelf parameters
        offtheshelf = args.network_offtheshelf.split('-')
        net_params = {}
        net_params['architecture'] = offtheshelf[0]
        net_params['pooling'] = offtheshelf[1]
        net_params['local_whitening'] = 'lwhiten' in offtheshelf[2:]
        net_params['regional'] = 'reg' in offtheshelf[2:]
        net_params['whitening'] = 'whiten' in offtheshelf[2:]
        net_params['pretrained'] = True

        # load off-the-shelf network
        print(">> Loading off-the-shelf network:\n>>>> '{}'".format(
            args.network_offtheshelf))
        net = init_network(net_params)
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters: test both single scale and multiscale
    ms_singlescale = [1]
    msp_singlescale = 1

    ms_multiscale = list(eval(args.multiscale))
    msp_multiscale = 1
    if len(ms_multiscale
           ) > 1 and net.meta['pooling'] == 'gem' and not net.meta[
               'regional'] and not net.meta['whitening']:
        msp_multiscale = net.pool.p.item()
    print(">> Set-up multiscale:")
    print(">>>> ms: {}".format(ms_multiscale))
    print(">>>> msp: {}".format(msp_multiscale))

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()

    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    if args.whitening is not None:
        start = time.time()
        if 'Lw' in net.meta and args.whitening in net.meta['Lw']:
            print('>> {}: Whitening is precomputed, loading it...'.format(
                args.whitening))
            Lw = net.meta['Lw'][args.whitening]
        else:
            # if we evaluate networks from path we should save/load whitening
            # not to compute it every time
            if args.network_path is not None:
                whiten_fn = args.network_path + '_{}_whiten'.format(
                    args.whitening)
                whiten_fn += '.pth'
            else:
                whiten_fn = None

            if whiten_fn is not None and os.path.isfile(whiten_fn):
                print('>> {}: Whitening is precomputed, loading it...'.format(
                    args.whitening))
                Lw = torch.load(whiten_fn)
            else:
                Lw = {}
                for whiten_type, ms, msp in zip(
                    ["ss", "ms"], [ms_singlescale, ms_multiscale],
                    [msp_singlescale, msp_multiscale]):
                    print('>> {0}: Learning whitening {1}...'.format(
                        args.whitening, whiten_type))

                    # loading db
                    db_root = os.path.join(get_data_root(), 'train',
                                           args.whitening)
                    ims_root = os.path.join(db_root, 'ims')
                    db_fn = os.path.join(
                        db_root, '{}-whiten.pkl'.format(args.whitening))
                    with open(db_fn, 'rb') as f:
                        db = pickle.load(f)
                    images = [
                        cid2filename(db['cids'][i], ims_root)
                        for i in range(len(db['cids']))
                    ]

                    # extract whitening vectors
                    print('>> {}: Extracting...'.format(args.whitening))
                    wvecs = extract_vectors(net,
                                            images,
                                            args.image_size,
                                            transform,
                                            ms=ms,
                                            msp=msp)

                    # learning whitening
                    print('>> {}: Learning...'.format(args.whitening))
                    wvecs = wvecs.numpy()
                    m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
                    Lw[whiten_type] = {'m': m, 'P': P}

                    print('>> {}: elapsed time: {}'.format(
                        args.whitening, htime(time.time() - start)))

                # saving whitening if whiten_fn exists
                if whiten_fn is not None:
                    print('>> {}: Saving to {}...'.format(
                        args.whitening, whiten_fn))
                    torch.save(Lw, whiten_fn)
    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.datasets.split(',')
    for dataset in datasets:
        start = time.time()

        for whiten_type, ms, msp in zip(["ss", "ms"],
                                        [ms_singlescale, ms_multiscale],
                                        [msp_singlescale, msp_multiscale]):
            print('>> Extracting feature on {0}, whitening {1}'.format(
                dataset, whiten_type))

            # prepare config structure for the test dataset
            cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
            images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
            qimages = [cfg['qim_fname'](cfg, i) for i in range(cfg['nq'])]
            bbxs = [tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])]

            # extract database and query vectors
            print('>> {}: database images...'.format(dataset))
            vecs = extract_vectors(net,
                                   images,
                                   args.image_size,
                                   transform,
                                   ms=ms,
                                   msp=msp)
            print('>> {}: query images...'.format(dataset))
            qvecs = extract_vectors(net,
                                    qimages,
                                    args.image_size,
                                    transform,
                                    bbxs=bbxs,
                                    ms=ms,
                                    msp=msp)

            print('>> {}: Evaluating...'.format(dataset))

            # convert to numpy
            vecs = vecs.numpy()
            qvecs = qvecs.numpy()

            # search, rank, and print
            scores = np.dot(vecs.T, qvecs)
            ranks = np.argsort(-scores, axis=0)
            compute_map_and_print(dataset, ranks, cfg['gnd'])

            if Lw is not None:
                # whiten the vectors
                vecs_lw = whitenapply(vecs, Lw[whiten_type]['m'],
                                      Lw[whiten_type]['P'])
                qvecs_lw = whitenapply(qvecs, Lw[whiten_type]['m'],
                                       Lw[whiten_type]['P'])

                # search, rank, and print
                scores = np.dot(vecs_lw.T, qvecs_lw)
                ranks = np.argsort(-scores, axis=0)
                compute_map_and_print(
                    dataset + ' + whiten {}'.format(whiten_type), ranks,
                    cfg['gnd'])

            print('>> {}: elapsed time: {}'.format(dataset,
                                                   htime(time.time() - start)))
Exemple #10
0
def main():
    args = parser.parse_args()

    # check if test dataset are downloaded
    # and download if they are not
    #download_train(get_data_root())
    #download_test(get_data_root())

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path
    if args.network_path is not None:
        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        if args.network_path in PRETRAINED:
            # pretrained networks (downloaded automatically)
            state = load_url(PRETRAINED[args.network_path],
                             model_dir=os.path.join(get_data_root(),
                                                    'networks'))
        else:
            state = torch.load(args.network_path)
        net = init_network(model=state['meta']['architecture'],
                           pooling=state['meta']['pooling'],
                           whitening=state['meta']['whitening'],
                           mean=state['meta']['mean'],
                           std=state['meta']['std'],
                           pretrained=False)
        net.load_state_dict(state['state_dict'])

        # if whitening is precomputed
        if 'Lw' in state['meta']:
            net.meta['Lw'] = state['meta']['Lw']

        print(">>>> loaded network: ")
        print(net.meta_repr())

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:
        offtheshelf = args.network_offtheshelf.split('-')
        if len(offtheshelf) == 3:
            if offtheshelf[2] == 'whiten':
                offtheshelf_whiten = True
            else:
                raise (RuntimeError(
                    "Incorrect format of the off-the-shelf network. Examples: resnet101-gem | resnet101-gem-whiten"
                ))
        else:
            offtheshelf_whiten = False
        print(">> Loading off-the-shelf network:\n>>>> '{}'".format(
            args.network_offtheshelf))
        net = init_network(model=offtheshelf[0],
                           pooling=offtheshelf[1],
                           whitening=offtheshelf_whiten)
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = [1]
    msp = 1
    if args.multiscale:
        ms = [1, 1. / math.sqrt(2), 1. / 2]
        if net.meta['pooling'] == 'gem' and net.whiten is None:
            msp = net.pool.p.data.tolist()[0]

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()
    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    if args.whitening is not None:
        start = time.time()

        if 'Lw' in net.meta and args.whitening in net.meta['Lw']:

            print('>> {}: Whitening is precomputed, loading it...'.format(
                args.whitening))

            if args.multiscale:
                Lw = net.meta['Lw'][args.whitening]['ms']
            else:
                Lw = net.meta['Lw'][args.whitening]['ss']

        else:

            print('>> {}: Learning whitening...'.format(args.whitening))

            # loading db
            db_root = os.path.join(get_data_root(), 'train', args.whitening)
            ims_root = os.path.join(db_root, 'ims')
            db_fn = os.path.join(db_root,
                                 '{}-whiten.pkl'.format(args.whitening))
            with open(db_fn, 'rb') as f:
                db = pickle.load(f)
            images = [
                cid2filename(db['cids'][i], ims_root)
                for i in range(len(db['cids']))
            ]

            # extract whitening vectors
            print('>> {}: Extracting...'.format(args.whitening))
            wvecs = extract_vectors(net,
                                    images,
                                    args.image_size,
                                    transform,
                                    ms=ms,
                                    msp=msp)

            # learning whitening
            print('>> {}: Learning...'.format(args.whitening))
            wvecs = wvecs.numpy()
            m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
            Lw = {'m': m, 'P': P}

        print('>> {}: elapsed time: {}'.format(args.whitening,
                                               htime(time.time() - start)))
    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.datasets.split(',')
    for dataset in datasets:
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
        images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
        qimages = [cfg['qim_fname'](cfg, i) for i in range(cfg['nq'])]
        bbxs = [tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])]

        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        vecs = extract_vectors(net,
                               images,
                               args.image_size,
                               transform,
                               ms=ms,
                               msp=msp)
        print('>> {}: query images...'.format(dataset))
        qvecs = extract_vectors(net,
                                qimages,
                                args.image_size,
                                transform,
                                bbxs=bbxs,
                                ms=ms,
                                msp=msp)

        print('>> {}: Evaluating...'.format(dataset))

        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()

        # search, rank, and print
        scores = np.dot(vecs.T, qvecs)
        ranks = np.argsort(-scores, axis=0)
        compute_map_and_print(dataset, ranks, cfg['gnd'])

        if Lw is not None:
            # whiten the vectors
            vecs_lw = whitenapply(vecs, Lw['m'], Lw['P'])
            qvecs_lw = whitenapply(qvecs, Lw['m'], Lw['P'])

            # search, rank, and print
            scores = np.dot(vecs_lw.T, qvecs_lw)
            ranks = np.argsort(-scores, axis=0)
            compute_map_and_print(dataset + ' + whiten', ranks, cfg['gnd'])

        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))
Exemple #11
0
def test(datasets, net, noise, image_size):
    global base
    print(">> Evaluating network on test datasets...")

    net.cuda()
    net.eval()
    normalize = transforms.Normalize(mean=net.meta["mean"],
                                     std=net.meta["std"])

    def add_noise(img):
        n = noise
        n = F.interpolate(n.unsqueeze(0),
                          mode=MODE,
                          size=tuple(img.shape[-2:]),
                          align_corners=True).squeeze()
        return torch.clamp(img + n, 0, 1)

    transform_base = transforms.Compose([transforms.ToTensor(), normalize])
    transform_query = transforms.Compose(
        [transforms.ToTensor(),
         transforms.Lambda(add_noise), normalize])

    if "Lw" in net.meta:
        Lw = net.meta["Lw"]["retrieval-SfM-120k"]["ss"]
    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.test_datasets.split(",")
    attack_result = {}
    for dataset in datasets:
        start = time.time()

        print(">> {}: Extracting...".format(dataset))

        cfg = configdataset(dataset, os.path.join(get_data_root(), "test"))
        images = [cfg["im_fname"](cfg, i) for i in range(cfg["n"])]
        qimages = [cfg["qim_fname"](cfg, i) for i in range(cfg["nq"])]
        bbxs = [tuple(cfg["gnd"][i]["bbx"]) for i in range(cfg["nq"])]

        # extract database and query vectors
        print(">> {}: database images...".format(dataset))
        with torch.no_grad():
            if dataset in base and str(image_size) in base[dataset]:
                vecs = base[dataset][str(image_size)]
            else:
                vecs = extract_vectors(net, images, image_size, transform_base)
                if dataset not in base:
                    base[dataset] = {}
                base[dataset][str(image_size)] = vecs
                fname = args.network_path.replace("/", "_") + ".pkl"
                with open(f"base/{fname}", "wb") as f:
                    pickle.dump(base, f)
            print(">> {}: query images...".format(dataset))
            qvecs = extract_vectors(net, qimages, image_size, transform_query,
                                    bbxs)

        print(">> {}: Evaluating...".format(dataset))

        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()

        # whiten the vectors
        vecs_lw = whitenapply(vecs, Lw["m"], Lw["P"])
        qvecs_lw = whitenapply(qvecs, Lw["m"], Lw["P"])

        # search, rank, and print
        scores = np.dot(vecs_lw.T, qvecs_lw)
        ranks = np.argsort(-scores, axis=0)
        r = compute_map_and_print(dataset + " + whiten", ranks, cfg["gnd"])
        attack_result[dataset] = r

        print(">> {}: elapsed time: {}".format(dataset,
                                               htime(time.time() - start)))
    return inv_gfr(
        attack_result,
        baseline_result[net.meta["architecture"]][net.meta["pooling"]])
Exemple #12
0
def main():
    args = parser.parse_args()

    # check if test dataset are downloaded
    # and download if they are not
    download_train(get_data_root())
    download_test(get_data_root())

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path
    if args.network_path is not None:
        net = load_network(args.network_path)

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:
        net = load_offtheshelf(args.network_offtheshelf)

    # setting up the multi-scale parameters
    ms = [1]
    msp = 1
    if args.multiscale:
        ms = [1, 1./math.sqrt(2), 1./2]
        if net.meta['pooling'] == 'gem' and net.whiten is None:
            msp = net.pool.p.data.tolist()[0]

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()
    # set up the transform
    normalize = transforms.Normalize(
        mean=net.meta['mean'],
        std=net.meta['std']
    )
    transform = transforms.Compose([
        transforms.ToTensor(),
        normalize
    ])

    # compute whitening
    if args.whitening is not None:
        start = time.time()

        if 'Lw' in net.meta and args.whitening in net.meta['Lw']:

            print('>> {}: Whitening is precomputed, loading it...'.format(args.whitening))

            if args.multiscale:
                Lw = net.meta['Lw'][args.whitening]['ms']
            else:
                Lw = net.meta['Lw'][args.whitening]['ss']

        else:

            print('>> {}: Learning whitening...'.format(args.whitening))

            if args.whitening == "scores":
                # special logic for scores database
                from score_retrieval.exports import (
                    db,
                    train_images as images,
                )

            else:
                # loading db
                db_root = os.path.join(get_data_root(), 'train', args.test_whiten)
                ims_root = os.path.join(db_root, 'ims')
                db_fn = os.path.join(db_root, '{}-whiten.pkl'.format(args.test_whiten))
                with open(db_fn, 'rb') as f:
                    db = pickle.load(f)
                images = [cid2filename(db['cids'][i], ims_root) for i in range(len(db['cids']))]

            # extract whitening vectors
            print('>> {}: Extracting...'.format(args.whitening))
            wvecs = extract_vectors(net, images, args.image_size, transform, ms=ms, msp=msp)

            # learning whitening
            print('>> {}: Learning...'.format(args.whitening))
            wvecs = wvecs.numpy()
            m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
            Lw = {'m': m, 'P': P}

        print('>> {}: elapsed time: {}'.format(args.whitening, htime(time.time()-start)))
    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.datasets.split(',')
    for dataset in datasets:
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        if dataset == "scores":
            # Special added logic to handle loading our score dataset
            from score_retrieval.exports import (
                images,
                qimages,
                gnd,
            )

            print('>> {}: database images...'.format(dataset))
            vecs = extract_vectors(net, images, args.image_size, transform, ms=ms, msp=msp)
            print('>> {}: query images...'.format(dataset))
            qvecs = extract_vectors(net, qimages, args.image_size, transform, ms=ms, msp=msp)

        else:
            # extract ground truth
            cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
            gnd = cfg['gnd']

            # prepare config structure for the test dataset
            images = [cfg['im_fname'](cfg,i) for i in range(cfg['n'])]
            qimages = [cfg['qim_fname'](cfg,i) for i in range(cfg['nq'])]
            bbxs = [tuple(gnd[i]['bbx']) for i in range(cfg['nq'])]

            # extract database and query vectors
            print('>> {}: database images...'.format(dataset))
            vecs = extract_vectors(net, images, args.image_size, transform, ms=ms, msp=msp)
            print('>> {}: query images...'.format(dataset))
            qvecs = extract_vectors(net, qimages, args.image_size, transform, bbxs=bbxs, ms=ms, msp=msp)

        # validation
        print(">> {}: gnd stats: {}, {}, {}".format(
            dataset,
            len(gnd),
            [len(x["ok"]) for x in gnd[10:]],
            [len(x["junk"]) for x in gnd[10:]],
        ))
        print(">> {}: image stats: {}, {}".format(dataset, len(images), len(qimages)))
        assert len(gnd) == len(qimages), (len(gnd), len(qimages))

        print('>> {}: Evaluating...'.format(dataset))

        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()
        print(">> {}: qvecs.shape: {}".format(dataset, qvecs.shape))

        # search, rank, and print
        scores = np.dot(vecs.T, qvecs)
        ranks = np.argsort(-scores, axis=0)
        print(">> {}: ranks (shape {}) head: {}".format(dataset, ranks.shape, ranks[10:,10:]))
        print(">> {}: gnd head: {}".format(dataset, gnd[5:]))

        # Compute and print metrics
        compute_acc(ranks, gnd, dataset)
        compute_mrr(ranks, gnd, dataset)
        compute_map_and_print(dataset, ranks, gnd)

        if Lw is not None:
            # whiten the vectors
            vecs_lw  = whitenapply(vecs, Lw['m'], Lw['P'])
            qvecs_lw = whitenapply(qvecs, Lw['m'], Lw['P'])

            # search, rank, and print
            scores = np.dot(vecs_lw.T, qvecs_lw)
            ranks = np.argsort(-scores, axis=0)
            compute_acc(ranks, gnd, dataset + " + whiten")
            compute_mrr(ranks, gnd, dataset + " + whiten")
            compute_map_and_print(dataset + " + whiten", ranks, gnd)

        print('>> {}: elapsed time: {}'.format(dataset, htime(time.time()-start)))
def main():
    args = parser.parse_args()
    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path
    result_dir = 'retreival_results'
    if args.network_path is not None:
        result_dir = os.path.join(result_dir, args.network_path)
        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        if args.network_path in PRETRAINED:
            # pretrained networks (downloaded automatically)
            state = load_url(PRETRAINED[args.network_path],
                             model_dir=os.path.join(get_data_root(),
                                                    'networks'))
        else:
            state = torch.load(args.network_path)
        net = init_network(model=state['meta']['architecture'],
                           pooling=state['meta']['pooling'],
                           whitening=state['meta']['whitening'],
                           mean=state['meta']['mean'],
                           std=state['meta']['std'],
                           pretrained=False)
        net.load_state_dict(state['state_dict'])

        # if whitening is precomputed
        if 'Lw' in state['meta']:
            net.meta['Lw'] = state['meta']['Lw']

        print(">>>> loaded network: ")
        print(net.meta_repr())

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:
        result_dir = os.path.join(result_dir, args.network_offtheshelf)
        offtheshelf = args.network_offtheshelf.split('-')
        if len(offtheshelf) == 3:
            if offtheshelf[2] == 'whiten':
                offtheshelf_whiten = True
            else:
                raise (RuntimeError(
                    "Incorrect format of the off-the-shelf network. Examples: resnet101-gem | resnet101-gem-whiten"
                ))
        else:
            offtheshelf_whiten = False
        print(">> Loading off-the-shelf network:\n>>>> '{}'".format(
            args.network_offtheshelf))
        net = init_network(model=offtheshelf[0],
                           pooling=offtheshelf[1],
                           whitening=offtheshelf_whiten)
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = [1]
    msp = 1
    if args.multiscale:
        ms = [1, 1. / math.sqrt(2), 1. / 2]
        if net.meta['pooling'] == 'gem' and net.whiten is None:
            msp = net.pool.p.data.tolist()[0]

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()

    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    if args.whitening is not None:
        start = time.time()
        if 'Lw' in net.meta and args.whitening in net.meta['Lw']:

            print('>> {}: Whitening is precomputed, loading it...'.format(
                args.whitening))

            if args.multiscale:
                Lw = net.meta['Lw'][args.whitening]['ms']
            else:
                Lw = net.meta['Lw'][args.whitening]['ss']
        else:
            # Save whitening TODO
            print('>> {}: Learning whitening...'.format(args.whitening))

            # loading db
            db_root = os.path.join(get_data_root(), 'train', args.whitening)
            ims_root = os.path.join(db_root, 'ims')
            db_fn = os.path.join(db_root,
                                 '{}-whiten.pkl'.format(args.whitening))
            with open(db_fn, 'rb') as f:
                db = pickle.load(f)
            images = [
                cid2filename(db['cids'][i], ims_root)
                for i in range(len(db['cids']))
            ]

            # extract whitening vectors
            print('>> {}: Extracting...'.format(args.whitening))
            wvecs = extract_vectors(net,
                                    images,
                                    args.image_size,
                                    transform,
                                    ms=ms,
                                    msp=msp)

            # learning whitening
            print('>> {}: Learning...'.format(args.whitening))
            wvecs = wvecs.numpy()
            m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
            Lw = {'m': m, 'P': P}

        print('>> {}: elapsed time: {}'.format(args.whitening,
                                               htime(time.time() - start)))
    else:
        Lw = None

    # evaluate on test datasets
    data_root = args.data_root
    datasets = datasets_names[args.dataset]
    result_dict = {}
    for dataset in datasets:
        start = time.time()
        result_dict[dataset] = {}
        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        images = get_imlist(data_root, dataset, args.train_txt)
        qimages = get_imlist(data_root, dataset, args.query_txt)

        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        vecs = extract_vectors(net,
                               images,
                               args.image_size,
                               transform,
                               root=os.path.join(data_root, dataset),
                               ms=ms,
                               msp=msp)
        print('>> {}: query images...'.format(dataset))
        qvecs = extract_vectors(net,
                                qimages,
                                args.image_size,
                                transform,
                                root=os.path.join(data_root, dataset),
                                ms=ms,
                                msp=msp)
        print('>> {}: Evaluating...'.format(dataset))

        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()
        scores, ranks = cal_ranks(vecs, vecs, Lw)
        result_dict[dataset]['train'] = {'scores': scores, 'ranks': ranks}
        scores, ranks = cal_ranks(vecs, qvecs, Lw)
        result_dict[dataset]['test'] = {'scores': scores, 'ranks': ranks}
        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))

    # Save retrieval results
    if not os.path.exists(result_dir):
        os.makedirs(result_dir)
    result_file = os.path.join(result_dir, args.outfile)
    np.save(result_file, result_dict)
    print('Save retrieval results to {}'.format(result_file))
def main():
    args = parser.parse_args()

    # check if there are unknown datasets
    for dataset in args.datasets.split(','):
        if dataset not in datasets_names:
            raise ValueError('Unsupported or unknown dataset: {}!'.format(dataset))

    # check if test dataset are downloaded
    # and download if they are not
    # download_train(get_data_root())
    # download_test(get_data_root())

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path
    if args.network_path is not None:

        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        if args.network_path in PRETRAINED:
            # pretrained networks (downloaded automatically)
            state = load_url(PRETRAINED[args.network_path], model_dir=os.path.join(get_data_root(), 'networks'))
        else:
            # fine-tuned network from path
            state = torch.load(args.network_path)

        # parsing net params from meta
        # architecture, pooling, mean, std required
        # the rest has default values, in case that is doesnt exist
        net_params = {}
        net_params['architecture'] = state['meta']['architecture']
        net_params['pooling'] = state['meta']['pooling']
        net_params['local_whitening'] = state['meta'].get('local_whitening', False)
        net_params['regional'] = state['meta'].get('regional', False)
        net_params['whitening'] = state['meta'].get('whitening', False)
        net_params['mean'] = state['meta']['mean']
        net_params['std'] = state['meta']['std']
        net_params['pretrained'] = False
        net_params['multi_layer_cat'] = state['meta']['multi_layer_cat']

        # load network
        net = init_network(net_params)
        net.load_state_dict(state['state_dict'])
        
        # if whitening is precomputed
        if 'Lw' in state['meta']:
            net.meta['Lw'] = state['meta']['Lw']
        
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:
        
        # parse off-the-shelf parameters
        offtheshelf = args.network_offtheshelf.split('-')
        net_params = {}
        net_params['architecture'] = offtheshelf[0]
        net_params['pooling'] = offtheshelf[1]
        net_params['local_whitening'] = 'lwhiten' in offtheshelf[2:]
        net_params['regional'] = 'reg' in offtheshelf[2:]
        net_params['whitening'] = 'whiten' in offtheshelf[2:]
        net_params['pretrained'] = True

        # load off-the-shelf network
        print(">> Loading off-the-shelf network:\n>>>> '{}'".format(args.network_offtheshelf))
        net = init_network(net_params)
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters
    print(">> image size: {}".format(args.image_size))
    ms = list(eval(args.multiscale))
    if len(ms)>1 and net.meta['pooling'] == 'gem' and not net.meta['regional'] and not net.meta['whitening']:
        msp = net.pool.p.item()
        print(">> Set-up multiscale:")
        print(">>>> ms: {}".format(ms))            
        print(">>>> msp: {}".format(msp))
    else:
        msp = 1
        print(">> Set-up multiscale:")
        print(">>>> ms: {}".format(ms))
        print(">>>> msp: {}".format(msp))

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()

    # set up the transform
    normalize = transforms.Normalize(
        mean=net.meta['mean'],
        std=net.meta['std']
    )
    transform = transforms.Compose([
        transforms.ToTensor(),
        normalize
    ])

    # compute whitening
    if args.whitening is not None:
        start = time.time()

        if 'Lw' in net.meta and args.whitening in net.meta['Lw']:
            
            print('>> {}: Whitening is precomputed, loading it...'.format(args.whitening))
            
            if len(ms)>1:
                Lw = net.meta['Lw'][args.whitening]['ms']
            else:
                Lw = net.meta['Lw'][args.whitening]['ss']

        else:

            # if we evaluate networks from path we should save/load whitening
            # not to compute it every time
            if args.network_path is not None:
                whiten_fn = args.network_path + '_{}_whiten'.format(args.whitening)
                if len(ms) > 1:
                    whiten_fn += '_ms'
                whiten_fn += '.pth'
            else:
                whiten_fn = None

            if whiten_fn is not None and os.path.isfile(whiten_fn):
                print('>> {}: Whitening is precomputed, loading it...'.format(args.whitening))
                Lw = torch.load(whiten_fn)

            else:
                print('>> {}: Learning whitening...'.format(args.whitening))
                
                # loading db
                db_root = os.path.join(get_data_root(), 'train', args.whitening)
                ims_root = os.path.join(db_root, 'ims')
                db_fn = os.path.join(db_root, '{}-whiten.pkl'.format(args.whitening))
                with open(db_fn, 'rb') as f:
                    db = pickle.load(f)
                images = [cid2filename(db['cids'][i], ims_root) for i in range(len(db['cids']))]

                # extract whitening vectors
                print('>> {}: Extracting...'.format(args.whitening))
                wvecs = extract_vectors(net, images, args.image_size, transform, ms=ms, msp=msp)
                
                # learning whitening 
                print('>> {}: Learning...'.format(args.whitening))
                wvecs = wvecs.numpy()
                m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
                Lw = {'m': m, 'P': P}

                # saving whitening if whiten_fn exists
                if whiten_fn is not None:
                    print('>> {}: Saving to {}...'.format(args.whitening, whiten_fn))
                    torch.save(Lw, whiten_fn)

        print('>> {}: elapsed time: {}'.format(args.whitening, htime(time.time()-start)))

    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.datasets.split(',')
    for dataset in datasets: 
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
        images = [cfg['im_fname'](cfg,i) for i in range(cfg['n'])]
        qimages = [cfg['qim_fname'](cfg,i) for i in range(cfg['nq'])]
        # bbxs = [tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])]

        print('>> not use bbxs...')
        bbxs = None

        # key_url_list = ParseData(os.path.join(get_data_root(), 'index.csv'))
        # index_image_path = os.path.join(get_data_root(), 'resize_index_image')
        # images = [os.path.join(index_image_path, key_url_list[i][0]) for i in range(len(key_url_list))]
        # key_url_list = ParseData(os.path.join(get_data_root(), 'test.csv'))
        # test_image_path = os.path.join(get_data_root(), 'resize_test_image')
        # qimages = [os.path.join(test_image_path, key_url_list[i][0]) for i in range(len(key_url_list))]
        # # bbxs = [tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])]

        # csvfile = open(os.path.join(get_data_root(), 'index_clear.csv'), 'r')
        # csvreader = csv.reader(csvfile)
        # images = [line[:1][0] for line in csvreader]
        #
        # csvfile = open(os.path.join(get_data_root(), 'test_clear.csv'), 'r')
        # csvreader = csv.reader(csvfile)
        # qimages = [line[:1][0] for line in csvreader]

        # bbxs = None
        
        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        vecs = extract_vectors(net, images, args.image_size, transform, ms=ms, msp=msp)
        # vecs = torch.randn(2048, 5063)
        # vecs = torch.randn(2048, 4993)

        # hxq modified
        # bbxs = None
        # print('>> set no bbxs...')
        print('>> {}: query images...'.format(dataset))
        qvecs = extract_vectors(net, qimages, args.image_size, transform, bbxs=bbxs, ms=ms, msp=msp)
        
        print('>> {}: Evaluating...'.format(dataset))

        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()

        # search, rank, and print
        scores = np.dot(vecs.T, qvecs)

        # hxq modified, test add features map for retrieval
        # vecs = [vecs[i].numpy() for i in range(len(vecs))]
        # qvecs_temp = np.zeros((qvecs[0].shape[0], len(qvecs)))
        # for i in range(len(qvecs)):
        #     qvecs_temp[:, i] = qvecs[i][:, 0].numpy()
        # qvecs = qvecs_temp
        #
        # scores = np.zeros((len(vecs), qvecs.shape[-1]))
        # for i in range(len(vecs)):
        #     scores[i, :] = np.amax(np.dot(vecs[i].T, qvecs), 0)

        ranks = np.argsort(-scores, axis=0)
        mismatched_info = compute_map_and_print(dataset, ranks, cfg['gnd'], kappas=[1, 5, 10, 100])

        # hxq added
        show_false_img = False
        if show_false_img == True:
            print('>> Save mismatched image tuple...')
            for info in mismatched_info:
                mismatched_img_show_save(info, qimages, images, args, bbxs=bbxs)
    
        if Lw is not None:
            # whiten the vectors
            vecs_lw  = whitenapply(vecs, Lw['m'], Lw['P'])
            qvecs_lw = whitenapply(qvecs, Lw['m'], Lw['P'])

            # search, rank, and print
            scores = np.dot(vecs_lw.T, qvecs_lw)
            ranks = np.argsort(-scores, axis=0)
            mismatched_info = compute_map_and_print(dataset + ' + whiten', ranks, cfg['gnd'])

            # hxq added
            # show_false_img = False
            if show_false_img == True:
                print('>> Save mismatched image tuple...')
                for info in mismatched_info:
                    mismatched_img_show_save(info, qimages, images, args, bbxs=bbxs)
        
        print('>> {}: elapsed time: {}'.format(dataset, htime(time.time()-start)))
Exemple #15
0
def main():
    #def process(network_path, datasets='oxford5k,paris6k', whitening=None, image_size=1024, multiscale = '[1]', query=None):
    args = parser.parse_args()
    #args.query = None
    # check if there are unknown datasets
    for dataset in args.datasets.split(','):
        if dataset not in datasets_names:
            raise ValueError(
                'Unsupported or unknown dataset: {}!'.format(dataset))

    # check if test dataset are downloaded
    # and download if they are not
    #download_train(get_data_root())
    #download_test(get_data_root())

    # setting up the visible GPU
    #os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path
    if args.network_path is not None:

        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        if args.network_path in PRETRAINED:
            # pretrained networks (downloaded automatically)
            state = load_url(PRETRAINED[args.network_path],
                             model_dir=os.path.join(get_data_root(),
                                                    'networks'))
        else:
            # fine-tuned network from path
            state = torch.load(args.network_path)

        # parsing net params from meta
        # architecture, pooling, mean, std required
        # the rest has default values, in case that is doesnt exist
        net_params = {}
        net_params['architecture'] = state['meta']['architecture']
        net_params['pooling'] = state['meta']['pooling']
        net_params['local_whitening'] = state['meta'].get(
            'local_whitening', False)
        net_params['regional'] = state['meta'].get('regional', False)
        net_params['whitening'] = state['meta'].get('whitening', False)
        net_params['mean'] = state['meta']['mean']
        net_params['std'] = state['meta']['std']
        net_params['pretrained'] = False

        # load network
        net = init_network(net_params)
        net.load_state_dict(state['state_dict'])

        # if whitening is precomputed
        if 'Lw' in state['meta']:
            net.meta['Lw'] = state['meta']['Lw']

        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = list(eval(args.multiscale))
    if len(ms) > 1 and net.meta['pooling'] == 'gem' and not net.meta[
            'regional'] and not net.meta['whitening']:
        msp = net.pool.p.item()
        print(">> Set-up multiscale:")
        print(">>>> ms: {}".format(ms))
        print(">>>> msp: {}".format(msp))
    else:
        msp = 1

    # moving network to gpu and eval mode
    #net.cuda()
    #net.eval()

    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    if args.whitening is not None:
        start = time.time()

        if 'Lw' in net.meta and args.whitening in net.meta['Lw']:

            print('>> {}: Whitening is precomputed, loading it...'.format(
                args.whitening))

            if len(ms) > 1:
                Lw = net.meta['Lw'][args.whitening]['ms']
            else:
                Lw = net.meta['Lw'][args.whitening]['ss']

        else:

            # if we evaluate networks from path we should save/load whitening
            # not to compute it every time
            if args.network_path is not None:
                whiten_fn = args.network_path + '_{}_whiten'.format(
                    args.whitening)
                if len(ms) > 1:
                    whiten_fn += '_ms'
                whiten_fn += '.pth'
            else:
                whiten_fn = None
            print(whiten_fn)
            return
            if whiten_fn is not None and os.path.isfile(whiten_fn):
                print('>> {}: Whitening is precomputed, loading it...'.format(
                    args.whitening))
                Lw = torch.load(whiten_fn)

            else:
                print('>> {}: Learning whitening...'.format(args.whitening))

                # loading db
                db_root = os.path.join(get_data_root(), 'train',
                                       args.whitening)
                ims_root = os.path.join(db_root, 'ims')
                db_fn = os.path.join(db_root,
                                     '{}-whiten.pkl'.format(args.whitening))
                with open(db_fn, 'rb') as f:
                    db = pickle.load(f)
                images = [
                    cid2filename(db['cids'][i], ims_root)
                    for i in range(len(db['cids']))
                ]

                # extract whitening vectors
                print('>> {}: Extracting...'.format(args.whitening))
                wvecs = extract_vectors(net,
                                        images,
                                        args.image_size,
                                        transform,
                                        ms=ms,
                                        msp=msp)

                # learning whitening
                print('>> {}: Learning...'.format(args.whitening))
                wvecs = wvecs.numpy()
                m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
                Lw = {'m': m, 'P': P}

                # saving whitening if whiten_fn exists
                if whiten_fn is not None:
                    print('>> {}: Saving to {}...'.format(
                        args.whitening, whiten_fn))
                    torch.save(Lw, whiten_fn)

        print('>> {}: elapsed time: {}'.format(args.whitening,
                                               htime(time.time() - start)))

    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.datasets.split(',')
    # query type

    for dataset in datasets:
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))

        #for i in cfg: print(i)
        #print(cfg['gnd'][0]['bbx'])
        #return

        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        feas_dir = os.path.join(cfg['dir_data'], 'features')
        if not os.path.isdir(feas_dir):
            os.mkdir(feas_dir)
        feas_sv = os.path.join(
            feas_dir, dataset + '_' + args.network_path + '_features.pkl')
        if not os.path.isfile(feas_sv):
            images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
            vecs = extract_vectors(net,
                                   images,
                                   args.image_size,
                                   transform,
                                   ms=ms,
                                   msp=msp)
            with open(feas_sv, 'wb') as f:
                pickle.dump(vecs, f)
        else:
            with open(feas_sv, 'rb') as f:
                vecs = pickle.load(f)

        print('>> {}: query images...'.format(dataset))
        if args.query is not None:
            qimages = [args.query]
            qvecs = extract_vectors(net,
                                    qimages,
                                    args.image_size,
                                    transform,
                                    ms=ms,
                                    msp=msp)
        else:
            qfeas_dir = feas_dir
            qfeas_sv = os.path.join(
                qfeas_dir,
                dataset + '_' + args.network_path + '_qfeatures.pkl')
            if not os.path.isfile(qfeas_sv):
                qimages = [cfg['qim_fname'](cfg, i) for i in range(cfg['nq'])]
                try:
                    bbxs = [
                        tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])
                    ]
                except:
                    bbxs = None
                qvecs = extract_vectors(net,
                                        qimages,
                                        args.image_size,
                                        transform,
                                        bbxs=bbxs,
                                        ms=ms,
                                        msp=msp)
                with open(qfeas_sv, 'wb') as f:
                    pickle.dump(qvecs, f)
            else:
                with open(qfeas_sv, 'rb') as f:
                    qvecs = pickle.load(f)

        print('>> {}: Evaluating...'.format(dataset))
        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()
        #qvecs = qvecs[:, 0].reshape(-1, 1)
        #args.query = True
        # search, rank, and print
        if Lw is not None:
            # whiten the vectors
            vecs_lw = whitenapply(vecs, Lw['m'], Lw['P'])
            qvecs_lw = whitenapply(qvecs, Lw['m'], Lw['P'])

            # search, rank, and print
            scores = np.dot(vecs_lw.T, qvecs_lw)
            ranksw = np.argsort(-scores, axis=0)
            if args.query is None:
                #compute_map_and_print(dataset + ' + whiten', ranksw, cfg['gnd'])
                compute_map_and_print1(dataset + ' + whiten', ranksw,
                                       cfg['gnd'])

                scores = np.dot(vecs.T, qvecs)
                ranks = np.argsort(-scores, axis=0)
                # compute_map_and_print(dataset, ranks, cfg['gnd'])
                compute_map_and_print1(dataset, ranks, cfg['gnd'])
            else:
                a = []
                for i in ranksw:
                    a.append(
                        os.path.join(cfg['dir_images'], cfg['imlist'][i[0]]) +
                        cfg['ext'])
                print(a[:10])
                result = cfg['dir_data'] + '_result'
                with open(result + '.pkl', 'wb') as f:
                    pickle.dump(a[:10], f)
        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))
Exemple #16
0
def main():
    args = parser.parse_args()

    # check if there are unknown datasets
    for dataset in args.datasets.split(','):
        if dataset not in datasets_names:
            raise ValueError(
                'Unsupported or unknown dataset: {}!'.format(dataset))

    # check if test dataset are downloaded
    # and download if they are not
    #download_train(get_data_root())
    #download_test(get_data_root())

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path
    if args.network_path is not None:

        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        if args.network_path in PRETRAINED:
            # pretrained networks (downloaded automatically)
            state = load_url(PRETRAINED[args.network_path],
                             model_dir=os.path.join(get_data_root(),
                                                    'networks'))
        else:
            # fine-tuned network from path
            state = torch.load(args.network_path)

        # parsing net params from meta
        # architecture, pooling, mean, std required
        # the rest has default values, in case that is doesnt exist
        net_params = {}
        net_params['architecture'] = state['meta']['architecture']
        net_params['pooling'] = state['meta']['pooling']
        net_params['local_whitening'] = state['meta'].get(
            'local_whitening', False)
        net_params['regional'] = state['meta'].get('regional', False)
        net_params['whitening'] = state['meta'].get('whitening', False)
        net_params['mean'] = state['meta']['mean']
        net_params['std'] = state['meta']['std']
        net_params['pretrained'] = False

        # load network
        net = init_network(net_params)
        net.load_state_dict(state['state_dict'])

        # if whitening is precomputed
        if 'Lw' in state['meta']:
            net.meta['Lw'] = state['meta']['Lw']

        print(">>>> loaded network: ")
        print(net.meta_repr())

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:

        # parse off-the-shelf parameters
        offtheshelf = args.network_offtheshelf.split('-')
        net_params = {}
        net_params['architecture'] = offtheshelf[0]
        net_params['pooling'] = offtheshelf[1]
        net_params['local_whitening'] = 'lwhiten' in offtheshelf[2:]
        net_params['regional'] = 'reg' in offtheshelf[2:]
        net_params['whitening'] = 'whiten' in offtheshelf[2:]
        net_params['pretrained'] = True

        # load off-the-shelf network
        print(">> Loading off-the-shelf network:\n>>>> '{}'".format(
            args.network_offtheshelf))
        net = init_network(net_params)
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = list(eval(args.multiscale))
    if len(ms) > 1 and net.meta['pooling'] == 'gem' and not net.meta[
            'regional'] and not net.meta['whitening']:
        msp = net.pool.p.item()
        print(">> Set-up multiscale:")
        print(">>>> ms: {}".format(ms))
        print(">>>> msp: {}".format(msp))
    else:
        msp = 1

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()

    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    if args.whitening is not None:
        start = time.time()

        if 'Lw' in net.meta and args.whitening in net.meta['Lw']:

            print('>> {}: Whitening is precomputed, loading it...'.format(
                args.whitening))

            if len(ms) > 1:
                Lw = net.meta['Lw'][args.whitening]['ms']
            else:
                Lw = net.meta['Lw'][args.whitening]['ss']

        else:

            # if we evaluate networks from path we should save/load whitening
            # not to compute it every time
            if args.network_path is not None:
                whiten_fn = args.network_path + '_{}_whiten'.format(
                    args.whitening)
                if len(ms) > 1:
                    whiten_fn += '_ms'
                whiten_fn += '.pth'
            else:
                whiten_fn = None

            if whiten_fn is not None and os.path.isfile(whiten_fn):
                print('>> {}: Whitening is precomputed, loading it...'.format(
                    args.whitening))
                Lw = torch.load(whiten_fn)

            else:
                print('>> {}: Learning whitening...'.format(args.whitening))

                # loading db
                db_root = os.path.join(get_data_root(), 'train',
                                       args.whitening)
                ims_root = os.path.join(db_root, 'ims')
                db_fn = os.path.join(db_root,
                                     '{}-whiten.pkl'.format(args.whitening))
                with open(db_fn, 'rb') as f:
                    db = pickle.load(f)
                images = [
                    cid2filename(db['cids'][i], ims_root)
                    for i in range(len(db['cids']))
                ]

                # extract whitening vectors
                print('>> {}: Extracting...'.format(args.whitening))
                wvecs = extract_vectors(net,
                                        images,
                                        args.image_size,
                                        transform,
                                        ms=ms,
                                        msp=msp)

                # learning whitening
                print('>> {}: Learning...'.format(args.whitening))
                wvecs = wvecs.numpy()
                m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
                Lw = {'m': m, 'P': P}

                # saving whitening if whiten_fn exists
                if whiten_fn is not None:
                    print('>> {}: Saving to {}...'.format(
                        args.whitening, whiten_fn))
                    torch.save(Lw, whiten_fn)

        print('>> {}: elapsed time: {}'.format(args.whitening,
                                               htime(time.time() - start)))

    else:
        Lw = None
    # evaluate on test datasets
    datasets = args.datasets.split(',')
    for dataset in datasets:
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        #cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
        images = []
        gallery_file = open(
            '/home/zzd/University1652-Baseline/gallery_name.txt')
        for line in gallery_file:
            images.append('/home/zzd/University1652-Baseline/' +
                          line.replace('\n', '')[2:])
        #qimages = [cfg['qim_fname'](cfg,i) for i in range(cfg['nq'])]
        qimages = []
        query_file = open('/home/zzd/University1652-Baseline/query_name.txt')
        for line in query_file:
            qimages.append('/home/zzd/University1652-Baseline/' +
                           line.replace('\n', '')[2:])

        gallery_label = get_id(images)
        query_label = get_id(qimages)

        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        gallery_feature = extract_vectors(net,
                                          images,
                                          args.image_size,
                                          transform,
                                          ms=ms,
                                          msp=msp)
        gallery_feature = torch.transpose(gallery_feature, 0, 1)
        print('>> {}: query images...'.format(dataset))
        query_feature = extract_vectors(net,
                                        qimages,
                                        args.image_size,
                                        transform,
                                        ms=ms,
                                        msp=msp)
        query_feature = torch.transpose(query_feature, 0, 1)
        result = {
            'gallery_f': gallery_feature.numpy(),
            'gallery_label': gallery_label,
            'query_f': query_feature.numpy(),
            'query_label': query_label
        }
        scipy.io.savemat('pytorch_result.mat', result)
        os.system('python evaluate_gpu.py')
        print('>> {}: Evaluating...'.format(dataset))
Exemple #17
0
def main():
    args = parser.parse_args()

    # check if test dataset are downloaded
    # and download if they are not
    download_train(get_data_root())
    download_test(get_data_root())

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path
    if args.network_path is not None:
        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        state = torch.load(args.network_path)
        net = init_network(model=state['meta']['architecture'],
                           pooling=state['meta']['pooling'],
                           whitening=state['meta']['whitening'],
                           mean=state['meta']['mean'],
                           std=state['meta']['std'],
                           pretrained=False)
        net.load_state_dict(state['state_dict'])
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:
        offtheshelf = args.network_offtheshelf.split('-')
        if len(offtheshelf) == 3:
            if offtheshelf[2] == 'whiten':
                offtheshelf_whiten = True
            else:
                raise (RuntimeError(
                    "Incorrect format of the off-the-shelf network. Examples: resnet101-gem | resnet101-gem-whiten"
                ))
        else:
            offtheshelf_whiten = False
        print(">> Loading off-the-shelf network:\n>>>> '{}'".format(
            args.network_offtheshelf))
        net = init_network(model=offtheshelf[0],
                           pooling=offtheshelf[1],
                           whitening=offtheshelf_whiten)
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = [1]
    msp = 1
    if args.multiscale:
        ms = [1, 1. / math.sqrt(2), 1. / 2]
        if net.meta['pooling'] == 'gem' and net.whiten is None:
            msp = net.pool.p.data.tolist()[0]

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()
    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    if args.whitening is not None:
        start = time.time()

        print('>> {}: Learning whitening...'.format(args.whitening))

        # loading db
        db_root = os.path.join(get_data_root(), 'train', args.whitening)
        ims_root = os.path.join(db_root, 'ims')
        db_fn = os.path.join(db_root, '{}-whiten.pkl'.format(args.whitening))
        with open(db_fn, 'rb') as f:
            db = pickle.load(f)
        images = [
            cid2filename(db['cids'][i], ims_root)
            for i in range(len(db['cids']))
        ]

        # extract whitening vectors
        print('>> {}: Extracting...'.format(args.whitening))
        wvecs = extract_vectors(net,
                                images,
                                args.image_size,
                                transform,
                                ms=ms,
                                msp=msp)

        # learning whitening
        print('>> {}: Learning...'.format(args.whitening))
        wvecs = wvecs.numpy()
        m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
        Lw = {'m': m, 'P': P}

        print('>> {}: elapsed time: {}'.format(args.whitening,
                                               htime(time.time() - start)))
    else:
        Lw = None

    datasets = args.datasets.split(',')
    for dataset in datasets:
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        if dataset == 'reco':
            images, qimages = landmark_recognition_dataset()
            bbxs = [None for x in qimages]

        elif dataset == 'retr':
            images, _ = landmark_retrieval_dataset()
            qimages = []
            bbxs = [None for x in qimages]

        else:
            # prepare config structure for the test dataset
            cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
            images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
            qimages = [cfg['qim_fname'](cfg, i) for i in range(cfg['nq'])]
            bbxs = [tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])]

        with open('%s_fnames.pkl' % dataset, 'wb') as f:
            pickle.dump([images, qimages], f)

        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        vecs = extract_vectors(net,
                               images,
                               args.image_size,
                               transform,
                               ms=ms,
                               msp=msp)
        vecs = vecs.numpy()
        print('>> saving')
        np.save('{}_vecs.npy'.format(dataset), vecs)

        if len(qimages) > 0:
            print('>> {}: query images...'.format(dataset))
            qvecs = extract_vectors(net,
                                    qimages,
                                    args.image_size,
                                    transform,
                                    bbxs=bbxs,
                                    ms=ms,
                                    msp=msp)
            qvecs = qvecs.numpy()
            np.save('{}_qvecs.npy'.format(dataset), qvecs)

        if Lw is not None:
            # whiten the vectors
            vecs_lw = whitenapply(vecs, Lw['m'], Lw['P'])
            qvecs_lw = whitenapply(qvecs, Lw['m'], Lw['P'])

            # TODO

        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))
Exemple #18
0
def test(args, config, model, rank=None, world_size=None, **varargs):

    log_debug('Evaluating network on test datasets...')

    # Eval mode
    model.eval()
    data_config = config["dataloader"]
    local_config = config["local"]

    # Average score
    avg_score = 0.0

    # Evaluate on test datasets
    list_datasets = data_config.getstruct("test_datasets")

    for dataset in list_datasets:

        start = time.time()
        Avg_F_score = 0.

        log_debug('{%s}: Loading Dataset', dataset)

        for split in {"v", "i"}:

            test_tf = ISSTestTransform(
                rgb_mean=data_config.getstruct("rgb_mean"),
                rgb_std=data_config.getstruct("rgb_std"),
                shortest_size=data_config.getint("test_shortest_size"),
                longest_max_size=data_config.getint("test_longest_max_size"),
                num_kpt=2000,
                kpt_type='superpoint')

            test_db = HPacthes(root_dir=args.data,
                               name=dataset,
                               split=split,
                               transform=test_tf)

            test_sampler = DistributedARBatchSampler(
                data_source=test_db,
                batch_size=data_config.getint("test_batch_size"),
                num_replicas=world_size,
                rank=rank,
                drop_last=True,
                shuffle=False)

            test_dl = torch.utils.data.DataLoader(test_db,
                                                  batch_sampler=test_sampler,
                                                  collate_fn=iss_collate_fn,
                                                  pin_memory=True,
                                                  num_workers=0,
                                                  shuffle=False)

            log_debug('{%s}: Feature Extraction %s...', dataset, split)

            for it, batch in tqdm(enumerate(test_dl), total=len(test_dl)):
                with torch.no_grad():

                    # Upload batch
                    img1_path, img2_path = batch["img1_path"][0], batch[
                        "img2_path"][0]

                    scores1 = batch["scores1"][0]
                    scores2 = batch["scores2"][0]

                    batch = {
                        k: batch[k].cuda(device=varargs["device"],
                                         non_blocking=True)
                        for k in HP_INPUTS
                    }

                    # Run Image 1
                    _, pred1 = model(img=batch["img1"],
                                     kpts=batch["kpts1"],
                                     do_prediction=True,
                                     do_augmentaton=False)
                    distributed.barrier()

                    kpts1, _ = batch["kpts1"].contiguous
                    pred1, _ = pred1["local_pred"].contiguous

                    kpts1 = kpts1.squeeze(0)
                    pred1 = pred1.squeeze(0)

                    with open(img1_path + ".npz", 'wb') as output_file:
                        np.savez(output_file,
                                 keypoints=kpts1.cpu().numpy(),
                                 descriptors=pred1.cpu().numpy(),
                                 scores=scores1)

                    # Run Image 2
                    _, pred2 = model(img=batch["img2"],
                                     kpts=batch["kpts2"],
                                     do_prediction=True,
                                     do_augmentaton=False)
                    distributed.barrier()

                    kpts2, _ = batch["kpts2"].contiguous
                    pred2, _ = pred2["local_pred"].contiguous

                    kpts2 = kpts2.squeeze(0)
                    pred2 = pred2.squeeze(0)

                    with open(img2_path + ".npz", 'wb') as output_file:
                        np.savez(output_file,
                                 keypoints=kpts2.cpu().numpy(),
                                 descriptors=pred2.cpu().numpy(),
                                 scores=scores2)

            log_debug('{%s}: Run Evalution %s...', dataset, split)

            # run evaluation
            config = {'correctness_threshold': 3, 'max_mma_threshold': 10}

            H_estimation, Precision, Recall, MMA = run_descriptor_evaluation(
                config, test_dl)

            # compute F score
            F_score = 2 * ((Precision * Recall) / (Precision + Recall + 1e-10))

            Avg_F_score += 0.5 * F_score

            np.set_printoptions(precision=3)

            log_info('{%s}: H_estimation_%s = %s', dataset, split,
                     format(H_estimation, '.3f'))
            log_info('{%s}: Precision_%s    = %s', dataset, split,
                     format(Precision, '.3f'))
            log_info('{%s}: Recall_%s       = %s', dataset, split,
                     format(Recall, '.3f'))
            log_info('{%s}: MMA_%s          = %s', dataset, split, MMA)
            log_info('{%s}: F_score_%s      = %s', dataset, split,
                     format(F_score, '.3f'))

        log_info('{%s}: Running time     = %s', dataset,
                 htime(time.time() - start))
        log_info('{%s}: Avg_F_score      = %s', dataset,
                 format(Avg_F_score, '.3f'))

    return Avg_F_score
Exemple #19
0
def main():
    args = parser.parse_args()

    # check if there are unknown datasets
    for dataset in args.datasets.split(','):
        if dataset not in datasets_names:
            raise ValueError(
                'Unsupported or unknown dataset: {}!'.format(dataset))

    # check if test dataset are downloaded
    # and download if they are not
    download_train(get_data_root())
    download_test(get_data_root())

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network
    # pretrained networks (downloaded automatically)
    print(">> Loading network:\n>>>> '{}'".format(args.network))
    state = load_url(PRETRAINED[args.network],
                     model_dir=os.path.join(get_data_root(), 'networks'))
    # parsing net params from meta
    # architecture, pooling, mean, std required
    # the rest has default values, in case that is doesnt exist
    net_params = {}
    net_params['architecture'] = state['meta']['architecture']
    net_params['pooling'] = state['meta']['pooling']
    net_params['local_whitening'] = state['meta'].get('local_whitening', False)
    net_params['regional'] = state['meta'].get('regional', False)
    net_params['whitening'] = state['meta'].get('whitening', False)
    net_params['mean'] = state['meta']['mean']
    net_params['std'] = state['meta']['std']
    net_params['pretrained'] = False
    # network initialization
    net = init_network(net_params)
    net.load_state_dict(state['state_dict'])

    print(">>>> loaded network: ")
    print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = list(eval(args.multiscale))
    print(">>>> Evaluating scales: {}".format(ms))

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()

    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # evaluate on test datasets
    datasets = args.datasets.split(',')
    for dataset in datasets:
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
        images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
        qimages = [cfg['qim_fname'](cfg, i) for i in range(cfg['nq'])]
        try:
            bbxs = [tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])]
        except:
            bbxs = None  # for holidaysmanrot and copydays

        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        vecs = extract_vectors(net, images, args.image_size, transform, ms=ms)
        print('>> {}: query images...'.format(dataset))
        qvecs = extract_vectors(net,
                                qimages,
                                args.image_size,
                                transform,
                                bbxs=bbxs,
                                ms=ms)

        print('>> {}: Evaluating...'.format(dataset))

        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()

        # search, rank, and print
        scores = np.dot(vecs.T, qvecs)
        ranks = np.argsort(-scores, axis=0)

        top_k = 100
        ranks_fnames_qs = []
        for q_id in range(len(cfg["qimlist"])):
            ranks_q = list(ranks[:top_k, q_id])
            ranks_fname_per_q = []
            for img_id in ranks_q:
                ranks_fname_per_q.append(cfg["imlist"][img_id])
            ranks_fnames_qs.append(ranks_fname_per_q)

        compute_map_and_print(dataset, ranks, cfg['gnd'])
        compute_map_and_print_top_k(dataset, ranks_fnames_qs, cfg['gnd'],
                                    cfg["imlist"])

        sys.exit()
        with open(dataset + "_gl18_tl_resnet101_gem_w_m.pkl", "wb") as f:
            data = {"ranks": ranks, "db_images": images, "q_images": qimages}
            pickle.dump(data, f)

        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))
def test(datasets, net):
    print('>> Evaluating network on test datasets...')

    # for testing we use image size of max 1024
    image_size = 1024

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()
    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    if args.test_whiten:
        start = time.time()

        print('>> {}: Learning whitening...'.format(args.test_whiten))

        # loading db
        db_root = os.path.join(get_data_root(), 'train', args.test_whiten)
        ims_root = os.path.join(db_root, 'ims')
        db_fn = os.path.join(db_root, '{}-whiten.pkl'.format(args.test_whiten))
        with open(db_fn, 'rb') as f:
            db = pickle.load(f)
        images = [
            cid2filename(db['cids'][i], ims_root)
            for i in range(len(db['cids']))
        ]

        # extract whitening vectors
        print('>> {}: Extracting...'.format(args.test_whiten))
        wvecs = extract_vectors(net,
                                images,
                                image_size,
                                transform,
                                print_freq=10,
                                batchsize=20)  # implemented with torch.no_grad

        # learning whitening
        print('>> {}: Learning...'.format(args.test_whiten))
        wvecs = wvecs.numpy()
        m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
        Lw = {'m': m, 'P': P}

        print('>> {}: elapsed time: {}'.format(args.test_whiten,
                                               htime(time.time() - start)))
    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.test_datasets.split(',')
    for dataset in datasets:
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
        images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
        qimages = [cfg['qim_fname'](cfg, i) for i in range(cfg['nq'])]
        if dataset == 'cdvs_test_retrieval':
            bbxs = None
        else:
            bbxs = None

        print('>> {}: database images...'.format(dataset))
        if args.pool == 'gem':
            ms = [1, 1 / 2**(1 / 2), 1 / 2]
        else:
            ms = [1]
        if len(ms) > 1 and net.meta['pooling'] == 'gem' and not net.meta[
                'regional'] and not net.meta['whitening']:
            msp = net.pool.p.item()
            print(">> Set-up multiscale:")
            print(">>>> ms: {}".format(ms))
            print(">>>> msp: {}".format(msp))
        else:
            msp = 1
        vecs = extract_vectors(net,
                               images,
                               image_size,
                               transform,
                               bbxs,
                               ms=ms,
                               msp=msp,
                               print_freq=1000,
                               batchsize=1)  # implemented with torch.no_grad
        print('>> {}: query images...'.format(dataset))
        qvecs = extract_vectors(net,
                                qimages,
                                image_size,
                                transform,
                                bbxs,
                                ms=ms,
                                msp=msp,
                                print_freq=1000,
                                batchsize=1)  # implemented with torch.no_grad

        print('>> {}: Evaluating...'.format(dataset))

        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()

        # search, rank, and print
        scores = np.dot(vecs.T, qvecs)
        ranks = np.argsort(-scores, axis=0)
        if dataset == 'cdvs_test_retrieval':
            compute_map_and_print(dataset, ranks, cfg['gnd_id'])
        else:
            compute_map_and_print(dataset, ranks, cfg['gnd'])

        if Lw is not None:
            # whiten the vectors
            vecs_lw = whitenapply(vecs, Lw['m'], Lw['P'])
            qvecs_lw = whitenapply(qvecs, Lw['m'], Lw['P'])

            # search, rank, and print
            scores = np.dot(vecs_lw.T, qvecs_lw)
            ranks = np.argsort(-scores, axis=0)
            compute_map_and_print(dataset + ' + whiten', ranks, cfg['gnd'])

        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))
Exemple #21
0
def test(args, config, model, rank=None, world_size=None, **varargs):

    log_debug('Evaluating network on test datasets...')

    # Eval mode
    model.eval()
    data_config = config["dataloader"]

    # Average score
    avg_score = 0.0

    # Evaluate on test datasets
    list_datasets = data_config.getstruct("test_datasets")

    if data_config.get("multi_scale"):
        scales = eval(data_config.get("multi_scale"))
    else:
        scales = [1]

    for dataset in list_datasets:

        start = time.time()

        log_debug('{%s}: Loading Dataset', dataset)

        # Prepare database
        db = ParisOxfordTestDataset(root_dir=path.join(args.data, 'test',
                                                       dataset),
                                    name=dataset)

        batch_size = data_config.getint("test_batch_size")

        with torch.no_grad():
            """ Paris and Oxford are :
                    1 - resized to a ratio of desired max size, after bbx cropping 
                    2 - normalized after that
                    3 - not flipped and not scaled (!! important for evaluation)
                
            """
            # Prepare query loader
            log_debug('{%s}: Extracting descriptors for query images', dataset)

            query_tf = ISSTestTransform(
                shortest_size=data_config.getint("test_shortest_size"),
                longest_max_size=data_config.getint("test_longest_max_size"),
                random_scale=data_config.getstruct("random_scale"))

            query_data = ISSDataset(root_dir='',
                                    name="query",
                                    images=db['query_names'],
                                    bbx=db['query_bbx'],
                                    transform=query_tf)

            query_sampler = DistributedARBatchSampler(
                data_source=query_data,
                batch_size=data_config.getint("test_batch_size"),
                num_replicas=world_size,
                rank=rank,
                drop_last=True,
                shuffle=False)

            query_dl = torch.utils.data.DataLoader(
                query_data,
                batch_sampler=query_sampler,
                collate_fn=iss_collate_fn,
                pin_memory=True,
                num_workers=data_config.getstruct("num_workers"),
                shuffle=False)

            # Extract query vectors
            qvecs = torch.zeros(varargs["output_dim"], len(query_data)).cuda()

            for it, batch in tqdm(enumerate(query_dl), total=len(query_dl)):

                # Upload batch
                batch = {
                    k: batch[k].cuda(device=varargs["device"],
                                     non_blocking=True)
                    for k in INPUTS
                }

                _, pred = model(**batch,
                                scales=scales,
                                do_prediction=True,
                                do_augmentaton=False)

                distributed.barrier()

                qvecs[:,
                      it * batch_size:(it + 1) * batch_size] = pred["ret_pred"]

                del pred

            # Prepare negative database data loader
            log_debug('{%s}: Extracting descriptors for database images',
                      dataset)

            database_tf = ISSTestTransform(
                shortest_size=data_config.getint("test_shortest_size"),
                longest_max_size=data_config.getint("test_longest_max_size"),
                random_scale=data_config.getstruct("random_scale"))

            database_data = ISSDataset(root_dir='',
                                       name="database",
                                       images=db['img_names'],
                                       transform=database_tf)

            database_sampler = DistributedARBatchSampler(
                data_source=database_data,
                batch_size=data_config.getint("test_batch_size"),
                num_replicas=world_size,
                rank=rank,
                drop_last=True,
                shuffle=False)

            database_dl = torch.utils.data.DataLoader(
                database_data,
                batch_sampler=database_sampler,
                collate_fn=iss_collate_fn,
                pin_memory=True,
                num_workers=data_config.getstruct("num_workers"),
                shuffle=False)

            # Extract negative pool vectors
            database_vecs = torch.zeros(varargs["output_dim"],
                                        len(database_data)).cuda()

            for it, batch in tqdm(enumerate(database_dl),
                                  total=len(database_dl)):
                # Upload batch

                batch = {
                    k: batch[k].cuda(device=varargs["device"],
                                     non_blocking=True)
                    for k in INPUTS
                }

                _, pred = model(**batch,
                                scales=scales,
                                do_prediction=True,
                                do_augmentaton=False)

                distributed.barrier()

                database_vecs[:, it * batch_size:(it + 1) *
                              batch_size] = pred["ret_pred"]

                del pred

        # Compute dot product scores and ranks on GPU
        # scores = torch.mm(database_vecs.t(), qvecs)
        # scores, scores_indices = torch.sort(-scores, dim=0, descending=False)

        # convert to numpy
        qvecs = qvecs.cpu().numpy()
        database_vecs = database_vecs.cpu().numpy()

        # search, rank, and print
        scores = np.dot(database_vecs.T, qvecs)
        ranks = np.argsort(-scores, axis=0)

        score = compute_map_and_print(dataset, ranks, db['gnd'], log_info)
        log_info('{%s}: Running time = %s', dataset,
                 htime(time.time() - start))

        avg_score += 0.5 * score["mAP"]

    # As Evaluation metrics
    log_info('Average score = %s', avg_score)

    return avg_score
Exemple #22
0
def main():
    args = parser.parse_args()

    # check if there are unknown datasets
    # for dataset in args.datasets.split(','):
    #     if dataset not in datasets_names:
    #         raise ValueError('Unsupported or unknown dataset: {}!'.format(dataset))

    # check if test dataset are downloaded
    # and download if they are not
    # download_train(get_data_root())
    # download_test(get_data_root())

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path

    #datasets = args.datasets.split(',')
    for dataset in datasets_names:
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join('/data', 'test'))
        images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
        qimages = [cfg['qim_fname'](cfg, i) for i in range(cfg['nq'])]

        global_feature_dict, gloabal_feature_size = build_global_feature_dict(
            '/home/ubuntu/DELG/extract/roxf5k.delf.global', 'global_features')

        # # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        vecs = extract_feature(global_feature_dict, images,
                               gloabal_feature_size)
        print('>> {}: query images...'.format(dataset))
        qvecs = extract_feature(global_feature_dict, qimages,
                                gloabal_feature_size)
        print('>> {}: Evaluating...'.format(dataset))

        # search, rank, and print
        # using cosine similarity of two vectors
        scores = np.dot(vecs.T, qvecs)
        ranks = np.argsort(-scores, axis=0)

        compute_map_and_print(dataset, ranks, cfg['gnd'])

        feature_location, feature_descriptor = build_local_feature_dict(
            '/home/ubuntu/DELG/extract/roxf5k.delf.local')
        new_ranks = []  #np.empty_like(ranks)
        # for i, qimage in enumerate(qimages):
        #     new_ranks[:, i] = RerankByGeometricVerification(i, ranks[:, i], scores[:, i], qimage,
        #                                       images, feature_location,
        #                                       feature_descriptor, [])

        from functools import partial
        re_rank_func = partial(RerankByGeometricVerification,
                               input_ranks=ranks,
                               initial_scores=scores,
                               query_name=qimages,
                               index_names=images,
                               feature_location=feature_location,
                               feature_descriptor=feature_descriptor,
                               junk_ids=[])

        new_ranks = p_map(re_rank_func, range(len(qimages)))

        new_ranks = np.concatenate(new_ranks, axis=0)

        compute_map_and_print(dataset, new_ranks, cfg['gnd'])

        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))
def main():
    args = parser.parse_args()

    # check if there are unknown datasets
    for dataset in args.datasets.split(','):
        if dataset not in datasets_names:
            raise ValueError(
                'Unsupported or unknown dataset: {}!'.format(dataset))

    # check if test dataset are downloaded
    # and download if they are not
    download_train(get_data_root())
    download_test(get_data_root())

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path
    if args.network_path is not None:

        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        if args.network_path in PRETRAINED:
            # pretrained networks (downloaded automatically)
            state = load_url(PRETRAINED[args.network_path],
                             model_dir=os.path.join(get_data_root(),
                                                    'networks'))
        else:
            # fine-tuned network from path
            state = torch.load(args.network_path)

        # parsing net params from meta
        # architecture, pooling, mean, std required
        # the rest has default values, in case that is doesnt exist
        net_params = {}
        net_params['architecture'] = state['meta']['architecture']
        net_params['pooling'] = state['meta']['pooling']
        net_params['local_whitening'] = state['meta'].get(
            'local_whitening', False)
        net_params['regional'] = state['meta'].get('regional', False)
        net_params['whitening'] = state['meta'].get('whitening', False)
        net_params['mean'] = state['meta']['mean']
        net_params['std'] = state['meta']['std']
        net_params['pretrained'] = False

        # load network
        net = init_network(net_params)
        net.load_state_dict(state['state_dict'])

        # if whitening is precomputed
        if 'Lw' in state['meta']:
            net.meta['Lw'] = state['meta']['Lw']

        print(">>>> loaded network: ")
        print(net.meta_repr())

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:

        # parse off-the-shelf parameters
        offtheshelf = args.network_offtheshelf.split('-')
        net_params = {}
        net_params['architecture'] = offtheshelf[0]
        net_params['pooling'] = offtheshelf[1]
        net_params['local_whitening'] = 'lwhiten' in offtheshelf[2:]
        net_params['regional'] = 'reg' in offtheshelf[2:]
        net_params['whitening'] = 'whiten' in offtheshelf[2:]
        net_params['pretrained'] = True

        # load off-the-shelf network
        print(">> Loading off-the-shelf network:\n>>>> '{}'".format(
            args.network_offtheshelf))
        net = init_network(net_params)
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = list(eval(args.multiscale))
    if len(ms) > 1 and net.meta['pooling'] == 'gem' and not net.meta[
            'regional'] and not net.meta['whitening']:
        msp = net.pool.p.item()
        print(">> Set-up multiscale:")
        print(">>>> ms: {}".format(ms))
        print(">>>> msp: {}".format(msp))
    else:
        msp = 1

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()

    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    if args.whitening is not None:
        start = time.time()

        if 'Lw' in net.meta and args.whitening in net.meta['Lw']:

            print('>> {}: Whitening is precomputed, loading it...'.format(
                args.whitening))

            if len(ms) > 1:
                Lw = net.meta['Lw'][args.whitening]['ms']
            else:
                Lw = net.meta['Lw'][args.whitening]['ss']

        else:

            # if we evaluate networks from path we should save/load whitening
            # not to compute it every time
            if args.network_path is not None:
                whiten_fn = args.network_path + '_{}_whiten'.format(
                    args.whitening)
                if len(ms) > 1:
                    whiten_fn += '_ms'
                whiten_fn += '.pth'
            else:
                whiten_fn = None

            if whiten_fn is not None and os.path.isfile(whiten_fn):
                print('>> {}: Whitening is precomputed, loading it...'.format(
                    args.whitening))
                Lw = torch.load(whiten_fn)

            else:
                print('>> {}: Learning whitening...'.format(args.whitening))

                # loading db
                db_root = os.path.join(get_data_root(), 'train',
                                       args.whitening)
                ims_root = os.path.join(db_root, 'ims')
                db_fn = os.path.join(db_root,
                                     '{}-whiten.pkl'.format(args.whitening))
                with open(db_fn, 'rb') as f:
                    db = pickle.load(f)
                images = [
                    cid2filename(db['cids'][i], ims_root)
                    for i in range(len(db['cids']))
                ]

                # extract whitening vectors
                print('>> {}: Extracting...'.format(args.whitening))
                wvecs = extract_vectors(net,
                                        images,
                                        args.image_size,
                                        transform,
                                        ms=ms,
                                        msp=msp)

                # learning whitening
                print('>> {}: Learning...'.format(args.whitening))
                wvecs = wvecs.numpy()
                m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
                Lw = {'m': m, 'P': P}

                # saving whitening if whiten_fn exists
                if whiten_fn is not None:
                    print('>> {}: Saving to {}...'.format(
                        args.whitening, whiten_fn))
                    torch.save(Lw, whiten_fn)

        print('>> {}: elapsed time: {}'.format(args.whitening,
                                               htime(time.time() - start)))

    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.datasets.split(',')
    for dataset in datasets:
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        images = get_imlist("E:\\PycharmProjects\\image-retrieval\\holiday2\\")
        names = []
        for i, img_path in enumerate(images):
            img_name = os.path.split(img_path)[1]
            print(img_name)
            names.append(img_name)
        # prepare config structure for the test dataset
        # cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
        # images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
        # try:
        #     bbxs = [tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])]
        # except:
        #     bbxs = None  # for holidaysmanrot and copydays

        # names = []
        # for i, img_path in enumerate(images):
        #     img_name = os.path.split(img_path)[1]
        #     print(img_name)
        #     names.append(img_name)

        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        vecs = extract_vectors(net,
                               images,
                               args.image_size,
                               transform,
                               ms=ms,
                               msp=msp)

        # convert to numpy
        vecs = vecs.numpy()
        vecs = vecs.T
        print("--------------------------------------------------")
        print("      writing feature extraction results ...")
        print("--------------------------------------------------")
        output = "gem_res_holiday_3.h5"
        h5f = h5py.File(output, 'w')
        h5f.create_dataset('dataset_1', data=vecs)
        h5f.create_dataset('dataset_2', data=np.string_(names))
        h5f.close()

        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))
Exemple #24
0
def main():
    args = parser.parse_args()

    # check if there are unknown datasets
    for scene in args.scenes.split(','):
        if scene not in datasets_names:
            raise ValueError('Unsupported or unknown scene: {}!'.format(scene))

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network
    # pretrained networks (downloaded automatically)
    print(">> Loading network:\n>>>> '{}'".format(args.network))
    state = load_url(PRETRAINED[args.network],
                     model_dir=os.path.join(get_data_root(), 'networks'))
    # parsing net params from meta
    # architecture, pooling, mean, std required
    # the rest has default values, in case that is doesnt exist
    net_params = {}
    net_params['architecture'] = state['meta']['architecture']
    net_params['pooling'] = state['meta']['pooling']
    net_params['local_whitening'] = state['meta'].get('local_whitening', False)
    net_params['regional'] = state['meta'].get('regional', False)
    net_params['whitening'] = state['meta'].get('whitening', False)
    net_params['mean'] = state['meta']['mean']
    net_params['std'] = state['meta']['std']
    net_params['pretrained'] = False
    # network initialization
    net = init_network(net_params)
    net.load_state_dict(state['state_dict'])

    print(">>>> loaded network: ")
    print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = list(eval(args.multiscale))
    print(">>>> Evaluating scales: {}".format(ms))

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()

    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # evaluate on test datasets
    scenes = args.scenes.split(',')
    for scene in scenes:
        start = time.time()

        print('>> {}: Extracting...'.format(scene))
        img_path = osp.join(args.data_path, scene, "images")
        images = [
            osp.join(img_path, fname) for fname in os.listdir(img_path)
            if fname[-3:].lower() in ['jpg', 'png']
        ]

        # extract vectors
        vecs = extract_vectors(net, images, args.image_size, transform, ms=ms)

        print('>> {}: Evaluating...'.format(scene))

        # convert to numpy
        vecs = vecs.numpy()

        # search, rank, and print
        scores = np.dot(vecs.T, vecs)
        ranks = np.argsort(-scores, axis=0)

        images = [img.split('/')[-1] for img in images]
        for top_k in list(eval(args.top_n)):
            pairs = []
            for q_id in range(len(images)):
                img_q = images[q_id]
                pairs_per_q = [
                    " ".join([img_q, images[db_id]])
                    for db_id in list(ranks[1:top_k + 1, q_id])
                ]
                pairs += pairs_per_q
            with open(
                    osp.join(args.data_path, scene,
                             "image_pairs_" + str(top_k) + ".txt"), "w") as f:
                for pair in pairs:
                    f.write(pair + "\n")

        print('>> {}: elapsed time: {}'.format(scene,
                                               htime(time.time() - start)))
Exemple #25
0
def test(datasets, net, wandb_enabled=False, epoch=-1):
    
    global global_step

    print('>> Evaluating network on test datasets...')

    # for testing we use image size of max 1024
    image_size = 1024

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()
    # set up the transform
    normalize = transforms.Normalize(
        mean=net.meta['mean'],
        std=net.meta['std']
    )
    transform = transforms.Compose([
        transforms.ToTensor(),
        normalize
    ])

    # compute whitening
    if args.test_whiten:
        start = time.time()

        print('>> {}: Learning whitening...'.format(args.test_whiten))

        # loading db
        db_root = os.path.join(get_data_root(), 'train', args.test_whiten)
        ims_root = os.path.join(db_root, 'ims')
        db_fn = os.path.join(db_root, '{}-whiten.pkl'.format(args.test_whiten))
        with open(db_fn, 'rb') as f:
            db = pickle.load(f)
        images = [cid2filename(db['cids'][i], ims_root) for i in range(len(db['cids']))]

        # extract whitening vectors
        print('>> {}: Extracting...'.format(args.test_whiten))
        wvecs = extract_vectors(net, images, image_size, transform)  # implemented with torch.no_grad
        
        # learning whitening 
        print('>> {}: Learning...'.format(args.test_whiten))
        wvecs = wvecs.numpy()
        m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
        Lw = {'m': m, 'P': P}

        print('>> {}: elapsed time: {}'.format(args.test_whiten, htime(time.time()-start)))
    else:
        Lw = None

    # evaluate on test datasets
    datasets = args.test_datasets.split(',')
    for dataset in datasets: 
        start = time.time()

        print('>> {}: Extracting...'.format(dataset))

        # prepare config structure for the test dataset
        cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
        images = [cfg['im_fname'](cfg,i) for i in range(cfg['n'])]
        qimages = [cfg['qim_fname'](cfg,i) for i in range(cfg['nq'])]
        bbxs = [tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])]
        
        # extract database and query vectors
        print('>> {}: database images...'.format(dataset))
        vecs = extract_vectors(net, images, image_size, transform)  # implemented with torch.no_grad
        print('>> {}: query images...'.format(dataset))
        qvecs = extract_vectors(net, qimages, image_size, transform, bbxs)  # implemented with torch.no_grad
        
        print('>> {}: Evaluating...'.format(dataset))

        # convert to numpy
        vecs = vecs.numpy()
        qvecs = qvecs.numpy()

        # search, rank, and print
        scores = np.dot(vecs.T, qvecs)
        ranks = np.argsort(-scores, axis=0)
        compute_map_and_print(dataset, ranks, cfg['gnd'], wandb_enabled=wandb_enabled, epoch=epoch, global_step=global_step)
    
        if Lw is not None:
            # whiten the vectors
            vecs_lw  = whitenapply(vecs, Lw['m'], Lw['P'])
            qvecs_lw = whitenapply(qvecs, Lw['m'], Lw['P'])

            # search, rank, and print
            scores = np.dot(vecs_lw.T, qvecs_lw)
            ranks = np.argsort(-scores, axis=0)
            compute_map_and_print(dataset + ' + whiten', ranks, cfg['gnd'], wandb_enabled=wandb_enabled, epoch=epoch, global_step=global_step)
        
        print('>> {}: elapsed time: {}'.format(dataset, htime(time.time()-start)))
            wvecs = np.hstack((vecs, qvecs))
            # learning whitening
            print('>> {}: Learning...'.format(whitening))
            m, P = pcawhitenlearn(wvecs)
            Lw = {'m': m, 'P': P}
            del wvecs
            gc.collect()
            # saving whitening if whiten_fn exists
            if whiten_fn is not None:
                whiten_fn = os.path.join(
                    get_data_root(), 'whiten',
                    'R101_FC_GL_362_IS1024_MS1,0.707,1.414.pth')
                print('>> {}: Saving to {}...'.format(whitening, whiten_fn))
                torch.save(Lw, whiten_fn)
    print('>> {}: elapsed time: {}'.format(whitening,
                                           htime(time.time() - start)))
else:
    Lw = None

#%%
print('>> apply PCA whiten...')
if Lw is not None:
    # whiten the vectors and shrinkage
    split_num = 4
    for i in range(split_num):
        vecs_lw_temp = np.dot(
            Lw['P'],
            vecs[:,
                 int(vecs.shape[1] / split_num *
                     i):int(vecs.shape[1] / split_num * (i + 1))] - Lw['m'])
        if i == 0:
Exemple #27
0
def testOxfordParisHolidays(net, eConfig):

    #datasets = eConfig['test-datasets'].split(',')
    #results = []
    #
    #for dataset in datasets:
    #    results.append((dataset, np.random.rand(1)[0]))
    #
    #return results

    print('>> Evaluating network on test datasets...')

    # for testing we use image size of max 1024
    image_size = 1024

    # setting up the multi-scale parameters
    ms = [1]
    msp = 1
    if (eConfig['multiscale']):
        ms = [1, 1. / math.sqrt(2), 1. / 2]
        if net.meta['pooling'] == 'gem' and net.whiten is None:
            msp = net.pool.p.data.tolist()[0]

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()
    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # compute whitening
    if eConfig['whitening']:

        start = time.time()

        print('>> {}: Learning whitening...'.format(eConfig['test-whiten']))

        # loading db
        db_root = os.path.join(get_data_root(), 'train',
                               eConfig['test-whiten'])
        ims_root = os.path.join(db_root, 'ims')
        db_fn = os.path.join(db_root,
                             '{}-whiten.pkl'.format(eConfig['test-whiten']))
        with open(db_fn, 'rb') as f:
            db = pickle.load(f)
        images = [
            cid2filename(db['cids'][i], ims_root)
            for i in range(len(db['cids']))
        ]

        # extract whitening vectors
        print('>> {}: Extracting...'.format(eConfig['test-whiten']))
        wvecs = extract_vectors(net,
                                images,
                                image_size,
                                transform,
                                ms=ms,
                                msp=msp)

        # learning whitening
        print('>> {}: Learning...'.format(eConfig['test-whiten']))
        wvecs = wvecs.numpy()
        m, P = whitenlearn(wvecs, db['qidxs'], db['pidxs'])
        Lw = {'m': m, 'P': P}

        print('>> {}: elapsed time: {}'.format(eConfig['test-whiten'],
                                               htime(time.time() - start)))

    else:
        Lw = None

    # evaluate on test datasets
    datasets = eConfig['test-datasets'].split(',')
    results = []

    for dataset in datasets:
        start = time.time()

        if (dataset != 'holidays' and dataset != 'rholidays'):
            print('>> {}: Extracting...'.format(dataset))

            # prepare config structure for the test dataset
            cfg = configdataset(dataset, os.path.join(get_data_root(), 'test'))
            images = [cfg['im_fname'](cfg, i) for i in range(cfg['n'])]
            qimages = [cfg['qim_fname'](cfg, i) for i in range(cfg['nq'])]
            bbxs = [tuple(cfg['gnd'][i]['bbx']) for i in range(cfg['nq'])]

            if (dataset == 'oxford105k' or dataset == 'paris106k'):
                images.extend(cfg['distractors'])

            # extract database and query vectors
            print('>> {}: database images...'.format(dataset))
            vecs = extract_vectors(net,
                                   images,
                                   image_size,
                                   transform,
                                   ms=ms,
                                   msp=msp)
            print('>> {}: query images...'.format(dataset))
            qvecs = extract_vectors(net,
                                    qimages,
                                    image_size,
                                    transform,
                                    bbxs,
                                    ms=ms,
                                    msp=msp)
            print('>> {}: Evaluating...'.format(dataset))

            # convert to numpy
            vecs = vecs.numpy()
            qvecs = qvecs.numpy()

            # search, rank, and print
            scores = np.dot(vecs.T, qvecs)
            ranks = np.argsort(-scores, axis=0)
            results.append(
                compute_map_and_print(
                    dataset +
                    ('+ multiscale' if eConfig['multiscale'] else ''), ranks,
                    cfg['gnd']))

            if Lw is not None:
                # whiten the vectors
                vecs_lw = whitenapply(vecs, Lw['m'], Lw['P'])
                qvecs_lw = whitenapply(qvecs, Lw['m'], Lw['P'])

                # search, rank, and print
                scores = np.dot(vecs_lw.T, qvecs_lw)
                ranks = np.argsort(-scores, axis=0)
                results.append(
                    compute_map_and_print(dataset + ' + whiten', ranks,
                                          cfg['gnd']))

        else:
            results.append(testHolidays(net, eConfig, dataset, Lw))

        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))

    return results
def main():
    args = parser.parse_args()

    # check if there are unknown datasets
    for dataset in args.datasets.split(','):
        if dataset not in datasets_names:
            raise ValueError(
                'Unsupported or unknown dataset: {}!'.format(dataset))

    # check if test dataset are downloaded
    # and download if they are not
    # download_train(get_data_root())
    # download_test(get_data_root())

    # setting up the visible GPU
    os.environ['CUDA_VISIBLE_DEVICES'] = args.gpu_id

    # loading network from path
    if args.network_path is not None:

        print(">> Loading network:\n>>>> '{}'".format(args.network_path))
        if args.network_path in PRETRAINED:
            # pretrained networks (downloaded automatically)
            state = load_url(PRETRAINED[args.network_path],
                             model_dir=os.path.join(get_data_root(),
                                                    'networks'))
        else:
            # fine-tuned network from path
            state = torch.load(args.network_path)

        # parsing net params from meta
        # architecture, pooling, mean, std required
        # the rest has default values, in case that is doesnt exist
        net_params = {}
        net_params['architecture'] = state['meta']['architecture']
        net_params['pooling'] = state['meta']['pooling']
        net_params['local_whitening'] = state['meta'].get(
            'local_whitening', False)
        net_params['regional'] = state['meta'].get('regional', False)
        net_params['whitening'] = state['meta'].get('whitening', False)
        net_params['mean'] = state['meta']['mean']
        net_params['std'] = state['meta']['std']
        net_params['pretrained'] = False

        # load network
        net = init_network(net_params)
        net.load_state_dict(state['state_dict'])

        # if whitening is precomputed
        if 'Lw' in state['meta']:
            net.meta['Lw'] = state['meta']['Lw']

        print(">>>> loaded network: ")
        print(net.meta_repr())

    # loading offtheshelf network
    elif args.network_offtheshelf is not None:

        # parse off-the-shelf parameters
        offtheshelf = args.network_offtheshelf.split('-')
        net_params = {}
        net_params['architecture'] = offtheshelf[0]
        net_params['pooling'] = offtheshelf[1]
        net_params['local_whitening'] = 'lwhiten' in offtheshelf[2:]
        net_params['regional'] = 'reg' in offtheshelf[2:]
        net_params['whitening'] = 'whiten' in offtheshelf[2:]
        net_params['pretrained'] = True

        # load off-the-shelf network
        print(">> Loading off-the-shelf network:\n>>>> '{}'".format(
            args.network_offtheshelf))
        net = init_network(net_params)
        print(">>>> loaded network: ")
        print(net.meta_repr())

    # setting up the multi-scale parameters
    ms = list(eval(args.multiscale))
    if len(ms) > 1 and net.meta['pooling'] == 'gem' and not net.meta[
            'regional'] and not net.meta['whitening']:
        msp = net.pool.p.item()
        print(">> Set-up multiscale:")
        print(">>>> ms: {}".format(ms))
        print(">>>> msp: {}".format(msp))
    else:
        msp = 1

    # moving network to gpu and eval mode
    net.cuda()
    net.eval()

    # set up the transform
    normalize = transforms.Normalize(mean=net.meta['mean'],
                                     std=net.meta['std'])
    transform = transforms.Compose([transforms.ToTensor(), normalize])

    # evaluate on test datasets
    datasets = args.datasets.split(',')
    for dataset in datasets:
        start = time.time()
        print('>> {}: Extracting...'.format(dataset))

        print('>> Prepare data information...')
        index_file_path = os.path.join(get_data_root(), 'index.csv')
        index_mark_path = os.path.join(get_data_root(), 'index_mark.csv')
        index_miss_path = os.path.join(get_data_root(), 'index_miss.csv')
        test_file_path = os.path.join(get_data_root(), 'test.csv')
        test_mark_path = os.path.join(get_data_root(), 'test_mark.csv')
        test_mark_add_path = os.path.join(get_data_root(), 'test_mark_add.csv')
        test_miss_path = os.path.join(get_data_root(), 'test_miss.csv')
        if dataset == 'google-landmarks-dataset':
            index_img_path = os.path.join(get_data_root(), 'index')
            test_img_path = os.path.join(get_data_root(),
                                         'google-landmarks-dataset-test')
        elif dataset == 'google-landmarks-dataset-resize':
            index_img_path = os.path.join(get_data_root(),
                                          'resize_index_image')
            test_img_path = os.path.join(get_data_root(), 'resize_test_image')
        if not (os.path.isfile(index_mark_path)
                or os.path.isfile(index_miss_path)):
            clear_no_exist(index_file_path, index_mark_path, index_miss_path,
                           index_img_path)
        if not (os.path.isfile(test_mark_path)
                or os.path.isfile(test_miss_path)):
            clear_no_exist(test_file_path, test_mark_path, test_miss_path,
                           test_img_path)

        print('>> load index image path...')
        retrieval_other_dataset = '/home/iap205/Datasets/google-landmarks-dataset-resize'
        csvfile = open(index_mark_path, 'r')
        csvreader = csv.reader(csvfile)
        images = []
        miss, add = 0, 0
        for line in csvreader:
            if line[0] == '1':
                images.append(os.path.join(index_img_path, line[1] + '.jpg'))
            elif line[0] == '0':
                retrieval_img_path = os.path.join(retrieval_other_dataset,
                                                  'resize_index_image',
                                                  line[1] + '.jpg')
                if os.path.isfile(retrieval_img_path):
                    images.append(retrieval_img_path)
                    add += 1
                miss += 1
        csvfile.close()
        print(
            '>>>> index image miss: {}, supplement: {}, still miss: {}'.format(
                miss, add, miss - add))

        print('>> load query image path...')
        csvfile = open(test_mark_path, 'r')
        csvreader = csv.reader(csvfile)
        savefile = open(test_mark_add_path, 'w')
        save_writer = csv.writer(savefile)
        qimages = []
        miss, add = 0, 0
        for line in csvreader:
            if line[0] == '1':
                qimages.append(os.path.join(test_img_path, line[1] + '.jpg'))
                save_writer.writerow(line)
            elif line[0] == '0':
                retrieval_img_path = os.path.join(retrieval_other_dataset,
                                                  'resize_test_image',
                                                  line[1] + '.jpg')
                if os.path.isfile(retrieval_img_path):
                    qimages.append(retrieval_img_path)
                    save_writer.writerow(['1', line[1]])
                    add += 1
                else:
                    save_writer.writerow(line)
                miss += 1
        csvfile.close()
        savefile.close()
        print(
            '>>>> test image miss: {}, supplement: {}, still miss: {}'.format(
                miss, add, miss - add))

        # extract index vectors
        print('>> {}: index images...'.format(dataset))
        split_num = 6
        extract_num = int(len(images) / split_num)
        num_list = list(range(0, len(images), extract_num))
        num_list.append(len(images))

        # k = 0
        # print('>>>> extract part {} of {}'.format(k, split_num-1))
        # vecs = extract_vectors(net, images[num_list[k]:num_list[k+1]], args.image_size, transform, ms=ms, msp=msp)
        # vecs = vecs.numpy()
        # print('>>>> save index vecs to pkl...')
        # vecs_file_path = os.path.join(get_data_root(), 'index_vecs{}_of_{}.pkl'.format(k+1, split_num))
        # vecs_file = open(vecs_file_path, 'wb')
        # pickle.dump(vecs[:, num_list[k]:num_list[k+1]], vecs_file)
        # vecs_file.close()
        # print('>>>> index_vecs{}_of_{}.pkl save done...'.format(k+1, split_num))

        for i in range(split_num):
            # vecs_temp = np.loadtxt(open(os.path.join(get_data_root(), 'index_vecs{}_of_{}.csv'.format(i+1, split_num)), "rb"),
            #                        delimiter=",", skiprows=0)
            with open(
                    os.path.join(
                        get_data_root(),
                        'index_vecs{}_of_{}.pkl'.format(i + 1, split_num)),
                    'rb') as f:
                vecs_temp = pickle.load(f)
            if i == 0:
                vecs = vecs_temp
            else:
                vecs = np.hstack((vecs, vecs_temp[:, :]))
            del vecs_temp
            gc.collect()
            print('\r>>>> index_vecs{}_of_{}.pkl load done...'.format(
                i + 1, split_num),
                  end='')
        print('')

        # extract query vectors
        print('>> {}: query images...'.format(dataset))
        split_num = 1
        extract_num = int(len(qimages) / split_num)
        num_list = list(range(0, len(qimages), extract_num))
        num_list.append(len(qimages))
        # k = 0
        # print('>>>> extract part {} of {}'.format(k, split_num - 1))
        # qvecs = extract_vectors(net, qimages[num_list[k]:num_list[k + 1]], args.image_size, transform, ms=ms, msp=msp)
        # qvecs = qvecs.numpy()
        # for i in range(split_num):
        #     qvecs_file_path = os.path.join(get_data_root(), 'test_vecs{}_of_{}.pkl'.format(i+1, split_num))
        #     qvecs_file = open(qvecs_file_path, 'wb')
        #     pickle.dump(qvecs[:, num_list[i]:num_list[i+1]], qvecs_file)
        #     qvecs_file.close()
        #     print('\r>>>> test_vecs{}_of_{}.pkl save done...'.format(i+1, split_num), end='')
        # print('')

        for i in range(split_num):
            # qvecs_temp = np.loadtxt(open(os.path.join(get_data_root(), 'test_vecs{}_of_{}.csv'.format(i+1, split_num)), "rb"),
            #                         delimiter=",", skiprows=0)
            with open(
                    os.path.join(
                        get_data_root(),
                        'test_vecs{}_of_{}.pkl'.format(i + 1, split_num)),
                    'rb') as f:
                qvecs_temp = pickle.load(f)
            if i == 0:
                qvecs = qvecs_temp
            else:
                qvecs = np.hstack((qvecs, qvecs_temp[:, :]))
            del qvecs_temp
            gc.collect()
            print('\r>>>> test_vecs{}_of_{}.pkl load done...'.format(
                i + 1, split_num),
                  end='')
        print('')

        # vecs = np.zeros((2048, 1093278))
        # qvecs = np.zeros((2048, 115921))

        # save vecs to csv file
        # np.savetxt(os.path.join(get_data_root(), 'index_vecs{}_of_{}.csv'.format(k, split_num-1)), vecs, delimiter=',')
        # np.savetxt(os.path.join(get_data_root(), 'test_vecs{}_of_{}.csv'.format(k, split_num-1)), qvecs, delimiter=',')

        # compute whitening
        if args.whitening is not None:
            start = time.time()
            if 'Lw' in net.meta and args.whitening in net.meta['Lw']:
                print('>> {}: Whitening is precomputed, loading it...'.format(
                    args.whitening))
                if len(ms) > 1:
                    Lw = net.meta['Lw'][args.whitening]['ms']
                else:
                    Lw = net.meta['Lw'][args.whitening]['ss']
            else:
                # if we evaluate networks from path we should save/load whitening
                # not to compute it every time
                if args.network_path is not None:
                    whiten_fn = args.network_path + '_{}_whiten'.format(
                        args.whitening)
                    if len(ms) > 1:
                        whiten_fn += '_ms'
                    whiten_fn += '.pth'
                else:
                    whiten_fn = None
                if whiten_fn is not None and os.path.isfile(whiten_fn):
                    print('>> {}: Whitening is precomputed, loading it...'.
                          format(args.whitening))
                    Lw = torch.load(whiten_fn)
                else:
                    print('>> {}: Learning whitening...'.format(
                        args.whitening))
                    # extract whitening vectors
                    print('>> {}: Extracting...'.format(args.whitening))
                    wvecs = vecs
                    # learning whitening
                    print('>> {}: Learning...'.format(args.whitening))
                    m, P = pcawhitenlearn(wvecs)
                    Lw = {'m': m, 'P': P}
                    # saving whitening if whiten_fn exists
                    if whiten_fn is not None:
                        print('>> {}: Saving to {}...'.format(
                            args.whitening, whiten_fn))
                        torch.save(Lw, whiten_fn)
            print('>> {}: elapsed time: {}'.format(args.whitening,
                                                   htime(time.time() - start)))
        else:
            Lw = None

        print('>> apply PCAwhiten...')
        if Lw is not None:
            # whiten the vectors and shrinkage
            vecs = whitenapply(vecs, Lw['m'], Lw['P'])
            qvecs = whitenapply(qvecs, Lw['m'], Lw['P'])

        print('>>>> save index PCAwhiten vecs to pkl...')
        split_num = 6
        extract_num = int(len(images) / split_num)
        num_list = list(range(0, len(images), extract_num))
        num_list.append(len(images))
        for i in range(split_num):
            vecs_file_path = os.path.join(
                get_data_root(),
                'index_PCAwhiten_vecs{}_of_{}.pkl'.format(i + 1, split_num))
            vecs_file = open(vecs_file_path, 'wb')
            pickle.dump(vecs[:, num_list[i]:num_list[i + 1]], vecs_file)
            vecs_file.close()
            print(
                '\r>>>> index_PCAwhiten_vecs{}_of_{}.pkl save done...'.format(
                    i + 1, split_num),
                end='')
        print('')

        print('>>>> save test PCAwhiten vecs to pkl...')
        split_num = 1
        extract_num = int(len(qimages) / split_num)
        num_list = list(range(0, len(qimages), extract_num))
        num_list.append(len(images))
        for i in range(split_num):
            qvecs_file_path = os.path.join(
                get_data_root(),
                'test_PCAwhiten_vecs{}_of_{}.pkl'.format(i + 1, split_num))
            qvecs_file = open(qvecs_file_path, 'wb')
            pickle.dump(qvecs[:, num_list[i]:num_list[i + 1]], qvecs_file)
            qvecs_file.close()
            print('\r>>>> test_PCAwhiten_vecs{}_of_{}.pkl save done...'.format(
                i + 1, split_num),
                  end='')
        print('')

        print('>>>> load index PCAwhiten vecs from pkl...')
        for i in range(split_num):
            with open(
                    os.path.join(
                        get_data_root(),
                        'index_PCAwhiten_vecs{}_of_{}.pkl'.format(
                            i + 1, split_num)), 'rb') as f:
                vecs_temp = pickle.load(f)
            if i == 0:
                vecs = vecs_temp
            else:
                vecs = np.hstack((vecs, vecs_temp[:, :]))
            del vecs_temp
            gc.collect()
            print(
                '\r>>>> index_PCAwhiten_vecs{}_of_{}.pkl load done...'.format(
                    i + 1, split_num),
                end='')
        print('')

        print('>>>> load test PCAwhiten vecs from pkl...')
        for i in range(split_num):
            with open(
                    os.path.join(
                        get_data_root(),
                        'test_PCAwhiten_vecs{}_of_{}.pkl'.format(
                            i + 1, split_num)), 'rb') as f:
                qvecs_temp = pickle.load(f)
            if i == 0:
                qvecs = qvecs_temp
            else:
                qvecs = np.hstack((qvecs, qvecs_temp[:, :]))
            del qvecs_temp
            gc.collect()
            print('\r>>>> test_PCAwhiten_vecs{}_of_{}.pkl load done...'.format(
                i + 1, split_num),
                  end='')
        print('')

        # extract principal components and dimension shrinkage
        ratio = 0.8
        vecs = vecs[:int(vecs.shape[0] * ratio), :]
        qvecs = vecs[:int(qvecs.shape[0] * ratio), :]

        print('>> {}: Evaluating...'.format(dataset))
        split_num = 50
        top_num = 100
        vecs_T = np.zeros((vecs.shape[1], vecs.shape[0])).astype('float32')
        vecs_T[:] = vecs.T[:]
        QE_iter = 0
        QE_weight = (np.arange(top_num, 0, -1) / top_num).reshape(
            1, top_num, 1)
        print('>> find {} nearest neighbour...'.format(top_num))
        import faiss  # place it in the file top will cause network load so slowly

        # ranks_top_100 = np.loadtxt(open(os.path.join(get_data_root(), 'ranks_top_{}.csv'.format(top_num)), "rb"),
        #            delimiter=",", skiprows=0).astype('int')

        for iter in range(0, QE_iter + 1):
            if iter != 0:
                # ranks_top_100 = np.ones((100, 115921)).astype('int')
                print('>> Query expansion iteration {}'.format(iter))
                ranks_split = 50
                for i in range(ranks_split):
                    ranks_top_100_split = ranks_top_100[:,
                                                        int(ranks_top_100.
                                                            shape[1] /
                                                            ranks_split * i
                                                            ):int(ranks_top_100
                                                                  .shape[1] /
                                                                  ranks_split *
                                                                  (i + 1))]
                    top_100_vecs = vecs[:,
                                        ranks_top_100_split]  # (2048, 100, query_split_size)
                    qvecs_temp = (top_100_vecs * QE_weight).sum(axis=1)
                    qvecs_temp = qvecs_temp / (np.linalg.norm(
                        qvecs_temp, ord=2, axis=0, keepdims=True) + 1e-6)
                    if i == 0:
                        qvecs = qvecs_temp
                    else:
                        qvecs = np.hstack((qvecs, qvecs_temp))
                    del ranks_top_100_split, top_100_vecs, qvecs_temp
                    gc.collect()
                    print('\r>>>> calculate new query vectors {}/{} done...'.
                          format(i + 1, ranks_split),
                          end='')
                print('')
                qe_iter_qvecs_path = os.path.join(
                    get_data_root(), 'QE_iter{}_qvecs.pkl'.format(iter))
                qe_iter_qvecs_file = open(qe_iter_qvecs_path, 'wb')
                pickle.dump(qvecs, qe_iter_qvecs_file)
                qe_iter_qvecs_file.close()
                print('>>>> QE_iter{}_qvecs.pkl save done...'.format(iter))
                del ranks_top_100
                gc.collect()
            for i in range(split_num):
                # scores = np.dot(vecs.T, qvecs[:, int(qvecs.shape[1]/split_num*i):int(qvecs.shape[1]/split_num*(i+1))])
                # ranks = np.argsort(-scores, axis=0)

                # kNN search
                k = top_num
                index = faiss.IndexFlatL2(vecs.shape[0])
                index.add(vecs_T)
                query_vecs = qvecs[:,
                                   int(qvecs.shape[1] / split_num *
                                       i):int(qvecs.shape[1] / split_num *
                                              (i + 1))]
                qvecs_T = np.zeros((query_vecs.shape[1],
                                    query_vecs.shape[0])).astype('float32')
                qvecs_T[:] = query_vecs.T[:]
                _, ranks = index.search(qvecs_T, k)
                ranks = ranks.T
                if i == 0:
                    ranks_top_100 = ranks[:top_num, :]
                else:
                    ranks_top_100 = np.hstack(
                        (ranks_top_100, ranks[:top_num, :]))
                # del scores, ranks
                del index, query_vecs, qvecs_T, ranks
                gc.collect()
                print('\r>>>> kNN search {} nearest neighbour {}/{} done...'.
                      format(top_num, i + 1, split_num),
                      end='')
            del qvecs
            gc.collect()
            print('')
        del vecs, vecs_T
        gc.collect()

        # save to csv file
        print(">> save to submission.csv file...")
        submission_file = open(os.path.join(get_data_root(), 'submission.csv'),
                               'w')
        writer = csv.writer(submission_file)
        test_mark_file = open(test_mark_add_path, 'r')
        csvreader = csv.reader(test_mark_file)
        cnt = 0
        writer.writerow(['id', 'images'])
        for index, line in enumerate(csvreader):
            (flag, img_name) = line[:2]
            if flag == '1':
                select = []
                for i in range(top_num):
                    select.append(images[int(
                        ranks_top_100[i,
                                      cnt])].split('/')[-1].split('.jpg')[0])
                cnt += 1
                writer.writerow([
                    img_name.split('/')[-1].split('.jpg')[0], ' '.join(select)
                ])
            else:
                # random_list = random.sample(range(0, len(images)), top_num)
                random_list = np.random.choice(len(images),
                                               top_num,
                                               replace=False)
                select = []
                for i in range(top_num):
                    select.append(
                        images[random_list[i]].split('/')[-1].split('.jpg')[0])
                writer.writerow([
                    img_name.split('/')[-1].split('.jpg')[0], ' '.join(select)
                ])
            if cnt % 10 == 0 or cnt == len(qimages):
                print('\r>>>> {}/{} done...'.format(cnt, len(qimages)), end='')
        submission_file.close()
        test_mark_file.close()
        print('')
        print('>> {}: elapsed time: {}'.format(dataset,
                                               htime(time.time() - start)))