Course 4-Convolutional Neural Networks--Week 4

本周的内容主要围绕人脸识别展开,主要包括face verification、face recognition、neural style transfer。

4.1 What is face recognition?

首先来看看人脸识别领域的一些术语。如下图所示,分别说明了人脸确认和人脸识别的概念。人脸确认是个1对1的问题,而人脸识别比人脸确认更难,是个1对K的问题。如果人脸确认系统的正确率是99%,当我有100个人的时候,正确率并不会很高;此时,我们需要进一步提高人脸系统的正确率,比如提升至99.9%。
Course 4-Convolutional Neural Networks--Week 4
接下来的几节中,我们将构建face verification系统,它是人脸识别问题的一个组成部分。如果人脸确认系统的准确率足够高,那么我们可以直接将其作为人脸识别系统的一部分。

4.2 One-shot learning

人脸识别的挑战之一就是要解决one-shot学习问题,这意味着,对于大多数人脸识别应用,我们需要仅用一张图片来识别人脸。但如果每个人只有一张训练照片的话,深度学习算法是不可能工作好的。我们先来通过一个例子说明下什么是one-shot,然后再来讨论如何定位这个问题。
假如我们有一个数据库,里面是四个雇员的人脸图像。系统所做的事情就是,尽管对每个人都只见过一张图片,但还是要识别出这个人在不在我的数据库中,如果在,指出是谁;如果不在,告诉我们。因此,one-shot学习问题指从一个样例中学习识别人脸。因此,可以尝试的一种方法是:将一张人脸图像输入到ConvNet中,最后使用softmax来输出y^,但是这样网络的工作效果并不好,因为训练集太少了,对于深度学习网络来说,这是远远不够的。并且,一旦有新人加入团队,又要重新训练网络,这样的话,这个方法并不是一个好方法。
Course 4-Convolutional Neural Networks--Week 4
取而代之的是,我们学习一个similarity function(相似性方程),我们想神经网络可以学习一个函数d,输入是两张图像,输出是两张图像的差异度。如果两张图像是同一个人的,我们希望输出值较小;如果两张图像是不同的人,我们希望输出值较大。因此,我们可以设置一个超参数阈值τ,如果输出的差异度小于等于阈值,则认为是同一个人,否则认为是两个人。这就是我们定位的人脸确认问题。将其用在识别任务中时,我们所做的就是,新来一张图片,我们使用函数d进行图像间的两两计算,输出差异度,若小于阈值,则认为是同一个人,否则是两个人。即便有新成员加入,只需要将其照片加入数据库,该方法仍然能工作的很好。
Course 4-Convolutional Neural Networks--Week 4
下节将介绍如何训练神经网络来学习函数d

4.3 Siamese network

函数d的工作是输入两张人脸图像,然后告诉我们它们的差异度。一个好的实现方法是使用Siamese network。
如下图所示。我们将图像x(1)输入ConvNet,经过卷积、池化、全连接的序列,最后得到一个特征向量。像我们之前,会将这个特征向量输入进softmax层,最后得到分类结果。但是现在,我们不需要分类结果,相反,我们只关心最后的特征向量,比如说是长度为128的特征向量,并称其为f(x(1)),我们将f(x(1))当做是输入图像x(1)的编码,因此,ConvNet将一幅二维图像重新表示成了一个一维特征向量。那么,构建人脸识别系统的方法就是将另一张人脸图像也输入具有相同参数的相同ConvNet中,并得到长度为128的特征向量。最后,如图中蓝色自己所写,通过计算两个特征向量之间的距离,得到输入x(1)x(2)之间的差异度,进而得出两张图像中的人脸是否是一个人。
Course 4-Convolutional Neural Networks--Week 4
那么,怎么训练这个Siamese network呢?神经网络的参数决定了输入x的编码f(x),对于任意的输入x,神经网络会输出一个长度为128的编码f(x)。更具体的说,我们要学习一组参数,这组参数可以使得对于相同的人,其图像的编码距离很小;但对于不同的人,其图像的编码距离较大。我们就是要使用back propagation,求得使上述条件成立的参数。
Course 4-Convolutional Neural Networks--Week 4
那么,我们如何定义目标函数,最终得到我们想要的参数呢?

