-
Notifications
You must be signed in to change notification settings - Fork 172
/
lfw_eval.py
executable file
·128 lines (104 loc) · 4.03 KB
/
lfw_eval.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
from __future__ import print_function
import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.autograd import Variable
torch.backends.cudnn.bencmark = True
import os,sys,cv2,random,datetime
import argparse
import numpy as np
import zipfile
from dataset import ImageDataset
from matlab_cp2tform import get_similarity_transform_for_cv2
import net_sphere
def alignment(src_img,src_pts):
ref_pts = [ [30.2946, 51.6963],[65.5318, 51.5014],
[48.0252, 71.7366],[33.5493, 92.3655],[62.7299, 92.2041] ]
crop_size = (96, 112)
src_pts = np.array(src_pts).reshape(5,2)
s = np.array(src_pts).astype(np.float32)
r = np.array(ref_pts).astype(np.float32)
tfm = get_similarity_transform_for_cv2(s, r)
face_img = cv2.warpAffine(src_img, tfm, crop_size)
return face_img
def KFold(n=6000, n_folds=10, shuffle=False):
folds = []
base = list(range(n))
for i in range(n_folds):
test = base[i*n/n_folds:(i+1)*n/n_folds]
train = list(set(base)-set(test))
folds.append([train,test])
return folds
def eval_acc(threshold, diff):
y_true = []
y_predict = []
for d in diff:
same = 1 if float(d[2]) > threshold else 0
y_predict.append(same)
y_true.append(int(d[3]))
y_true = np.array(y_true)
y_predict = np.array(y_predict)
accuracy = 1.0*np.count_nonzero(y_true==y_predict)/len(y_true)
return accuracy
def find_best_threshold(thresholds, predicts):
best_threshold = best_acc = 0
for threshold in thresholds:
accuracy = eval_acc(threshold, predicts)
if accuracy >= best_acc:
best_acc = accuracy
best_threshold = threshold
return best_threshold
parser = argparse.ArgumentParser(description='PyTorch sphereface lfw')
parser.add_argument('--net','-n', default='sphere20a', type=str)
parser.add_argument('--lfw', default='../../dataset/face/lfw/lfw.zip', type=str)
parser.add_argument('--model','-m', default='sphere20a.pth', type=str)
args = parser.parse_args()
predicts=[]
net = getattr(net_sphere,args.net)()
net.load_state_dict(torch.load(args.model))
net.cuda()
net.eval()
net.feature = True
zfile = zipfile.ZipFile(args.lfw)
landmark = {}
with open('data/lfw_landmark.txt') as f:
landmark_lines = f.readlines()
for line in landmark_lines:
l = line.replace('\n','').split('\t')
landmark[l[0]] = [int(k) for k in l[1:]]
with open('data/pairs.txt') as f:
pairs_lines = f.readlines()[1:]
for i in range(6000):
p = pairs_lines[i].replace('\n','').split('\t')
if 3==len(p):
sameflag = 1
name1 = p[0]+'/'+p[0]+'_'+'{:04}.jpg'.format(int(p[1]))
name2 = p[0]+'/'+p[0]+'_'+'{:04}.jpg'.format(int(p[2]))
if 4==len(p):
sameflag = 0
name1 = p[0]+'/'+p[0]+'_'+'{:04}.jpg'.format(int(p[1]))
name2 = p[2]+'/'+p[2]+'_'+'{:04}.jpg'.format(int(p[3]))
img1 = alignment(cv2.imdecode(np.frombuffer(zfile.read(name1),np.uint8),1),landmark[name1])
img2 = alignment(cv2.imdecode(np.frombuffer(zfile.read(name2),np.uint8),1),landmark[name2])
imglist = [img1,cv2.flip(img1,1),img2,cv2.flip(img2,1)]
for i in range(len(imglist)):
imglist[i] = imglist[i].transpose(2, 0, 1).reshape((1,3,112,96))
imglist[i] = (imglist[i]-127.5)/128.0
img = np.vstack(imglist)
img = Variable(torch.from_numpy(img).float(),volatile=True).cuda()
output = net(img)
f = output.data
f1,f2 = f[0],f[2]
cosdistance = f1.dot(f2)/(f1.norm()*f2.norm()+1e-5)
predicts.append('{}\t{}\t{}\t{}\n'.format(name1,name2,cosdistance,sameflag))
accuracy = []
thd = []
folds = KFold(n=6000, n_folds=10, shuffle=False)
thresholds = np.arange(-1.0, 1.0, 0.005)
predicts = np.array(map(lambda line:line.strip('\n').split(), predicts))
for idx, (train, test) in enumerate(folds):
best_thresh = find_best_threshold(thresholds, predicts[train])
accuracy.append(eval_acc(best_thresh, predicts[test]))
thd.append(best_thresh)
print('LFWACC={:.4f} std={:.4f} thd={:.4f}'.format(np.mean(accuracy), np.std(accuracy), np.mean(thd)))