返回首页
当前位置: 主页 > 精通Office > 其他教程 >

人脸识别技术

时间:2018-02-10 22:52来源:2018年最新注册送彩金www.zhixing123.cn 编辑:麦田守望者

在深度学习出现后,人脸识别技术才真正有了可用性。这是因为之前的机器学习技术中,难以从图片中取出合适的特征值。轮廓?颜色?眼睛?如此多的面孔,且随着年纪、光线、拍摄角度、气色、表情、化妆、佩饰挂件等等的不同,同一个人的面孔照片在照片象素层面上差别很大,凭借专家们的经验与试错难以取出准确率较高的特征值,自然也没法对这些特征值进一步分类。深度学习的最大优势在于由训练算法自行调整参数权重,构造出一个准确率较高的f(x)函数,给定一张照片则可以获取到特征值,进而再归类。本文中笔者试图用通俗的语言探讨人脸识别技术,首先概述人脸识别技术,接着探讨深度学习有效的原因以及梯度下降为什么可以训练出合适的权重参数,最后描述基于CNN卷积神经网络的人脸识别。

一、人脸识别技术概述

人脸识别技术大致由人脸检测和人脸识别两个环节组成。

之所以要有人脸检测,不光是为了检测出照片上是否有人脸,更重要的是把照片中人脸无关的部分删掉,否则整张照片的像素都传给f(x)识别函数肯定就不可用了。人脸检测不一定会使用深度学习技术,因为这里的技术要求相对低一些,只需要知道有没有人脸以及人脸在照片中的大致位置即可。一般我们考虑使用OpenCV、dlib等开源库的人脸检测功能(基于专家经验的传统特征值方法计算量少从而速度更快),也可以使用基于深度学习实现的技术如MTCNN(在神经网络较深较宽时运算量大从而慢一些)。

在人脸检测环节中,我们主要关注检测率、漏检率、误检率三个指标,其中:

  • 检测率:存在人脸并且被检测出的图像在所有存在人脸图像中的比例;
  • 漏检率:存在人脸但是没有检测出的图像在所有存在人脸图像中的比例;
  • 误检率:不存在人脸但是检测出存在人脸的图像在所有不存在人脸图像中的比例。

当然,检测速度也很重要。本文不对人脸检测做进一步描述。

在人脸识别环节,其应用场景一般分为1:1和1:N

1:1就是判断两张照片是否为同一个人,通常应用在人证匹配上,例如身份证与实时抓拍照是否为同一个人,常见于各种营业厅以及后面介绍的1:N场景中的注册环节。而1:N应用场景,则是首先执行注册环节,给定N个输入包括人脸照片以及其ID标识,再执行识别环节,给定人脸照片作为输入,输出则是注册环节中的某个ID标识或者不在注册照片中。可见,从概率角度上来看,前者相对简单许多,且由于证件照通常与当下照片年代间隔时间不定,所以通常我们设定的相似度阈值都是比较低的,以此获得比较好的通过率,容忍稍高的误识别率。

而后者1:N,随着N的变大,误识别率会升高,识别时间也会增长,所以相似度阈值通常都设定得较高,通过率会下降。这里简单解释下上面的几个名词:误识别率就是照片其实是A的却识别为B的比率;通过率就是照片确实是A的,但可能每5张A的照片才能识别出4张是A其通过率就为80%;相似度阈值是因为对特征值进行分类是概率行为,除非输入的两张照片其实是同一个文件,否则任何两张照片之间都有一个相似度,设定好相似度阈值后唯有两张照片的相似度超过阈值,才认为是同一个人。所以,单纯的评价某个人脸识别算法的准确率没有意义,我们最需要弄清楚的是误识别率小于某个值时(例如0.1%)的通过率。不管1:1还是1:N,其底层技术是相同的,只是难度不同而已。

取出人脸特征值是最难的,那么深度学习是如何取特征值的?

