facenet tensorflow code源码解析
引子[编辑 | 编辑源代码]
这里要讲的Facenet tensorflow code解析是基于github上https://github.com/davidsandberg/facenet这个开源代码的代码学习和理解所得。
目录结构介绍[编辑 | 编辑源代码]
下图有红色标注的是我所了解到的一些源码的作用,主要是跟着如何验证我们搜集到的一些照片这个线来看的代码,其他一些源码还没有研究过。
漏了一个文件件介绍就是models,这个文件夹下面放的是facent采用的CNN卷积中不同网络结构的不同实现代码比如Inception-ResNet-v1.
验证LFW测试样本的代码流程[编辑 | 编辑源代码]
验证命令解析[编辑 | 编辑源代码]
在facent源码根目录下执行:
python src/validate_on_lfw.py phone_image_facenet_format_mtcnnpy_160 models/20170216-091149/ --lfw_nrof_folds 9398 >phone_image_facenet_format_mtcnnpy_160_9398.log 要执行的python脚本 测试样本路径 模型存放路径 总共要测试的样本对长度,9398就是/data/pairs.txt中要测试比较的样本对总数
流程图[编辑 | 编辑源代码]
准确率计算代码解读[编辑 | 编辑源代码]
1 def evaluate(embeddings, actual_issame, nrof_folds=10):
2 #Calculate evaluation metrics
3 #thresholds初始化从0到3.99每0.01递增的数组
4 thresholds = np.arange(0, 4, 0.01)
5 #从tensorflow中得到的结果,猜测是测试样本对中的第一个图片的特征向量
6 embeddings1 = embeddings[0::2]
7 #从tensorflow中得到的结果,猜测是测试样本对中的第二个图片的特征向量
8 embeddings2 = embeddings[1::2]
9 #np.asarray(actual_issame)是指测试样本对的真实结果true,false的数组
10 tpr, fpr, accuracy = facenet.calculate_roc(thresholds, embeddings1, embeddings2,
11 np.asarray(actual_issame), nrof_folds=nrof_folds)
12 thresholds = np.arange(0, 4, 0.001)
13 val, val_std, far = facenet.calculate_val(thresholds, embeddings1, embeddings2,
14 np.asarray(actual_issame), 1e-3, nrof_folds=nrof_folds)
15 return tpr, fpr, accuracy, val, val_std, far
16
17 def calculate_roc(thresholds, embeddings1, embeddings2, actual_issame, nrof_folds=10):
18 assert(embeddings1.shape[0] == embeddings2.shape[0])
19 assert(embeddings1.shape[1] == embeddings2.shape[1])
20 #得到的对数就是data/pairs.txt中的行数
21 nrof_pairs = min(len(actual_issame), embeddings1.shape[0])
22 nrof_thresholds = len(thresholds)
23 k_fold = KFold(n_splits=nrof_folds, shuffle=False)
24
25 tprs = np.zeros((nrof_folds,nrof_thresholds))
26 fprs = np.zeros((nrof_folds,nrof_thresholds))
27 accuracy = np.zeros((nrof_folds))
28 #embeddings1,embeddings2的size为pairs * 128.这里的pairs为要比较的对数。
29 diff = np.subtract(embeddings1, embeddings2)
30 #dist是在embeddings1与embeddings2之差之后,进行平方的和。其size为pairs。
31 dist = np.sum(np.square(diff),1)
32 indices = np.arange(nrof_pairs)
33 #循环每一个flod,即每一个测试样本对做以下操作。
34 for fold_idx, (train_set, test_set) in enumerate(k_fold.split(indices)):
35
36 # Find the best threshold for the fold
37 acc_train = np.zeros((nrof_thresholds))
38 # 循环取thresholds中的一个阈值调用calculate_accuracy()计算得到acc_train的数组。并且取准确率最高对应的threshold_index为best_threshold_index。
39 #train_set与test_set按照9:1的个数比例来分配的。比如pairs为20,这里train_set的长度是18,test_set长度为2.
40 for threshold_idx, threshold in enumerate(thresholds):
41 _, _, acc_train[threshold_idx] = calculate_accuracy(threshold, dist[train_set], actual_issame[train_set])
42 best_threshold_index = np.argmax(acc_train)
43 # 循环取thresholds中的一个阈值调用calculate_accuracy()计算得到tprs[fold_idx,threshold_idx],fprs[fold_idx,threshold_idx]。
44 for threshold_idx, threshold in enumerate(thresholds):
45 tprs[fold_idx,threshold_idx], fprs[fold_idx,threshold_idx], _ = calculate_accuracy(threshold, dist[test_set], actual_issame[test_set])
46 #用前面得到的best_threshold_index 带入得到accuracy[fold_idx]一个测试对的准确率
47 _, _, accuracy[fold_idx] = calculate_accuracy(thresholds[best_threshold_index], dist[test_set], actual_issame[test_set])
48
49 tpr = np.mean(tprs,0)
50 fpr = np.mean(fprs,0)
51 return tpr, fpr, accuracy
52
53 def calculate_accuracy(threshold, dist, actual_issame):
54 #比较距离值与阈值的结果得到预测值predict_issame
55 predict_issame = np.less(dist, threshold)
56 #得到true pair,false pair,true negative,false negative,其中fp和fn是错误的预测
57 tp = np.sum(np.logical_and(predict_issame, actual_issame))
58 fp = np.sum(np.logical_and(predict_issame, np.logical_not(actual_issame)))
59 tn = np.sum(np.logical_and(np.logical_not(predict_issame), np.logical_not(actual_issame)))
60 fn = np.sum(np.logical_and(np.logical_not(predict_issame), actual_issame))
61 # tpr及fpr的计算是为了计算后面的ROC曲线的AUC面积。
62 tpr = 0 if (tp+fn==0) else float(tp) / float(tp+fn)
63 fpr = 0 if (fp+tn==0) else float(fp) / float(fp+tn)
64 #acc就等于正确的预测除以总的结果对。
65 acc = float(tp+tn)/dist.size
66 return tpr, fpr, acc
ROC AUC含义[编辑 | 编辑源代码]
最初也不明白为什么要计算tpr,fpr。参考了这篇链接后有所理解:
ROC和AUC在python中metrics上的实现
ROC(Receiver Operating Characteristic)曲线和AUC常被用来评价一个二值分类器(binary classifier)的优劣。