4.4 Triplet loss训练方法之一

一种学习上述神经网络参数的方法是,定义triplet loss,并利用梯度下降法更新参数。下面进行详述。
为了应用triplet loss,我们需要比较图像对。如下图所示,每次需要3张图片,分别是anchor、positive、negative。如下图中蓝色笔迹所示,当f(A)f(P)f(N)均为0,或f(A)f(P)f(N)均相等时,仍然满足下图中蓝色笔迹的不等式,为了防止这种情况的发生,我们加一个大于0的超参数α,如绿色笔迹所示,称其为margin,它的大小决定了d(A,P)d(A,N)之间的最小gap。
Course 4-Convolutional Neural Networks--Week 4
triplet loss function定义在3张图像上,A、P、N,其中,A和P表示的同一个人,A和N表示的不同的人。则triplet loss L(A,P,N)的定义如下图所示,当||f(A)f(P)||2||f(A)f(N)||2+α0满足时,损失loss为0,否则就是||f(A)f(P)||2||f(A)f(N)||2+α的值。这是一个三元组的损失。神经网络的代价函数就是对训练集中所有的三元组损失进行求和。假设训练集中有针对1000个人的10000个图像,我们所要做的就是从10000个图像中不断取数据,形成三元组,然后训练模型,使用梯度下降法。对于整个训练集代价函数J的定义如图中所示。必须要说明的是,对于训练阶段,每个人还是需要多张图像的。
Course 4-Convolutional Neural Networks--Week 4
在训练时,如果我们随机选择A、P、N,使A和P是一个人,A和N是两个人,那么d(A,P)+αd(A,N)是非常容易满足的,这样梯度下降就没什么作用了。因此,我们要选择那些难训练的triplets,即d(A,P)d(A,N)很相近的那些三元组,才能通过梯度下降改善参数,使d(A,P)d(A,N)之间的gap变大。
Course 4-Convolutional Neural Networks--Week 4
商业化的人脸识别系统训练所需要的数据集通过都是1million-100million images。如果我们自己想要训练这样的网络,无非是非常费力的。幸运的是,很多公司都把他们训练好的参数公开了,我们可以直接用。
Course 4-Convolutional Neural Networks--Week 4

4.5 Face verification and binary classification训练方法之二

triplet loss是一种学习人脸识别中ConvNet参数的好方法,但还有一种方法也可以学习参数,就是将人脸识别问题看作是一个二分类问题。下面将详细介绍。
如下图所示,另一种训练神经网络的方法就是选取一对Siamese神经网络,使其同时计算两幅图像的编码,比如是128维的特征,并将这两个特征编码输入一个logistic单元,使得两幅图像表示同一个人时,输出为1,表示不同的人的时候,输出为0。这样就把人脸识别问题转化为一个而分类问题。这是在训练时,可以替换triplet loss的一种训练方法。那最后的logistic unit做了什么呢?我们可以对两张图像的特征向量进行逐元素相减取绝对值,再将取绝对值的结果经过一个sigma**函数得到输出,如果输出为1,认为两张图像是一个人;否则,认为两张图像是两个人。另外,我们还可以如图中所示,将绿色括号括起来的部分换成χ2形式。由于我们训练的是一个Siamese网络,因此这一对网络拥有相同的参数。
最后提一个部署时候的技巧:当网络训练好的时候,对于数据库中的图像,我们可以提前计算好它们的编码,这样我们只需要计算新图像的编码,再与计算好的编码进行比较,得到分类结果,这种trick可以提升我们的计算效率。它不仅可以用在Siamese网络的二分类训练中,还可以用在triplet loss的训练中。
Course 4-Convolutional Neural Networks--Week 4
最后,总结一下,将人脸确认问题当作一个有监督学习问题,创建如下所示的成对图像的训练数据集。当图像对表示同一个人时,标签为1;当图像对表示不同的两个人时,标签为0。下图给出了训练集的样例。使用这样的图像对来训练网络,
Course 4-Convolutional Neural Networks--Week 4

