人脸验证和人脸识别
人脸验证:输入一张图片和姓名/ID,验证这个人是否和他声称的身份相符。
人脸识别:有一个K个人的数据库,输入一张图片,如果这张图片是k个人其中之一,输出其ID。不是K个人之一时输出识别失败。
识别问题比验证问题难得多,假设你有一个验证系统,准确率是99%,表面上敢接还可以。但是当在识别系统中有K个人时,假设K=100。如果把这个验证系统应用到100个人的人脸识别上,那么犯错的机会就是100倍了。如果你有一个上百人的数据库,想要得到一个可接受的识别误差,你要构造一个验证系统其准确率为99.9%甚至更高,然后才可以在100人的数据库上运行而保证有很大几率不会出错。事实上,当我们有一个100人的数据库,正确率可能需要远大于99%才能得到很好的效果。
One-shot learning
人脸识别所面临的一个挑战就是你需要解决一次学习的问题。这意味着在绝大多数人脸识别应用中你需要通过单单一张图片或者单单一个人脸样例就能去识别这个人。
在One-shot learning问题中,只能通过一个样本来进行学习以能认出同一个人。大多数人脸识别系统都需要解决这个问题。一种方法是将样本输入卷积神经网络进行训练,但样本太少不足以训练出一个稳健的网络,且当有新的人员加入时需要重新训练网络,这显然不是一个有效的方法。
另一个有效的解决方法就是,使用一个相似性的函数d,让神经网络学习到一个d这样的函数,它以两张图片作为输入,然后输出两张图片的差异值,如果你放进同一个人的两个照片,你希望它能输出一个很少的值,如果放进两个长相差别很大的人的照片,它就输出一个很大的值,如果两张图的差异值小于一个阈值τ(τ是一个超参数),那么就能预测这张图片是同一个人。
Siamese网络
要想实现像d函数这样的功能的一个方式就是使用Siamese网络。具体做法是将两张图片分别输入同一个网络,得到两个高维的特征向量,然后计算这两个高维特征向量的距离 。
更准确地说,神经网络的参数定义了一个编码函数f(x),给定输入图像x,这个网络会输出x的的一个高维编码,你要做的就是学习参数使得如果两个照片是同一个人,那么得到的两个编码的距离就小。相反,则让它们之间的编码距离大一些。
Triplet loss
要想通过学习神经网络参数来得到优质的人脸图片编码的方法之一就是定义三元组损失函数,然后应用梯度下降。
假设设定一个Anchor图片,正类图片P和反类图片N。损失函数可以设置为
为了确保对于所有的图片编码不会总是输出0,也为了确保对于所有的图片编码不会总是相等,可稍作修改:
α是一个超参数,间隔参数α 拉大了anchor和positive图片对anchor和negative图片之间的差距。
Loss函数就可以表示为
整体损失函数就表示为
为了定义三元组的数据集,你需要成对的A和P。为了训练你的系统,你确实需要一个数据集里面有同一个人的多个照片,如果你只有每个人一张照片,那么根本无法训练这个系统。当然,训练完这个系统之后,你可以应用到你的one-shot learning问题上。但对于训练集,你需要确保一个人的多个图片。
如果A和N是来自随机选择的不同的人,有很大的可能性式(2.1)的右边式子会比左边的大,而且差距远大于α ,这样网络并不能从中学到什么,所以为了构建一个数据集,你需要做的就是尽可能选择难训练的三元组(A,P,N)。
难训练就是你的A,P,N选择使得d(A, P)很接近d(A,N),选择这样的三元组还可以增加你的学习算法的计算效率,如果随机选择,其中太多会很简单,这对梯度下降算法不会有什么效果。
面部验证和二分类
其中绝对值项可以更换成 ,这是χ平方公式,也被称为χ平方相似度。y∈(0, 1)
实际部署时,可先计算好数据库中图片的编码并存储,而不需要每次识别都重新计算,可以节省大量的计算。
神经风格迁移
在深度卷积网络中,第一层隐藏单元通常会找一些简单的特征,比如说边缘或者颜色阴影。在深层部分,一个隐藏单元会看到一张图片更大的部分,第二层的隐藏单元检测到了更复杂的形状和模式,在第三层检测到更加复杂的模式,如此类推。
要构建一个神经风格迁移系统,要为生成的图像定义一个cost函数,通过最小化cost函数可以生成你想要的任何图像。
给定内容图像C,风格图片S,生成新图片G。我们把cost函数分为两部分,第一部分称为内容代价函数--- ,它是用来衡量生成图片的内容与内容图片C的内容有多相似。然后是一个风格代价函数---Jstyle(S, G)
,用来衡量G和图片S的风格相似度,之后用两个超参数α
和β
来确定两代价之间权重。
神经风格迁移步骤主要如下:
- 随机初始化图片G;
- 使用梯度下降法最小化J(G),更新图片G的像素值。
内容代价函数
使用预训练的网络(例如VGG)输入两张图片,在网络中间层输出 和
。所以内容代价函数
代价函数会激励这个算法来找到网络G使得隐藏层的激活值和你的内容图像C相似。
如果使用预训练网络较浅的隐藏层,这个代价函数就会使你的生成图片在像素上非常接近你的内容图片,如果使用较深的层,那么就相当于问内容图片是否有狗之类的问题,然后它就会确保生成图片中有一个狗。所以在实际中,既不能选择太浅的层,也不能选择太深的层。
风格损失函数
需要先计算风格矩阵,其主要表示的是图片不同通道之间的相关性。其计算方式如下:
其余a是预训练网络中间隐藏层的输出。它是一种非标准互相关函数,因为没有减去平均数,而是将它们直接相乘。
同理生成图片G的风格矩阵可以表述为
故风格损失函数如下所示:
作些许修改后可变成:
实际上,如果对预训练网络的各个层都使用风格损失函数会让结果变得更好。