假定我们给出的人脸照片是100*100像素大小,由于每个像素有RGB三个通道,每个像素通道由0-255范围的字节表示,则共有3个100*100的矩阵计3万个字节作为输入数据。深度学习实际上就是生成一个近似函数,把上面的输入值转化为可以用作特征分类的特征值。那么,特征值可以是一个数字吗?当然不行,一个数字(或者叫标量)是无法有效表示出特征的。通常我们用多个数值组成的向量表示特征值,向量的维度即其中的数值个数。特征向量的维度并非越大越好,Google的FaceNet项目(参见http://arxiv.org/abs/1503.03832论文)做过的测试结果显示,128个数值组成的特征向量结果最好,如下图所示:

 

 

那么,现在问题就转化为怎么把3*100*100的矩阵转化为128维的向量,且这个向量能够准确的区分出不同的人脸?

假定照片为x,特征值为y,也就是说存在一个函数f(x)=y可以完美的找出照片的人脸特征值。现在我们有一个f*(x)近似函数,其中它有参数w(或者叫权重w)可以设置,例如写成f*(x;w),若有训练集x及其id标识y,设初始参数p1后,那么每次f*(x;w)得到的y`与实际标识y相比,若正确则通过,若错误则适当调整参数w,如果能够正确的调整好参数w,f*(x;w)就会与理想中的f(x)函数足够接近,我们就获得了概率上足够高准确率的f*(x;w)函数。这一过程叫做监督学习下的训练。而计算f*(x;w)值的过程因为是正常的函数运算,我们称为前向运算,而训练过程中比较y`与实际标识id值y结果后,调整参数p的过程则是反过来的,称为反向传播

由于我们传递的x入参毕竟是一张照片,照片既有对焦、光线、角度等导致的不太容易衡量的质量问题,也有本身的像素数多少问题。如果x本身含有的数据太少,即图片非常不清晰,例如28*28像素的照片,那么谁也无法准确的分辨出是哪个人。可以想见,必然像素数越多识别也越准,但像素数越多导致的计算、传输、存储消耗也越大,我们需要有根据地找到合适的阈值。下图是FaceNet论文的结果,虽然只是一家之言,但Google的严谨态度使得数据也很有参考价值。

 

 

从图中可见,排除照片其他质量外,像素数至少也要有100*100(纯人脸部分)才能保证比较高的识别率。

二、深度学习技术的原理

由清晰的人脸照转化出的像素值矩阵,应当设计出什么样的函数f(x)转化为特征值呢?这个问题的答案依赖于分类问题。即,先不谈特征值,首先如何把照片集合按人正确地分类?这里就要先谈谈机器学习。机器学习认为可以从有限的训练集样本中把算法很好地泛化。所以,我们先找到有限的训练集,设计好初始函数f(x;w),并已经量化好了训练集中x->y。如果数据x是低维的、简单的,例如只有二维,那么分类很简单,如下图所示:

 

 

上图中的二维数据x只有方形和圆形两个类别y,很好分,我们需要学习的分类函数用最简单的f(x,y)=ax+by+c就能表示出分类直线。例如f(x,y)大于0时表示圆形,小于0时表示方形。

给定随机数作为a,c,b的初始值,我们通过训练数据不断的优化参数a,b,c,把不合适的L1、L3等分类函数逐渐训练成L2,这样的L2去面对泛化的测试数据就可能获得更好的效果。然而如果有多个类别,就需要多条分类直线才能分出,如下图所示:

 

 

这其实相当于多条分类函数执行与&&、或||操作后的结果。这个时候还可能用f1>0 && f2<0 && f3>0这样的分类函数,但如果更复杂的话,例如本身的特征不明显也没有汇聚在一起,这种找特征的方式就玩不转了,如下图所示,不同的颜色表示不同的分类,此时的训练数据完全是非线性可分的状态:

 

 

这个时候,我们可以通过多层函数嵌套的方法来解决,例如f(x)=f1(f2(x)),这样f2函数可以是数条直线,而f1函数可以通过不同的权重w以及激励函数完成与&&、或||等等操作。这里只有两层函数,如果函数嵌套层数越多,它越能表达出复杂的分类方法,这对高维数据很有帮助。例如我们的照片毫无疑问就是这样的输入。所谓激励函数就是把函数f计算出的非常大的值域转化为[0,1]这样较小的值域,这允许多层函数不断地前向运算、分类。

前向运算只是把输入交给f1(x,w1)函数,计算出的值再交给f2(y1,w2)函数,依次类推,很简单就可以得到最终的分类值。但是,因为初始的w权重其实没有多大意义,它得出的分类值f*(x)肯定是错的,在训练集上我们知道正确的值y,那么事实上我们其实是希望y-f*(x)的值最小,这样分类就越准。这其实变成了求最小值的问题。当然,y-f*(x)只是示意,事实上我们得到的f*(x)只是落到各个分类上的概率,把这个概率与真实的分类相比较得到最小值的过程,我们称为损失函数,其值为loss,我们的目标是把损失函数的值loss最小化。在人脸识别场景中,softmax是一个效果比较好的损失函数,我们简单看下它是如何使用的。

比如我们有训练数据集照片对应着cat、dog、ship三个类别,某个输入照片经过函数f(x)=x*W+b,前向运算得到该照片属于这3个分类的得分值。此时,这个函数被称为得分函数,如下图所示,假设左边关于猫的input image是一个4维向量[56,231,24,2],而W权重是一个4*3的矩阵,那么相乘后再加上向量[1.1,3.2,-1.2]可得到在cat、 dog、ship三个类别上的得分:

 

 

从上图示例可见,虽然输入照片是猫,但得分上属于狗的得分值437.9最高,但究竟比猫和船高多少呢?很难衡量!如果我们把得分值转化为0-100的百分比概率,这就方便度量了。这里我们可以使用sigmoid函数,如下图所示:

 

 

从上图公式及图形可知,sigmoid可以把任意实数转换为0-1之间的某个数作为概率。但sigmoid概率不具有归一性,也就是说我们需要保证输入照片在所有类别的概率之和为1,这样我们还需要对得分值按softmax方式做以下处理:

 

 

这样给定x后可以得到x在各个类别下的概率。假定三个类别的得分值分别为3、1、-3,则按照上面的公式运算后可得概率分别为[0.88、0.12、0],计算过程如下图所示:

 

 

然而实际上x对应的概率其实是第一类,比如[1,0,0],现在拿到的概率(或者可称为似然)是[0.88、0.12、0]。那么它们之间究竟有多大的差距呢?这个差距就是损失值loss。如何获取到损失值呢?在softmax里我们用互熵损失函数计算量最小(方便求导),如下所示:

 

 

其中i就是正确的分类,例如上面的例子中其loss值就是-ln0.88。这样我们有了损失函数f(x)后,怎么调整x才能够使得函数的loss值最小呢?这涉及到微分导数。

三、梯度下降

梯度下降就是为了快速的调整权重w,使得损失函数f(x;w)的值最小。因为损失函数的值loss最小,就表示上面所说的在训练集上的得分结果与正确的分类值最接近!

导数求的是函数在某一点上的变化率。例如从A点开车到B点,通过距离和时间可以算出平均速度,但在其中C点的瞬时速度是多少呢?如果用x表示时间,f(x)表示车子从A点驶出的距离,那么在x0的瞬时速度可以转化为:从x0时再开一个很小的时间,例如1秒,那么这一秒的平均速度就是这一秒开出的距离除以1秒,即(f(1+x0)-f(x0))/1。如果我们用的不是1秒而是1微秒,那么这个1微秒内的平均速度必然更接近x0时的瞬时速度。于是,到该时间段t趋向于0时,我们就得到了x0时的瞬时速度。这个瞬时速度就是函数f在x0上的变化率,所有x上的变化率就构成了函数f(x)的导数,称为f`(x)。即:

 

 

从几何意义上看,变化率就变成了斜率,这更容易理解怎样求函数的最小值。例如下图中有函数y=f(x)用粗体黑线表示,其在P0点的变化率就是切线红线的斜率:

 

 

可以形象的看出,当斜率的值为正数时,把x向左移动变小一些,f(x)的值就会小一些;当斜率的值为负数时,把x向右移动变大一些,f(x)的值也会小一些,如下图所示:

顶一下
(0)
0%
踩一下
(0)
0%
标签(Tag):人脸识别技术
------分隔线----------------------------
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
验证码:点击我更换图片
猜你感兴趣
博聚网