4.6 What is neural style transfer?

卷积神经网络最有意思的应用之一就是neural style transfer了,究竟什么是neural style transfer呢?通过下图的例子进行说明。
Course 4-Convolutional Neural Networks--Week 4
neural style transfer主要就是特征提取,即特征是如何通过不同的卷积层不断提取的。下节将给出关于这些卷积层是如何计算的intuitive。

4.7 What are deep ConvNets learning?

深度卷积网络在学习什么?本节将展示一些可视化的结果,告诉我们那些较深的卷积神经网络在做什么,这对我们实现nerual style transfer有帮助。
我们用下面的例子开始。比如说,我们训练了下图这样的网络,我们想看看不同的隐藏层都在计算什么。我们从第一层的一个隐藏单元开始,在训练集中找出能使该隐藏单元**函数最大的9个图像或图像块。然后对第一层的其他隐藏单元做相同的事情。从图中可以看出,第一个隐藏层的单元学习了一些简单的边缘特征。其实,再深一点的隐藏层单元会学习一些区域特征,更深一点的隐藏单元会学到更全局的特征或部分。
Course 4-Convolutional Neural Networks--Week 4
下图给出了使不同隐藏层中不同隐藏单元**函数最大的9个patches。我们来逐层看一下,第一层检测到的结果都比较简单模式一些不同方向的边缘。
Course 4-Convolutional Neural Networks--Week 4
第二层检测到的结果就是稍微复杂一点的形状或模式。第三层会怎么样呢?
Course 4-Convolutional Neural Networks--Week 4
第三层的输出结果依然很有趣,它已经可以检测车轮、人、以及蜂窝状的东西了,很显然,这一层检测到的模式更加复杂。
Course 4-Convolutional Neural Networks--Week 4
第四层检测到的模式比上一层的又复杂了一些,它不光能检测狗,而且检测到的狗都是长得很像的那一类。
Course 4-Convolutional Neural Networks--Week 4
第五层检测到的东西就更加精细、更加复杂了
Course 4-Convolutional Neural Networks--Week 4
希望以上可以让我们了解神经网络中浅的隐藏层和深的隐藏层都在计算什么,接下来,我们将使用这种直觉来构建neural style transfer算法。

4.8 cost function

为了构建neural style transfer系统,我们先来定义一下生成图像G的代价函数。通过最小化代价函数,我们可以得到我们想要的图像。如下图所示,我们的问题是,给定内容图像C、风格图像S,我们就可以得到生成图像G。因此,为了实现neural style transfer我们将代价函数定义为两部分的和:

J(G)=αJcontent(C,G)+βJstyle(S,G)

其中,Jcontent(C,G)表明内容图像C和生成图像G的内容有多相似,Jstyle(S,G)表明风格图像S和生成图像G的风格有多相似,αβ分别表示了内容代价和风格代价之间的相对权重。此处需要说明的是,看起来使用αβ两个超参数有些冗余,但是提出neural style transfer的作者就使用了两个参数,这里只是follow他的做法。
Course 4-Convolutional Neural Networks--Week 4
定义了代价函数后,算法的运行如下所示。1、首先,随机初始化生成图像G,其中,生成图像G的size是我们自己指定的,本例中指定为100*100*3;2、然后使用梯度下降法来最小化J(G),需要明确的是,在neural style transfer中,我们优化的是生成图像G的每个像素值,即G=GddGJ(G)。举个例子说明一下,内容图像C和风格图像S如图中所示,当我们随机初始化生成图像G后,G如右边第一幅图像所示,全是白噪声点。随着我们不断使用梯度下降法,生成图像G变得越来越像风格图像和内容图像。
Course 4-Convolutional Neural Networks--Week 4

