本文由2019年6月《软件工程》必修课的课程设计报告的AI部分改编
主要介绍了“员工考勤管理系统”课程设计中的员工人脸打卡子系统
该系统使用了Google CoLab提供的在线Tensorflow GPU平台训练得到的DeepID人脸特征提取比对模型,
以及基于该模型搭建的Tensorflow+OpenCV+Flask人脸比对Python服务器
中文标题:使用Google CoLab+Tensorflow训练DeepID1人脸比对模型
项目地址
- Google CoLab(需要访问国外网站的能力)
- GitHub(待发布)
简介
其中DeepID层能够提取出160维特征向量
DeepID是香港中文大学王晓刚教授团队在CVPR2014上发表的论文《Deep Learning Face Representation from Predicting 10,000 Classes》提出的方法,全称为Deep hidden IDentity feature(DeepID)。
该方法是一种特征提取的算法,对于一个多层卷积-池化网络进行多分类任务训练后,在其中一层中间层DeepID层能够提取出输入的任意人脸图片的160维深层次特征向量(实际上是160x2x60维的特征向量)。
而这种特征提取的能力是面向任意的(需要经过预先裁剪和对齐后的)人脸图像的,因此作者做出了一个形象的比喻:即使是分10000个类,网络也能够有效区分出每个类别的人脸的显著特征(从而通过特征之间的距离,识别出两张人脸是否为同一人)。
因此,这一方法体现出的以下特性,使得我们最终在众多人脸特征提取方法中选取了DeepId:
- 方法实现的仅需一次训练即可获得的人脸特征提取能力,十分适合企业员工人脸考勤环境下员工人脸库经常性变动、待对比人脸图像来源较为复杂的应用场景。
- 方法的网络结构简单,易于理解和实现。同时,网络层数较少,相应地也能够减少训练所消耗的时间和硬件资源,便于我们在短周期(8周,AI子系统开发仅一周)的软件工程课程设计开发过程中安排进度。最终,该算法的训练时长在Google CoLab上为50000次/2小时。
- 方法的准确率较高,在Tensorflow的实现+YouTube Aligned Faces数据集上的测试集人脸比对识别准确率能够达到96%。
当然,这一方法作为一个2014年提出的方法,(也是DeepID三代中的第一个版本)也存在着一定的缺陷:
- 仅适用于提取图像中的正脸,也就是通过摄像头正对人脸拍摄的、或者是通过一定图像处理算法重新对齐的人脸。对于侧脸、带有一定歪斜的人脸等日常生活中常见的人脸图像,识别能力大打折扣。也正因如此,GitHub上DeepID的Tensorflow实现采用了Youtube Aligned Faces数据集,已经做过了人脸对齐的预处理,用来训练DeepID较为方便。
- 在实际使用的过程中,笔者发现这一模型对于裁剪得出的人脸图像的光线明暗、是否佩戴眼镜等变化是敏感的,只有在光照条件、脸部配饰等状况近似于人脸图像采集时的情况下,才能够被识别为同一人。
因此,目前主流的人脸特征比对方法都聚焦在人脸检测阶段的多特征点提取、侧脸特征点的重新对齐、人脸3D模型识别(一个最著名的案例,就是Apple在iPhone上用于FaceID的3D结构光特征点识别方案)等研究方向。
至于Google Colab,是谷歌打造的的一个在线深度学习平台,基于Jupyter Notebook+Tensorflow,能够通过简单的配置,使用Google免费提供的云端GPU资源,从而无需本地硬件资源地轻松训练自己的神经网络。在很久之前的一次计设校赛上曾经使用过这一平台,因此本项目也继续使用这个平台对DeepID网络进行训练。
训练环境搭建
访问 https://colab.research.google.com,如果没有谷歌账号可以先去注册一个,列表中是已有的Jupyter Notebook文件,创建的文件一般会放在Google 云端硬盘的/colab notebook
文件夹下。一般是创建Python 3笔记本,
Colab的环境初始化结束后,呈现的是经典的jupyter notebook界面,先点击“代码执行程序-更改运行时类型”,将“硬件加速器”从“None”修改为“GPU”,这样就可以免费使用基于谷歌提供的云端Nvidia GTX Tesla T4 GPU的Tensorflow GPU版本,显存15GB,比自己笔记本的4G独显性能高多了。
注意!千万不要选择TPU!
虽然TPU是Google推出的号称Tensorflow专用的GPU平台,但是其训练速度真的难以接受,在下文我会附上GPU和TPU训练DeepID网络时的Tensorboard检测到的数据,足以体现两者之间的性能差异。
之后可以在左侧边栏中,查看文件目录,会发现一个“挂在Google云端硬盘”的选项,点击之后就会生成一个cell。内容大致为1
2
3# 运行此单元格即可装载您的 Google 云端硬盘。
from google.colab import drive
drive.mount('/content/drive')
运行之后,会生成一个链接拿到Google 云端硬盘生成的授权码,输入到这个cell中,即可成功挂在你的Google 云硬盘。1
2
3
4
5Go to this URL in a browser: https://accounts.google.com/o/oauth2/auth?....
Enter your authorization code:
··········
Mounted at /content/drive
之所以需要挂载Google云硬盘,是基于这样的考虑:
Google Colab有一个“防挖矿”机制,为了防止自己免费开放的GPU资源被矿工拿来挂机挖矿,Colab会自动回收那些运行了很久或者和网页端断线很久的项目的所有资源:包括GPU和所有文件。
因此尽量不要尝试在训练的过程中关闭浏览器,然后等时间到了再次打开浏览器查看结果,很有可能早已训练结束,模型文件已经生成,但是由于Colab的这个机制导致文件被删除。
所以在训练过程中,需要挂载Google 云端硬盘,将模型文件和训练生成的Tensorboard日志的路径放在云端硬盘里,就算谷歌回收了资源也能够及时保存。
但是,需要注意的是,数据集最好不要放在Google 云端硬盘里,因为网上有人试过了,Colab从Google云端硬盘上获取文件时不是直接读取文件系统,而是发送请求进行文件分块下载的,这个网络IO带来的延迟会极大地拖慢训练的速度。
此外,这个数据集直接上传到Google Colab上的速度也是堪忧。但是,值得称赞的是,在Colab里直接用Shell命令下载在线的数据集,速度极快,能够达到15M/s。以下是下载YouTube Aligned Faces数据集的输出,30秒完成~
还有一个需要注意的地方,就是Colab上已经装好了Tensorflow 1.14、OpenCV以及matplot、numpy、PIL等深度学习常用的python库,若需要其他库也是直接执行shell命令pip install即可。这里的Tensorflow 1.14与目前常用的1.x版本相比,在API上有着许多区别,如果直接复制他人的代码,会出现许多的问题。
笔者也因此几乎是把GitHub上的DeepID实现从头开始添加中文注释和改写API,学到了很多搭建Tensorflow训练框架的相关API用法(例如session、variable和namescope),也算是继续了之前《人工智能》大作业的“注释阅读法”的个人习惯。
以上就是一些搭建Colab环境的注意事项,如果你已经看懂了这些,而且熟悉Jupyter Notebook,就可以开始着手编写训练代码了。
编写训练代码
下载YouTube Aligned Faces数据集
1 | # 下载youtube aligned face数据集 |
裁剪数据集图片
1 | ''' |
分割数据集为训练集、验证集和测试集
1 | ''' |
向量化数据集,便于读取
1 | ''' |
运行tensorboard监视训练过程
在经过了以上漫长的数据集裁剪、分割和向量化过程(第1、2步各需要20分钟)之后,就开始了训练。这里可以选用Colab内置的Tensorboard进行训练过程的监视。首先需要升级,否则无法读取训练过程中生成的日志文件。
在实际使用过程中,若训练生成的日志放在了Colab的文件目录中,Tensorboard在训练开始后过一段时间会与训练程序断开连接,
因此同样需要将训练程序代码中的日志文件路径设为Google 云端硬盘的路径。这样就算掉线了也能够在本地运行一个Tensorboard,手动下载Google 云端硬盘上不断更新的日志文件进行监视(或者有下载Google云端硬盘的客户端,可以使用文件夹同步功能实时更新本地的日志文件)。
1 | ''' |
训练DeepID网络
1 | ''' |
这里展示一下tensorboard采集的使用TPU(由于速度过慢,未训练完)和Tesla T4 GPU(2小时训练结束)的进行50000次训练的准确率和损失率图表:
对于TPU:
可以看出TPU训练时的准确度上升缓慢,而且过了3个小时后,准确度仍然在0.6,而且才训练了不到4k次。
同样地,TPU训练时损失率下降也十分缓慢。
对于GPU:
可以看出TPU训练时的准确度上升呈对数曲线,在训练次数到15k~30k时就已经趋于稳定,在1小时27分时就已经结束了训练。
同样地,GPU训练时损失率下降也十分迅速。
综上,可以看出Google Colab提供的免费GPU性能十分地强劲,能够满足快速训练简单的深度学习模型的需求。这款GPU通过nvidia-smi命令查询的情况如下所示,据查,该款显卡的价格约两万元人民币,可以看出谷歌为了推广深度学习付出了巨大的成本。
在测试集上使用模型文件预测,获取余弦距离阈值
这里运行测试集除了检验模型的预测效果,更重要的是获取余弦距离的阈值,也就是(true_mean + false_mean)/2
,意思是:小于同类组+不同类组的平均组内距离的两者平均(有点拗口,但是确实是以此为阈值)。根据这个阈值,就能判断任意两个人脸之间的距离代表的是同一个人还是不同的人。
1 | ''' |
预测服务搭建
对于已经训练好的Tensorflow模型的预测服务搭建,在网络上有许多的方法,事实上最好的方法是使用frozen_graph工具对checkpoint进行固化处理,笔者这里是直接调用了checkpoint来恢复现场,事实上效果类似。
笔者在这里使用的是docker进行预测服务搭建,具体使用的镜像是yoanlin/opencv-python3-tensorflow
,自带python3、opencv和tensorflow1.x。由于tensorflow仅仅是使用1.14生成的模型,所以不存在兼容性问题。
具体命令如下
1 | # 拉取镜像 |
若需要部署到服务器,可以使用以下命令1
2
3
4
5
6
7# 将容器提交为新的镜像
docker commit tf-cv tf-cv:server
# 将新的镜像打包为tar压缩文件,之后用scp命令传到服务器上
docker save > tf-cv.tar tf-cv:server
# 在服务器上解压镜像
docker load < tf-cv.tar
# 再次使用docker run命令生成新的容器,并在新的容器内部运行flask,参见以上命令
编写预测代码
OpenCV人脸检测
1 | ''' |
Tensorflow人脸特征比对
1 | # import tensorflow as tf |
Flask后端服务器主程序
1 | from flask import Flask |
以上的flask服务器的业务流程是:
- 在主程序中路由
/face
上接收POST请求,收到待比对的两张人脸图片的文件路径。 - 在detect_face函数中,使用OpenCV的HAAR模型,检测图片中的人脸,并且裁剪成当时训练时使用的(55,47)尺寸输入。若检测不到人脸,或者图片文件无法找到,直接返回错误信息。
- 在predict函数中,调用tensorflow恢复(restore)模型的参数,输入这两张人脸,获取每张人脸的特征值,计算两者特征值的余弦距离,与之前在测试集上获取的余弦距离阈值进行比对,判断出是否为同一个人,返回结果。
最终,在前端小程序的手机前置摄像头调用和用户界面的配合下,该系统的最终效果如下所示:
总结
本次项目实践了使用OpenCV、Tensorflow、Tensorboard以及docker、Jupyter Notebook等深度学习模型训练的常用工具,并尝试将训练得出的模型进行Python flask后端+小程序前端应用落地。在这一过程中,笔者不但熟悉了从数据集预处理、模型训练框架搭建、模型训练过程监控再到模型实际应用的全过程,也通过编写中文注释、以及对Tensorflow不同版本API的移植重写,进一步熟悉深度学习的常用术语和内在含义,可以说是一次收获颇丰的实践案例。
在此,特别感谢Google Colab免费提供的Nvidia GTX Tesla T4高性能GPU硬件资源以及在线训练平台,感谢他们为深度学习的推广和应用做出的无数努力和贡献。最后,感谢USTB的《机器学习》(自动化学院)、《人工智能》、《模式识别》、《软件工程》等相关课程老师的辛勤教学,是各位老师传授的宝贵知识和设置的一系列大作业帮助着我进一步理解、学习AI各个方向的知识并加以实践,为未来的研究和工作打下了知识基础。感谢大家!
参考资料
- GitHub上DeepID的Tensorflow实现(本文在此基础上修改了调用的TensorflowAPI到1.14,并添加中文注释):
https://github.com/jinze1994/DeepID1 - DeepID1论文《Deep Learning Face Representation from Predicting 10,000 Classes》:
https://www.cv-foundation.org/openaccess/content_cvpr_2014/papers/Sun_Deep_Learning_Face_2014_CVPR_paper.pdf - Google Colab官网:https://colab.research.google.com
- DeepID1、2算法解读:https://www.cnblogs.com/venus024/p/5632243.html
- 人脸特征提取DeepID 1.0深度网络解读:
https://blog.csdn.net/jiajinrang93/article/details/72566130/