引子[编辑 | 编辑源代码]
在实现人脸分类研究型项目时。我们想用基于tensorflow深度学习的方式做人脸的比较。最初我们想的是自己训练模型,比如用CNN卷积网络。但CNN到底该几层?卷积核多少。都不知道。所以我们就想去搜索是否别人也有与我们同样的问题需要解决。
并且已经找到了好的解决方案。还好我们尝试了去查找世界上别人的解决方案。否则完全闭门造车不知道要花多少时间精力才能有较好的进展。
经过在网上的一番搜索,找到了facenet实现人脸聚类的论文和论文解读以及基于tensorflow实现的facenet源码。
facenet davidsandberg github源码[编辑 | 编辑源代码]
下载facenet github源码后,想要做的第一件事情就是正常运行这个源码,测试作者提到的LFW样本集的准确率。这里有可以参考的wiki https://github.com/davidsandberg/facenet/wiki/Validate-on-lfw 及中文解读篇 TensorFlow 实现人脸识别
配置facenet davidsandberg 依赖环境[编辑 | 编辑源代码]
如下是需要安装的依赖包:
tensorflow==1.0 scipy scikit-learn opencv-python h5py matplotlib Pillow requests psutil
由于对python属于新手级别,所以在这里其实遇到了很多问题。
在安装scipy就报错了。最初报错有一些依赖包未安装,均先安装依赖的包,其中有参考这个链接:http://blog.csdn.net/lingfeng892/article/details/50425547。
在安装其他包时用pip -V 查看版本,发现我机器里root用户下的pip比user用户下的pip版本更新也出现了问题。就先升级了user用户下的pip。
另外更常见的是遇到了超时报错。
a,scipy安装命令:
pip install scipy
b,scikit-learn安装方法:
pip install --user --install-option="--prefix=" -U scikit-learn
c,--default-timeout=1000
--default-timeout=1000用来解决安装超时的问题。
ReadTimeoutError: HTTPSConnectionPool(host='pypi.python.org', port=443): Read timed out.
举例: sudo pip --default-timeout=1000 install opencv-python
运行facenet davidsandberg 测试LFW样本集[编辑 | 编辑源代码]
$ git clone --recursive https://github.com/davidsandberg/facenet.git
$ cd facenet/
$ pip install -r requirements.txt
$ export PYTHONPATH=$(pwd)/src
$mkdir models
下载预训练好的模型 20170216-091149.zip 或者最新的2017-0512的https://drive.google.com/file/d/0B5MzpY9kBtDVZ2RpVDYwWmxoSUk/edit
放到 models 目录下,并执行:
$ cd models/
$ unzip 20170216-091149.zip
下载已经做过预处理(人脸检测、裁剪到160x160大小的图片)lfw_align_mtcnnpy_160放在目录中,其结构展开如下:
正确的预测结果如下,在data/pairs.txt中:
表示对同一人人脸做相似性比较,并且结果为true
表示对不同人的人脸做相似性比较,并且结果为false
$ python src/validate_on_lfw.py \
./lfw_align_mtcnnpy_160/ \
./models/20170216-091149
运行的结果如下图所示:
共有6000对的LFW数据,其中一部分是做相似比较,一部分做不相似比较的。
![](https://i-blog.csdnimg.cn/blog_migrate/0e2e32fe7c2a5c867f4466aedf6f2bb5.jpeg)
运行facenet davidsandberg 测试搜集到的手机照片[编辑 | 编辑源代码]
在得到上述的结论后,还希望对我们自己搜集到的手机照片进行相似比较,并得出准确率。从而能与dlib方案作比较。首先要对我们搜集到的186张图片做预处理主要分下面三步,搜集到的图片位置在这里:
\\10.120.10.100\ckt_cd_share\SmartPhone\team\Framework\Telephony\9.MachineLearning\人脸识别测试数据\phone_image
搜集到的测试样本预处理[编辑 | 编辑源代码]
样本图片名称修改[编辑 | 编辑源代码]
由于需要将样本整理成语lfw_align_mtcnnpy_160目录结构一样,举例一张图片的路径及名称为:mobile_photos/hcz/hcz_0001.jpg
因此需要对我们搜集到的图片名字做处理,这里写了一个简单的python代码,由于是小白级别,所以只是达到功能而已。
from PIL import Image 2 import os,re 3 inputFileFolder = "D:/work/project/face_classify/samples/phone_image_facenet_format/" 4 5 path = r"D:/work/project/face_classify/samples/phone_image_facenet_format/" 6 os.chdir(path) 7 foldernames = os.listdir(os.getcwd()) 8 print foldernames 9 10 for foldername in foldernames: 11 os.chdir(inputFileFolder+ foldername) 12 filenames = os.listdir(os.getcwd()) 13 print filenames 14 i = 1 15 for filename in filenames: 16 #isJpeg = re.search(r'\.jpg$', filename) or re.search(r'\.JPG$', filename) 17 #if isJpeg: 18 inputimagePath = inputFileFolder+ foldername+'/'+filename 19 print inputimagePath 20 #storeImagePath = inputFileFolder+ foldername+'/'+ foldername+'_000'+str(i)+'.png' 21 storeImagePath = inputFileFolder + foldername + '/' + foldername +'_' + '%04d' % i + '.jpg' 22 print storeImagePath 23 Image.open(inputimagePath).save(storeImagePath) 24 os.remove(inputimagePath) 25 i += 1
生成样本真实结果存在pairs.txt[编辑 | 编辑源代码]
在对样本图片名称和目录结构复合要求后,还需要生成与/data/pairs.txt 一样格式的真实结果。也写了一个简单的能达到功能的python代码。
1 from PIL import Image
2 import os,re
3 inputFileFolder = "/home/workdir/tensorflow/facenet-master/phone_image_facenet_format/"
4
5
6 path = r"/home/workdir/tensorflow/facenet-master/phone_image_facenet_format/"
7 os.chdir(path)
8 foldernames = os.listdir(os.getcwd())
9 print foldernames
10
11 f=open("/home/workdir/tensorflow/facenet-master/test_pair_phone_image.txt",'a')
12 name_number = {}
13 foldername_list = []
14 for foldername in foldernames:
15 os.chdir(inputFileFolder+ foldername)
16 filenames = os.listdir(os.getcwd())
17
18 number_list = []
19 #print foldername
20 for filename in filenames:
21 name, number = filename.split("_", 1)
22 number = number.rstrip(".png")
23 number = str(number).strip("000")
24 number_list.append(number)
25 number_list.sort()
26 count = len(number_list)
27 for i in range(0,count-1):
28 for j in range(i+1, count):
29 #对一个文件夹下的图片进行相似排列,如写入一行 jianwenmama 1 2
30 lineStr = foldername + ' ' + number_list[i] + ' ' + number_list[j]
31 f.write(lineStr)
32 f.write('\n')
33 #print number_list
34 name_number[foldername] = number_list
35 foldername_list.append(foldername)
36 #print name_number
37 count_foldername = len(foldername_list)
38 print count_foldername
39 for k in range(0,count_foldername):
40 #print foldername_list[k]
41 one_list = name_number.get(foldername_list[k])
42 #print one_list
43 for i in range(0,len(one_list)):
44 for j in range(0, count_foldername):
45 if j == k:
46 continue
47 next_list = name_number.get(foldername_list[j])
48 print foldername_list[j]
49 print next_list
50 #对一个文件夹下的图片与其他文件夹下的图片1进行不相似排列,如写入一行 yt 5 hcz 1
51 #由于如果对一个文件夹下的图片与其他文件夹下的每张图片都进行不相似排列,会太多不相似的测试样本组合,所以这里只对其他文件夹下的图片1比较。
52 negative_linestr = foldername_list[k] + " " + str(i+1) + " " + foldername_list[j] + " " + next_list[0]
53 print 'negative_linestr='
54 print negative_linestr
55 f.write(negative_linestr)
56 f.write('\n')
57 f.close()
人像图片预处理[编辑 | 编辑源代码]
作者在主页有介绍,这个facenet开源项目支持两种face align的方案。
1,dlib
2,MTCNN
作者认为dlib有一个缺点就是在图片遮挡情况下效果不好。所以用了这个MTCNN ,也有论文和github里该作者的代码实现。
我们直接调用MTCNN进行我们图片的预处理。
预处理是指人脸检测——裁剪过程。
我采用的是MTCNN的方式进行预处理,运行方法为:
预处理后的facenet验证准确率[编辑 | 编辑源代码]
经过上述的预处理后就可以进行facenet验证了。在facenet源码目录下输入命令:
在facenet目录下执行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
请注意--lfw_nrof_folds一定要加,最初没有加打log看实际只计算了默认10对测试样本的正确率。
最后在facenet中得到的结果如下:
共186张测试样本,其中50张为印度和非洲人,进行相似和不相似的比较,最终准确率为91.3%。
这里验证过程代码逻辑为写,感兴趣的请参考另一篇wiki facenet tensorflow code源码解析 ,对代码有更多理解。