123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import numpy as np
- import torch
- import torch.nn as nn
- from torch.autograd import Variable
- import scipy.io
- def extract_feature(model, dataloaders, device, ms=[1]):
- features = torch.FloatTensor()
- model = model.to(device)
- for data in dataloaders:
- img, label = data
- n, c, h, w = img.size()
- ff = torch.FloatTensor(n, 2048).zero_().to(device)
- for i in range(2):
- if i == 1:
- img = fliplr(img)
- input_img = Variable(img.to(device))
- for scale in ms:
- if scale != 1:
- # bicubic is only available in pytorch>= 1.1
- input_img = nn.functional.interpolate(input_img, scale_factor=scale, mode='bicubic',
- align_corners=False)
- _, outputs = model(input_img)
- ff += outputs
- # # norm feature
- fnorm = torch.norm(ff, p=2, dim=1, keepdim=True)
- ff = ff.div(fnorm.expand_as(ff))
- features = torch.cat((features, ff.data.cpu()), 0)
- return features
- def test_evaluate(path, dataset, device):
- result = scipy.io.loadmat(path)
- query_feature = torch.FloatTensor(result['query_f'])
- query_cam = result['query_cam'][0]
- query_label = result['query_label'][0]
- gallery_feature = torch.FloatTensor(result['gallery_f'])
- gallery_cam = result['gallery_cam'][0]
- gallery_label = result['gallery_label'][0]
- query_feature = query_feature.to(device)
- gallery_feature = gallery_feature.to(device)
- CMC = torch.IntTensor(len(gallery_label)).zero_()
- ap = 0.0
- for i in range(len(query_label)):
- ap_tmp, CMC_tmp = evaluate(query_feature[i], query_label[i], query_cam[i], gallery_feature, gallery_label,
- gallery_cam)
- if CMC_tmp[0] == -1:
- continue
- CMC = CMC + CMC_tmp
- ap += ap_tmp
- CMC = CMC.float()
- CMC = CMC / len(query_label) # average CMC
- return CMC[0], CMC[4], CMC[9], ap / len(query_label)
- def evaluate(qf, ql, qc, gf, gl, gc):
- query = qf.view(-1, 1)
- score = torch.mm(gf, query)
- score = score.squeeze(1).cpu()
- score = score.numpy()
- # predict index
- index = np.argsort(score) # from small to large
- index = index[::-1]
- # good index
- query_index = np.argwhere(gl == ql)
- camera_index = np.argwhere(gc == qc)
- good_index = np.setdiff1d(query_index, camera_index, assume_unique=True)
- junk_index1 = np.argwhere(gl == -1)
- junk_index2 = np.intersect1d(query_index, camera_index)
- junk_index = np.append(junk_index2, junk_index1) # .flatten())
- CMC_tmp = compute_mAP(index, good_index, junk_index)
- return CMC_tmp
- def compute_mAP(index, good_index, junk_index):
- ap = 0
- cmc = torch.IntTensor(len(index)).zero_()
- if good_index.size == 0: # if empty
- cmc[0] = -1
- return ap, cmc
- # remove junk_index
- mask = np.in1d(index, junk_index, invert=True)
- index = index[mask]
- # find good_index index
- ngood = len(good_index)
- mask = np.in1d(index, good_index)
- rows_good = np.argwhere(mask == True)
- rows_good = rows_good.flatten()
- cmc[rows_good[0]:] = 1
- for i in range(ngood):
- d_recall = 1.0 / ngood
- precision = (i + 1) * 1.0 / (rows_good[i] + 1)
- if rows_good[i] != 0:
- old_precision = i * 1.0 / rows_good[i]
- else:
- old_precision = 1.0
- ap = ap + d_recall * (old_precision + precision) / 2
- return ap, cmc
- def fliplr(img):
- inv_idx = torch.arange(img.size(3) - 1, -1, -1).long() # N x C x H x W
- img_flip = img.index_select(3, inv_idx)
- return img_flip
|