def search(): st = time.time() n_query = len(queries) print("min..", np.min(queries)) print("max..", np.max(queries)) diffusion = Diffusion(np.vstack([queries, gallery]), args.cache_dir) print("diffusion shape",diffusion.features.shape) # offline type : scipy.sparse.csr.csr_matrix (희소행렬) # offline shape : (5118 ,5118) >> query와 gallery의 합 offline = diffusion.get_offline_results(args.truncation_size, args.kd) # offline.data 안에 nan 값이 존재함 print("offline..", len(offline.data)) print("offline features shape..",offline.shape) offline.data = np.nan_to_num(offline.data, copy=False) # 컬럼별로 확률화(SUM=1), feature=(1-a)(1-aS)의 역행렬 features = preprocessing.normalize(offline, norm="l2", axis=1) print("features..",features.shape) scores = features[:n_query] @ features[n_query:].T np.save("pirsData/scores/"+ args.cate +"_scores.npy", -scores.todense()) print("1> features[:n_query].shape :", features[:n_query].shape) print("2> features[n_query:].shape :", features[n_query:].shape) print("3> scores.shape :", scores.shape) # scores.shape : (55, 5063) = (쿼리, 갤러리) = (row, col) ranks = np.argsort(-scores.todense()) #np.save("pirsData/ranks/"+ args.cate +"_ranks.npy", ranks) print("ranks[0]...\n", ranks[:10,:10]) print("time check...>>>", args.cate,">>>", time.time()-st, ">>>", len(queries))
def search(): n_query = len(queries) diffusion = Diffusion(np.vstack([queries, gallery]), args.cache_dir) offline = diffusion.get_offline_results(args.truncation_size, args.kd) features = preprocessing.normalize(offline, norm="l2", axis=1) scores = features[:n_query] @ features[n_query:].T ranks = np.argsort(-scores.todense()) evaluate(ranks)
def search_old(gamma=3): diffusion = Diffusion(gallery, args.cache_dir) offline = diffusion.get_offline_results(args.truncation_size, args.kd) time0 = time.time() print('[search] 1) k-NN search') sims, ids = diffusion.knn.search(queries, args.kq) sims = sims**gamma qr_num = ids.shape[0] print('[search] 2) linear combination') all_scores = np.empty((qr_num, args.truncation_size), dtype=np.float32) all_ranks = np.empty((qr_num, args.truncation_size), dtype=np.int) for i in tqdm(range(qr_num), desc='[search] query'): scores = sims[i] @ offline[ids[i]] parts = np.argpartition(-scores, args.truncation_size)[:args.truncation_size] ranks = np.argsort(-scores[parts]) all_scores[i] = scores[parts][ranks] all_ranks[i] = parts[ranks] print('[search] search costs {:.2f}s'.format(time.time() - time0)) # 3) evaluation evaluate(all_ranks)
def _infer(model, root_path, test_loader=None, local_val=False): """ 모델과 데이터가 주어졌을 때, 다음과 같은 데이터 구조를 반환하는 함수를 만들어야 합니다. [ [ query_image_id_1, predicted_database_image_id_1 ], [ query_image_id_2, predicted_database_image_id_2 ], ... [ query_image_id_N, predicted_database_image_id_N ] ] README 설명에서처럼 predicted_database_image_id_n 은 query_image_id_n 에 대해 평가셋 이미지 1,...,n-1,n+1,...,N 를 데이터베이스로 간주했을 때에 가장 쿼리와 같은 카테고리를 가질 것으로 예측하는 이미지입니다. 이미지 아이디는 test_loader 에서 extract 되는 첫번째 인자인 data_id 를 사용합니다. Args: model: 이미지를 인풋으로 받아서 feature vector를 반환하는 모델 root_path: 데이터가 저장된 위치 test_loader: 사용되지 않음 local_val: 사용되지 않음 Returns: top1_reference_ids: 위에서 설명한 list 데이터 구조 """ if test_loader is None: test_loader = test_data_loader( root=os.path.join(root_path, 'test_data')) # TODO 모델의 아웃풋을 적당히 가공하고 연산하여 각 query에 대해 매치가 되는 데이터베이스 # TODO 이미지의 ID를 찾는 모듈을 구현 (현재 구현은 베이스라인 - L2 정규화 및 내적으로 가장 # TODO 비슷한 이미지 조회). feats = None data_ids = None s_t = time.time() for idx, data_package in enumerate(test_loader): if local_val: data_id, image, _ = data_package else: data_id, image = data_package image = image.cuda() feat = model(image, extract=True) feat = feat.detach().cpu().numpy() feat = feat / np.linalg.norm(feat, axis=1)[:, np.newaxis] if feats is None: feats = feat else: feats = np.append(feats, feat, axis=0) if data_ids is None: data_ids = data_id else: data_ids = np.append(data_ids, data_id, axis=0) if time.time() - s_t > 10: print('Infer batch {}/{}.'.format(idx + 1, len(test_loader))) diffusion = Diffusion(feats, cache_dir='./cache') offline = diffusion.get_offline_results(n_trunc=1000, kd=50) features = preprocessing.normalize(offline, norm='l2', axis=1) score_matrix = features @ features.T np.fill_diagonal(score_matrix, -np.inf) top1_reference_indices = np.argmax(score_matrix, axis=1) top1_reference_ids = [[ data_ids[idx], data_ids[top1_reference_indices[idx]] ] for idx in range(len(data_ids))] return top1_reference_ids
def main(): arg_parser = argparse.ArgumentParser() arg_parser.add_argument('train_images_path') arg_parser.add_argument('test_images_path') arg_parser.add_argument('predictions_path') args = arg_parser.parse_args() imsize=480 train_path=args.train_images_path test_path=args.test_images_path outfile=args.predictions_path ##read data## data_list=os.listdir(ipath) train_images = get_imlist(train_path) test_images = get_imlist(test_path) ##RAMAC## RAMAC = extract_feature(train_images, 'resnet101', imsize) RAMAC_test = extract_feature(test_images, 'resnet101', imsize) ##UEL## normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) transform_train = transforms.Compose([ transforms.ToPILImage(), transforms.RandomCrop(size=224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), normalize, ]) transform_test = transforms.Compose([ transforms.ToPILImage(), transforms.CenterCrop(224), transforms.ToTensor(), normalize, ]) net = resnet101(pretrained=True,low_dim=128) model_path = './model/UEL.t'#After training UEL net.load_state_dict(torch.load()) imset = DataLoader(path = train_path, transform=transform_test) train_loader = torch.utils.data.DataLoader(imset, batch_size=32, shuffle=False, num_workers=0) UEL = obtainf(net, train_loader) imset = DataLoader(path = test_path, transform=transform_test) test_loader = torch.utils.data.DataLoader(imset, batch_size=32, shuffle=False, num_workers=0) UEL_test = obtainf(net, test_loader) ##GEM## image_size=1024 multiscale='[1, 2**(1/2), 1/2**(1/2)]' state = torch.load('./model/retrievalSfM120k-vgg16-gem-b4dcdc6.pth') 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'] ms = list(eval(multiscale)) msp = net.pool.p.item() 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 ]) GEM = extract_vectors(net,train_images , 480, transform, ms=ms, msp=msp).numpy().T GEM_test = extract_vectors(net,test_images , 480, transform, ms=ms, msp=msp).numpy().T ##Retrieval## feats=np.concatenate((RAMAC,UEL,GEM),axis=1).astype('float32') query_feat=np.concatenate((RAMAC_test, UEL_test,GEM_test),axis=1).astype('float32') ##diffusion## kq, kd = 7, 50 gamma=80 diffusion = Diffusion(feats, '/') offline = diffusion.get_offline_results(1024, kd) print('[search] 1) k-NN search') sims, ids = diffusion.knn.search(query_feat, kq) sims = sims ** gamma qr_num = ids.shape[0] print('[search] 2) linear combination') all_scores = np.empty((qr_num, 7), dtype=np.float32) all_ranks = np.empty((qr_num, 7), dtype=np.int) for i in range(qr_num): scores = sims[i] @ offline[ids[i]] parts = np.argpartition(-scores, 7)[:7] ranks = np.argsort(-scores[parts]) all_scores[i] = scores[parts][ranks] all_ranks[i] = parts[ranks] I = all_ranks ##output## out=pd.DataFrame(list(map(lambda x: x.split('/')[-1].split('.jpg')[0],timages))) out['1']=pd.DataFrame(I)[0].map(lambda x:data_list[x].split('.')[0] ) out['2']=pd.DataFrame(I)[1].map(lambda x:data_list[x].split('.')[0] ) out['3']=pd.DataFrame(I)[2].map(lambda x:data_list[x].split('.')[0] ) out['4']=pd.DataFrame(I)[3].map(lambda x:data_list[x].split('.')[0] ) out['5']=pd.DataFrame(I)[4].map(lambda x:data_list[x].split('.')[0] ) out['6']=pd.DataFrame(I)[5].map(lambda x:data_list[x].split('.')[0] ) out['7']=pd.DataFrame(I)[6].map(lambda x:data_list[x].split('.')[0] ) out.to_csv(outfile,index=None,header=None)