学习了机器人人脸识别程序的心得体会
整个人脸识别流程分为三个部分(1)人脸检测;(2)人脸特征提取;(3)基于欧几里得距离的比较。
人脸识别和图片分类不同,我们不能像在图片分类工程中一样针对每一个分类提供大量的训练集去训练我们的模型。在人脸识别的网络模型中,我们所需要的结果并不是最后全连接层输出的置信度结果,而是经过CNN网络提取的特征值。这些特征值的维度根据网络模型的选用和输入图片像素的不同而变化。
由于需求不同,我们对于神经网络的训练方式自然不同。通常可以选择基于三元组损失的训练方式和基于中心损失的训练方式。但是基于三元组损失的训练方式难以定义且难以收敛,所以多选择基于中心损失的训练方法,简单来说中心损失就是为训练集的每一个分类设置一个中心,通过优化提取特征和这个中心之间的距离来达到优化的效果。在这里需要注意:尽管我们是基于中心损失去训练神经网络,但这样的效果并不会很好。所以我们的损失定义应该是中心损失和传统的分类损失的加权结合。
至于训练集,有很多可选的训练集,但大多需要甚至正式申请才能够下载。我使用的训练集是casia-webface,很好获取。
我们应该在开始人脸识别之前,应该预先处理数据库中的图片。我认为比较好的方法是将提取的特征值(一个数组)记录在(.txt)文档里,在启动服务的时候统一读取进来。
在从视频流中获取图像的时候有一个要注意的地方,通常可能会选择用opencv来获取图片,但是opencv的图片格式是bgr与我们的训练集rgb图片格式不同。可以通过数组方式交换图层或者选用更简单的VideoCapture来获取图片。机器人编程培训心得体会
不同的人提取的特征值自然有所差别,通常的做法是将特征值reshape为一个一维数组,然后对不同的人脸的特征值之间求欧几里得距离,同一个人的照片求得的欧氏距离会更小(建议为了放大不同人脸之间距离的差距,可以省略开方的步骤)。这里我们为距离设置一个阈值(THRESGOLD),当求得的欧氏距离小于这个阈值时认为两张照片出自同一个人。这里阈值的设置没有一个标准,毕竟准确率和识别成功率难以兼得,可以通过自己的测试选定一个合适的值。比如我选用的Res-net模型,求得的特征值长度为2048,当阈值小于17时基本不会出错,但同时也会难识别;如果让人脸很端正地靠近摄像头,测得的欧式距离基本在14
以内。
在实际应用中我们是在一个很大的数据库中比对人脸特征,最简单的做法当然是在一个for循环里将本次取得的特征值和数据库里的特征值逐一求得距离,这也是我一开始没有做好的地方。在这里个人建议:为了充分利用计算资源,首先将图片特征值转换为narray格式,然后扩展为一个与数据库特征值数量对应的矩阵,如[15000,2048]。然后将该矩阵和数据库特征值整体求欧几里得距离。这是因为numpy库是用C语言编写的,它可以绕过Python的GIL而实现真正的多线程运算。经过我的测试,利用矩阵整体运算的方法可以使搜索速度提升2至3倍。这在数据库数据较少时对整体速度的提升很有限,但一旦该当数据库的数据上升到以万为单位时,多线程的矩阵运算对整体识别速度的提升是十分有效的。