4.9 Content cost function

如上节所示,neural style transfer的代价函数包括两部分:内容代价函数Jcontent(C,G)和风格代价函数Jstyle(S,G)。本节我们主要关注内容代价函数Jcontent(C,G)
我们使用隐藏层l来计算内容代价函数Jcontent(C,G)。如果l很小,比如是1,这会迫使生成图像G的像素值与内容图像C很像(因为浅层是一些基础特征,如线条、颜色等,还不够抽象);然而,当我们使用非常深的隐藏层时,就只是在问,内容图C中是否有狗,然后使生成图中也有狗(抽象度太高,忽略了内容)。实践中,我们选择既不太浅也不太深的隐藏层,即那些处于网络中间的隐藏层。
然后,我们使用一个预训练的ConvNet(可以是VGG或其他一些网络),来看看对于给定的内容图像C和生成图像G,它们在内容方面有多相似。定义a[l](C)a[l](G)分别表示内容图像C和生成图像G在某ConvNet的第l层上的**函数输出(可将它们看作一种既不太简单又不很抽象的图像表示),然后我们通过计算两张图像**函数输出之间的距离(element-wise operation)来衡量内容图像C和生成图像G之间的内容相似性(与之前计算两张图像编码之间的相似度本质是一样的),如果它们是相似的,则内容图像C和生成图像G具有相似的内容。
当然,也可以给内容代价函数加一个标准化系数,如12或其他的数,这没什么关系,因为这会由总代价函数中的超参数α进行调节。
Course 4-Convolutional Neural Networks--Week 4

4.10 Style cost function

上节介绍了内容代价函数的计算,本节介绍风格代价函数的计算。
那么,什么是图像的style呢?如下图所示,假设我们的输入图像是图中所示的三通道图像,对于这样的卷积神经网络,它在不同隐藏层的计算结果都不一样。假设我们选择了如箭头所指的第l层来定义图像风格的深度度量。
接下来,我们定义图像的风格为第l层**函数输出在不同channels间的相关性。具体来说就是,假设第l层**函数输出的大小为nHnWnC,我们会问这个**函数输出在不同channels间的相关性怎么样?
Course 4-Convolutional Neural Networks--Week 4
为了更好的解释说明,我们将**函数输出的通道用不同颜色的阴影表示,方便起见,这里只有5个channels,但实际中的channels数比这个多。为了捕获图像中的风格信息,我们将进行以下操作。我们先计算前两个channels,第一个channel是红色的,第二个channel是黄色的,来计算**函数输出的这两个channels相关性有多大。具体的就是,在两个channels的对应位置会形成很多值对(共有nHnW个),通过比较所有这些值对,得出两个channels的相关性。为什么这样做就能捕获图像风格呢?
Course 4-Convolutional Neural Networks--Week 4
我们来看一个例子。假设红色的channel对应第一行第二列包含的9个patches,从patches可以看出,这个神经元检测的是竖直条状特征(我们已经知道了,某一隐藏层的channel数是上一隐藏层所用的filters数量,不同的filter能检测不同的特征,因此,每一个channel就相当于是一种feature map)。第二个channel对应的是第二行第一列包含的9个patches,从patches可以看出,这个神经元检测的是类似橙色一样的颜色特征。那么,这两个channels相关性高是什么意思呢?就是无论在图像的任何部分,只要这部分有竖直状纹理,这部分很大可能就会有类似橙色这样的颜色。那么如果这两个channels不相关又是什么意思呢?就是出现竖直状纹理的部分不大可能出现橙色系颜色。因此,相关性表明,哪些高级纹理成分会倾向于在图像的区域中同时出现或不同时出现。相关性的程度给出了一种度量这些高级特征同时出现频率的方式
如果我们使用这种通道间的相关性作为风格度量方法,那么我们就可以对生成图像G进行风格度量。生成图像在卷积神经网络第l层隐藏层的**函数输出中,前两个通道的相似性程度与风格图像这两个通道的相似性程度的对比,就是生成图像G与风格图像S的风格对比。
Course 4-Convolutional Neural Networks--Week 4
现在,我们正式的说明这个intuition。如下图所示,对于生成图像G和风格图像S,我们要计算一个风格矩阵,style matrix,我们使用第l层,那么a[l]i,j,k就表示第l层、位置为i,j,k的**函数输出。于是,我们接下来要做的就是对风格图像S,计算在第l层的风格矩阵G[l](S),对生成图像G同样计算风格矩阵G[l](G)
我们先来计算风格图像S的风格矩阵G[l](S),该矩阵的型是nCnC(通道间两两计算)。假设G[l](S)k,k表示第k channel和第k channel的相关性,那么风格矩阵中第k行、第k列的元素计算方法如下

G[l](S)k,k=i=1n[l]Hj=1n[l]Wa[l]i,j,ka[l]i,j,k

即,将两个channels对应位置的值都乘起来,再对所有位置的乘积求和。到目前为止,我们一直使用术语——相关性,其实,按照它的定义方式,这应该叫做非标准化的互协方差,因为我们在做乘法之前并没有减去均值。这就是输入的风格图像S的风格矩阵。
然后,我们对生成图像做同样的事情,生成G[l](G)k,k。如果想区分这些**单元,就可以加上绿色笔迹所示的内容。我们用大写字母G表示这些矩阵,因为在线性代数中,这种矩阵也称为gram matrix。以上就是计算在nCnC的矩阵中,第k,k个元素的值的方法。因此,我们所做的就是对给定的图像计算其风格矩阵。
现在,我们有两个矩阵,分别捕获了风格图像S的风格和生成图像G的风格。于是,在第l层上,图像S和G的风格代价函数J[l]style(S,G)就可以定义为下图中所写的样子,由于G[l](S)G[l](G)都是矩阵,因此是F-范数(两个矩阵中对应位置元素差的平方和)。有时候还会加一些标准化系数,如图中所示,但这也不会有多大影响,因为在总的代价函数公式中,还有个超参数β
Course 4-Convolutional Neural Networks--Week 4
我们来总结一下。下图中所表示的就是定义在隐藏层l上的图像S和G的风格损失函数,这种形式就是F-范数的计算形式。最后,如果我们使用多个隐含层来计算两张图像的风格代价函数,使得我们能同时考虑到低级特征和高级特征,会得到视觉上效果更好的图像。因此,总的风格代价函数Jstyle(S,G)可以写为各个层上的风格代价函数的加权和,而权重又是一种超参数λ[l]。在本节的编程练习中,会对如何选择权重λ有更多认识。
有了总的代价函数J(G),我们可以使用梯度下降或其他优化方法来最小化代价函数,最终得到一个好的风格转换图像。
Course 4-Convolutional Neural Networks--Week 4
在结束本周课程之前,还想介绍下怎么样在1D或3D数据上做卷积,我们之前一直在2D数据上做的卷积。

4.11 Convolutional networks in 1D or 3D

我们已经知道了如何在2D图像上进行卷积操作,那么如何在1D和3D上进行卷积操作呢?
如下图所示,对1D数据进行卷积,其filter也是1D的。如果1D数据有多个channels,那么filter的channels数和1D数据的channels数相同。
Course 4-Convolutional Neural Networks--Week 4
那什么是3D数据呢?一部电影就是3D数据,因为它是由很多图像帧组成的。
Course 4-Convolutional Neural Networks--Week 4
对于3D数据,它的三个维度分别对应数据的height、width、depth,如果有多个channels,则将channels写在后面。相对应的filter也是3D的,也具有height、width、depth、channels(如果有多个channels的话)
Course 4-Convolutional Neural Networks--Week 4
在下节课RNN中,我们将会介绍时序模型,不过在这里,CNN也能处理时间序列。