吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

第四周 特殊应用:人脸识别和神经风格转换

一、什么是人脸识别?

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

首先,让我们了解一下人脸识别的一些术语。

主要是人脸验证(face verification)和人脸识别(face recognition)。

人脸验证问题:

如果你有一张输入图片,以及某人的ID或者是名字,这个系统要做的是,验证输入图片是否是这个人。有时候也被称作1对1问题。

人脸识别问题:

而人脸识别问题比人脸验证问题难很多。验证系统是一对一,而识别系统是一对多,对于100个人的人脸识别系统,识别上,犯错的机会会是验证的100倍。因此,如果我们构造的验证系统的准确率需要为99.9%或者更高,然后才可以在100人的数据库上运行,而保证有很大几率不出错。

二、 One-Shot学习

在大多数人脸识别应用中,我们需要通过单单一张图片或者单单一个人脸样例就能去识别这个人。

下面是一个例子:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

已有数据库中有4个人,现在进来一个人(1号),系统需要识别出她是这四个人中的第二个,接着进来一个人(2号),系统需要识别出她不是这四个人中的任何一个人。

第一种办法:

将人的照片放进卷积神经网络中,使用softmax单元来输出4种,或者说5种标签,分别对应这4个人,或者4个都不是,所以softmax里我们会有5种输出。但实际上这样效果并不好,因为如此小的训练集不足以去训练一个稳健的神经网络。

另外,假如有新人加入,输出就变成了6种,这时需要重新训练神经网络,所以这不是一个好办法。

第二种方法:

学习Similarity函数。详细地说,你想要神经网络学习这样一个函数d:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

它以两张图片作为输入,然后输出这两张图片的差异值。即如果放进同一个人的两张照片,它的输出值很小,如果放进两个长相差别很大的人的照片,它就输出一个很大的值。

所以在识别过程中,如果这两张图片的差异值小于某个阈值τ,那么这时就能预测这两张图片是同一个人,如果差异值大于τ,就能预测这是不同的两个人。这是一个可行的办法。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别
拿这张新图片,用函数d去分别与这四张图片比较,这样根据输出的值得大小来判断是这四个人中的哪一个。对应的,如果这个图片(人)不在数据库中,函数d会输出一个很大的值,比其他的都大,这就证明这个人并不是数据库中4个人的其中一个。

如果之后有新人加入数据库,我们只需将他的照片加入数据库即可,系统依然能照常工作。

三、 Siamese 网络

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

一个卷积网络,输入图片x^(1) ,然后通过一系列卷积,池化和全连接层,最终得到128维的特征向量(f(x^(1)) 。以前会接着送进softmax单元来做分类,但此时我们不这么做。我们把f(x^(1)) 看作是输入图像x^(1) 的编码。

如果要比较x^(1) 和x^(2) 这两个图片,我们需要把第二张图片喂给有同样参数的同样的神经网络,然后得到一个不同的128维的向量,这个向量f(x^(2) )代表或者编码第二个图片。这里用x^(1) 和x^(2) 仅仅代表两个输入图片,可以是任意两个图片。

最后如果这些编码很好地代表了这两个图片,接下来要做的就是定义函数d,将x^(1) 和x^(2)的距离定义为这两幅图片的编码之差的范数,即:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

对于两个不同的输入,运行相同的卷积神经网络,然后比较它们,这就是Siamese网络架构。

训练这个Siamese神经网络:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

这两个网络有相同的参数,所以实际上就是训练一个网络。它计算得到的编码可以用于函数d,进而判断两张图片是否是同一个人。更准确地说,神经网络的参数定义了一个编码函数f(x^(i)) ,我们要做的就是学习参数,使得如果两个图片如果是同一个人,那么得到的两个编码的距离就小。相反,如果是不同的人,那么让它们之间的编码距离大一点。

如果改变这个网络所有层的参数,就会得到不同的编码结果,我们要做的就是用反向传播来改变这些所有的参数,以确保满足这些条件。

四、 Triplet 损失

4.1三元组损失

要想通过学习神经网络的参数来得到优质的人脸图片编码,方法之一就是定义三元组损失函数然后应用梯度下降。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

我们要做的通常是看一个 Anchor 图片,让Anchor图片和Positive图片(Positive意味着是同一个人)的距离很接近,让Anchor图片与Negative图片(Negative意味着是非同一个人)的距离离得更远一点。

这就是为什么叫做三元组损失,也就是我们通常会同时看三张图片:Anchor图片、Postive图片,还有Negative图片。

把这些写成公式的话,我们想要的是网络的参数或者编码能够满足以下特性:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

现在把方程右边项移到左边,然后做一些小的改变,最终就得到:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别
改变的原因:

有一种情况,就是把所有的东西都学成0,如果f总是输出0,即0-0≤0,这就是0减去0还等于0,如果所有图像的f都是一个零向量,那么总能满足这个方程。所以为了确保网络对于所有的编码不会总是输出0,也为了确保它不会把所有的编码都设成互相相等的。

另一种情况,就是如果每个图片的编码和其他图片一样,这种情况,你还是得到0-0。

所以为了阻止网络出现这种情况,我们需要修改这个目标,也就是,这个不能是刚好小于等于0,应该是比0还要小。所以加上了一个超参数α,α也叫做间隔。

举个例子,假如间隔设置成0.2,在这个例子中,d(A,P) =0.5,如果d(A,N)只大一点,比如说0.51,条件就不能满足,d(A,N)至少是0.7或者更高。这就是间隔参数α的作用。它拉大了AnchorPositive 图片对和AnchorNegative 图片对之间的差距。

4.2 三元组损失函数:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

三元组损失函数的定义基于三张图片,为了定义这个损失函数,我们取前面那个式子和0的最大值,这个max函数的作用就是,只要这个式子小于等于0,那么损失函数就是0。所以只要能使这个式子小于等于0,我们就能达到目标损失值为0。

另一方面,如果这个式子大于0,损失函数就会取这个式子的值,这样会得到一个正的损失值。然后通过最小化这个损失函数达到的效果就是使这个式子成为0,或者小于等于0。只要这个损失函数小于等于0,网络不会关心它负值有多大。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

整个网络的代价函数应该是训练集中这些单个三元组损失的总和。

假如有一个10000个图片的训练集,里面是1000个不同的人的照片,我们要做的就是取这10000个图片,然后生成这样的三元组,然后训练我们的学习算法,对这种代价函数用梯度下降。

另外,为了定义三元组的数据集我们需要成对的A和P,即同一个人的成对的图片,这是为什么在有1000个不同的人的10000张照片。如果你只有每个人一张照片,那么根本没法训练这个系统。

4.3 选择这些三元组来形成训练集:

如果从训练集中,随机地选择A、P和N,遵守A和P是同一个人,而A和N是不同的人这一原则。有个问题就是,如果随机的选择它们,A和N比A和P差别很大的概率很大。但是如果A和N是随机选择的不同的人,有很大的可能性d(A,N)会比d(A,P)大,而且差距远大于α,这样网络并不能从中学到什么。

所以为了构建一个数据集,我们要做的就是尽可能选择难训练的三元组A、P和N。具体而言,难训练的三元组就是,A、P和N的选择使得d(A,P)很接近d(A,N),这样学习算法会竭尽全力使d(A,N)变大,或者使d(A,P)变小,这样左右两边至少有一个α的间隔。并且选择这样的三元组还可以增加学习算法的计算效率,如果随机的选择这些三元组,其中有太多会很简单,梯度算法不会有什么效果,因为网络总是很轻松就能得到正确的结果,只有选择难的三元组梯度下降法才能发挥作用,使得这两边离得尽可能远。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

定义了这些包括A、P和N图片的数据集之后,我们还需要做的就是用梯度下降最小化我们之前定义的代价函数J,这样做的效果就是反向传播到网络中的所有参数来学习到一种编码,使得如果两个图片是同一个人,那么它们的d就会很小,如果两个图片不是同一个人,它们的d就会很大。

五、人脸验证与二分类

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

另一个训练神经网络的方法是选取一对神经网络,选取Siamese网络,使其同时计算这些嵌入,比如说128维的嵌入,或者更高维,然后将其输入到逻辑回归单元,然后进行预测,如果是相同的人,那么输出是1,若是不同的人,输出是0。

这就把人脸识别问题转换为一个二分类问题。

最后的逻辑回归单元,使用sigmoid函数应用到某些特征上,相比起直接放入这些编码,我们可以利用编码之间的不同。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

符号f( x^( i))代表图片x^(i)的编码,下标k代表选择这个向量中的第k个元素。把这128个元素当作特征,然后把他们放入逻辑回归中,最后的逻辑回归可以增加参数w_{i}和b,就像普通的逻辑回归一样。然后在这128个单元上训练合适的权重,用来预测两张图片是否是一个人,输出0或者1,即是否是同一个人。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

还有其他不同的形式来计算| f( x^{( i)}){k} - f( x^{( j)}){k}|,这个公式被叫做X^{2}公式,是一个希腊字母X,也被称为X平方相似度。

但是在这个学习公式中,输入是一对图片,输出y是0或者1,取决于输入是相似图片还是非相似图片。与之前类似,两个神经网络拥有的相同的参数,这样的系统效果很好。

有一个计算技巧可以显著提高部署效果:

不需要每次都计算这些特征,而是提前计算好数据库中的图片的特征,那么有一个人进来时,可以使用上方的卷积网络来计算这些编码,然后使用它,和预先计算好的编码进行比较,然后输出预测值y。

这个预先计算的思想,在有一个很大的员工数据库的情况下,可以节省大量的计算。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

总结一下,把人脸验证当作一个监督学习,创建一个只有成对图片的训练集,不是三个一组,而是成对的图片,目标标签是1表示一对图片是一个人,目标标签是0表示图片中是不同的人。利用不同的成对图片,使用反向传播算法去训练神经网络,训练Siamese神经网络。

六、 神经风格迁移

什么是神经风格迁移?先看看一个例子:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

为了描述如何实现神经网络迁移,我将使用C来表示内容图像,S表示风格图像,G表示生成的图像。

为了实现神经风格迁移,你需要知道卷积网络提取的特征,在不同的神经网络,深层的、浅层的。

6.1 CNN特征可视化

理解卷积网络中深度较大的层真正在做什么有助于理解如何实现神经风格迁移。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

来看一个例子,假如我们训练了一个卷积神经网络,是一个Alexnet,希望看到不同层之间隐藏单元的计算结果。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

从第一层的隐藏单元开始,训练集经过神经网络,然后弄明白哪一张图片最大限度地**特定的单元。在第一层的隐藏单元,只能看到小部分卷积神经,只有一小块图片块是有意义的,因为这就是特定单元所能看到的全部。选择一个隐藏单元,发现有9个图片最大化了单元**,找到了像这样的边缘或者线,这就是那9个最大化地**了隐藏单元**项的图片块。

然后选一个另一个第一层的隐藏单元,重复刚才的步骤。对其他隐藏单元也进行处理,会发现其他隐藏单元趋向于**类似于这样的带边缘或者线的图片。

以此类推,这是9个不同的代表性神经元,每一个不同的图片块都最大化地**了。可以这样理解,第一层的隐藏单元通常会找一些简单的特征,比如说边缘或者颜色阴影。

而在深层部分,一个隐藏单元会看到一张图片更大的部分。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

我们放大一点来看:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

第二层,检测到了更复杂的形状和模式,比如说有的隐藏单元会找到有很多垂线的垂直图案,有的隐藏单元在左侧有圆形图案时会被高度**,有的特征是很细的垂线,以此类推,第二层检测的特征变得更加复杂。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

第三层,有的隐藏单元对图像左下角的圆形很敏感,所以检测到很多车。有的开始检测到人类,有的检测特定的图案,蜂窝形状或者方形,类似这样规律的图案。有些很难看出来,需要手动弄明白检测到什么,但是第三层明显,检测到更复杂的模式。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

第四层,检测到的模式和特征更加复杂,有的学习成了一个狗的检测器。有的隐藏单元它检测水吗或者检测到鸟的脚等等。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

第五层,检测到更加复杂的事物,有的是一个狗检测器,但是可以检测到的狗更加多样性。有的可以检测到键盘,或者是键盘质地的物体,可能是有很多点的物体。有的可能检测到文本,有的检测到花。

总体上,从检测简单的事物到复杂的事物,比如说,第一层的边缘,第二层的质地,到深层的复杂物体。

6.2 神经风格迁移的代价函数

6.2.1 代价函数

要构建一个神经风格迁移系统,需要为生成的图像定义一个代价函数,通过最小化代价函数,我们可以生成想要的任何图像。

我们的问题是,给一个内容图像C,给定一个风格图片S,而目标是生成一个新图片G。为了实现神经风格迁移,要做的是定义一个关于G的代价函数J用来评判某个生成图像的好坏,我们将使用梯度下降法去最小化J(G),以便于生成这个图像。

我们把这个代价函数定义为两个部分:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

第一部分被称作内容代价,这是一个关于内容图片和生成图片的函数,它是用来度量生成图片G的内容与内容图片C的内容有多相似。

第二部分是一个风格代价函数,也就是关于S和G的函数,用来度量图片G的风格和图片S的风格的相似度。

最后我们用两个超参数来来确定内容代价和风格代价,两者之间的权重用两个超参数来确定。(两个代价的权重似乎是多余的,一个超参数就够了,但提出神经风格迁移的原始作者使用了两个不同的超参数,所以这里保持一致。)

6.2.2 算法

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

算法的运行是这样的,对于代价函数J(G),为了生成一个新图像,接下来要做的是随机初始化生成图像G,它可能是100×100×3,可能是500×500×3,又或者是任何你想要的尺寸。

然后使用在之前定义的代价函数J(G),接着是使用梯度下降的方法将其最小化,更新:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

在这个步骤中,实际上更新的是图像G的像素值,也就是100×100×3,比如RGB通道的图片。

这里有个例子:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别
吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

假设从这两张图片开始,随机初始化G,随机初始化的生成图像就是这张随机选取像素的白噪声图。接下来运行梯度下降算法,最小化代价函数J(G),逐步处理像素,这样慢慢得到一个生成图片,越来越像用风格图片的风格画出来的内容图片。

6.3神经风格迁移的内容代价函数

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

假如说,用隐含层l来计算内容代价,如果l是个很小的数,比如用隐含层1,这个代价函数就会使我们的生成图片像素上非常接近我们的内容图片。然而如果用很深的层,那么那就会问,内容图片里是否有狗,然后它就会确保生成图片里有一个狗。所以在实际中,这个层l在网络中既不会选的太浅也不会选的太深。

接下来需要衡量一个内容图片和一个生成图片他们在内容上的相似度,我们令这个α^(l) 和a^(l),代表这两个图片C和G的l层的**函数值。如果这两个**值相似,那么就意味着两个图片的内容相似。

接下来定义这个代价函数:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

在前面加上归一化或者不加,都影响不大,因为这都可以由这个超参数α来调整。

这里用的符号都是展成向量形式的,在把他们展成向量后。这就是两个**值间的差值平方和,这就是两个图片之间l层**值差值的平方和。后面如果对J(G)做梯度下降来找G的值时,整个代价函数会激励这个算法来找到图像G,使得隐含层的**值和内容图像的相似。

6.4神经风格迁移的风格代价函数

6.4.1图片的风格

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

比如有这样一张图片,它含有不同隐藏层。现在选择了某一层l,这一层的**项去为图片的风格定义一个深度测量,接着就是将图片的风格定义为l层中各个通道之间**项的相关系数。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

现在将l层的**项取出,这是个 n_{H} × n_{W} × n_{C}的**项,它是一个三维的数据块。可是如何知道这些不同通道之间**项的相关系数呢?

为了很好的解释这个问题,我们把它的不同通道渲染成不同的颜色。在这个例子中,假设我们有5个通道,为了方便讲解,将它们染成了五种颜色。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

为了能捕捉图片的风格,需要进行下面这些操作,首先,先看前两个通道,前两个通道分别是图中的红色和黄色部分,我们要计算这两个通道间**项的相关系数。

举个例子:

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

我们知道,这个红色的通道对应的神经元能找出图片中的特定位置是否含有这些垂直的纹理,而黄色的通道对应的这个神经元可以粗略地找出橙色的区域。如果它们有高度相关性,那么这幅图片中出现垂直纹理的地方很大概率是橙色的。如果说它们是不相关的,这意味着图片中有垂直纹理的地方很大概率不是橙色的。

相关系数这个概念提供了一种去测量这些不同的特征的方法,比如这些垂直纹理,这些橙色或是其他的特征去测量它们在图片中的各个位置同时出现或不同时出现的频率。

如果我们在通道之间使用相关系数来描述通道的风格,通过测量,我们能得知在生成的图像中垂直纹理和橙色同时出现或者不同时出现的频率,这样我们将能够测量生成的图像的风格与输入的风格图像的相似程度。

现在我们来公式化这种说法:

对于这两个图像,也就是风格图像与生成图像,需要计算一个风格矩阵,说得更具体一点就是用l层来测量风格。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

我们设$α_{i,\ j,\ k}^{[l]} l(i,j,k)为隐藏层l中(i,j,k)位置的**项,ijk分别代表该位置的高度、宽度以及对应的通道数。现在要做的就是去计算一个关于l层和风格图像的矩阵,即G{[l](S)}$($l$表示层数,$S$表示风格图像),这($G{l})是一个n_{c} \times n_{c}$的矩阵,同样地,我们也对生成的图像进行这个操作。

但是现在我们先来定义风格图像,设这个关于ll层和风格图像的,GG是一个矩阵,这个矩阵的高度和宽度都是ll层的通道数。在这个矩阵中kkkk'元素被用来描述kk通道和kk'通道之间的相关系数。具体地:

Gkk[l](S)=i=1nH[l]j=1nW[l]ai, j, k[l](S)ai, j, k[l](S)G_{kk^{'}}^{[l]( S)} = \sum_{i = 1}^{n_{H}^{[l]}}{\sum_{j = 1}^{n_{W}^{[l]}}{a_{i,\ j,\ k}^{[l](S)}a_{i,\ j,\ k^{'}}^{[l](S)}}}

用符号iijj表示下界,对iijjkk位置的**项ai, j, k[l]a_{i,\ j,\ k}^{[l]},乘以同样位置的**项,也就是ii,$ j,,k’位置的**项,即a_{i,j,k{’}}{[l]},将它们两个相乘。然后ijl分别加到l层的高度和宽度,即n_{H}{[l]}$和$n_{W}{[l]},将这些不同位置的**项都加起来。(i,j,k)(i,j,k’)x坐标和y坐标分别对应高度和宽度,将k通道和k’$通道上这些位置的**项都进行相乘。我一直以来用的这个公式,严格来说,它是一种非标准的互相关函数,因为我们没有减去平均数,而是将它们直接相乘。

这就是输入的风格图像所构成的风格矩阵,然后,我们再对生成图像做同样的操作。

Gkk[l](G)=i=1nH[l]j=1nW[l]ai, j, k[l](G)ai, j, k[l](G)G_{kk^{'}}^{[l]( G)} = \sum_{i = 1}^{n_{H}^{[l]}}{\sum_{j = 1}^{n_{W}^{[l]}}{a_{i,\ j,\ k}^{[l](G)}a_{i,\ j,\ k^{'}}^{[l](G)}}}

ai, j, k[l](S)a_{i,\ j,\ k}^{[l](S)}ai,j,k[l](G)a_{i, j,k}^{[l](G)}中的上标(S)(S)(G)(G)分别表示在风格图像SS中的**项和在生成图像GG的**项。我们之所以用大写字母GG来代表这些风格矩阵,是因为在线性代数中这种矩阵有时也叫Gram矩阵,但在这里我只把它们叫做风格矩阵。

所以我们要做的就是计算出这张图像的风格矩阵,以便能够测量出刚才所说的这些相关系数。更正规地来表示,我们用ai,j,k[l]a_{i,j,k}^{[l]}来记录相应位置的**项,也就是ll层中的i,j,ki,j,k位置,所以ii代表高度,jj代表宽度,kk代表着ll中的不同通道。之前说过,我们有5个通道,所以kk就代表这五个不同的通道。

对于这个风格矩阵,我们要做的就是计算这个矩阵也就是G[l]G^{[l]}矩阵,它是个nc×ncn_{c} \times n_{c}的矩阵,也就是一个方阵。记住,因为这里有ncn_{c}个通道,所以矩阵的大小是nc×ncn_{c}\times n_{c}。以便计算每一对**项的相关系数,所以Gkk[l]G_{\text{kk}^{'}}^{[l]}可以用来测量kk通道与kk'通道中的**项之间的相关系数,kkkk'会在1到ncn_{c}之间取值,ncn_{c}就是ll层中通道的总数量。

当在计算G[l]G^{[l]}时,下标kkkk’只代表一种元素,所以需要在右下角标明是kkkk'元素,和之前一样iijj从一开始往上加,对应(i,j,k)(i,j,k)位置的**项与对应(i,j,k)(i, j, k')位置的**项相乘。记住,这个iijj是**块中对应位置的坐标,也就是该**项所在的高和宽,所以ii会从1加到nH[l]n_{H}^{[l]}jj会从1加到nW[l]n_{W}^{[l]}kkkk'则表示对应的通道,所以kkkk'值的范围是从1开始到这个神经网络中该层的通道数量nC[l]n_{C}^{[l]}。这个式子就是把图中各个高度和宽度的**项都遍历一遍,并将kkkk'通道中对应位置的**项都进行相乘,这就是Gkk[l]G_{{kk}^{'}}^{[l]}的定义。通过对kkkk'通道中所有的数值进行计算就得到了GG矩阵,也就是风格矩阵。

Gkk[l]=i=1nH[l]j=1nW[l]ai, j, k[l]ai, j, k[l]G_{kk^{'}}^{[l]} = \sum_{i = 1}^{n_{H}^{[l]}}{\sum_{j = 1}^{n_{W}^{[l]}}{a_{i,\ j,\ k}^{[l]}a_{i,\ j,\ k^{'}}^{[l]}}}

要注意,如果两个通道中的**项数值都很大,那么Gkk[l]G_{{kk}^{'}}^{[l]}也会变得很大,对应地,如果他们不相关那么Gkk[l]G_{{kk}^{'}}^{[l]}就会很小。严格来讲,它其实是一种非标准的互协方差,因为我们并没有减去均值而只是把这些元素直接相乘,这就是计算图像风格的方法。

Gkk[l](S)=i=1nH[l]j=1nW[l]ai, j, k[l](S)ai, j, k[l](S)G_{kk^{'}}^{[l]( S)} = \sum_{i = 1}^{n_{H}^{[l]}}{\sum_{j = 1}^{n_{W}^{[l]}}{a_{i,\ j,\ k}^{[l](S)}a_{i,\ j,\ k^{'}}^{[l](S)}}}

我们要同时对风格图像SS和生成图像GG都进行这个运算,为了区分它们,我们在它的右上角加一个(S)(S),表明它是风格图像SS,这些都是风格图像S中的**项,之后需要对生成图像也做相同的运算。

Gkk[l](G)=i=1nH[l]j=1nW[l]ai, j, k[l](G)ai, j, k[l](G)G_{kk^{'}}^{[l]( G)} = \sum_{i = 1}^{n_{H}^{[l]}}{\sum_{j = 1}^{n_{W}^{[l]}}{a_{i,\ j,\ k}^{[l](G)}a_{i,\ j,\ k^{'}}^{[l](G)}}}

和之前一样,再把公式都写一遍,把这些都加起来,为了区分它是生成图像,在这里放一个(G)(G)

现在,我们有2个矩阵,分别从风格图像SS和生成图像GG

我们一直使用大写字母GG来表示矩阵,是因为在线性代数中,这种矩阵被称为Gram矩阵,但在本视频中我把它叫做风格矩阵,我们取了Gram矩阵的首字母GG来表示这些风格矩阵。

最后,如果我们将SSGG代入到风格代价函数中去计算,这将得到这两个矩阵之间的误差,因为它们是矩阵,所以在这里加一个FFFrobenius范数),这实际上是计算两个矩阵对应元素相减的平方的和,我们把这个式子展开,从kkkk'开始作它们的差,把对应的式子写下来,然后把得到的结果都加起来,作者在这里使用了一个归一化常数,也就是12nH[l]lnW[l]nC[l]\frac{1}{2n_{H}^{[l]l}n_{W}^{[l]}n_{C}^{[l]}},再在外面加一个平方,但是一般情况下不用写这么多,一般我们只要将它乘以一个超参数β\beta就行。

最后,这是对ll层定义的风格代价函数,和之前见到的一样,这是两个矩阵间一个基本的Frobenius范数,也就是SS图像和GG图像之间的范数再乘上一个归一化常数。实际上,如果对各层都使用风格代价函数,会让结果变得更好。如果要对各层都使用风格代价函数,我们可以这么定义代价函数,把各个层的结果(各层的风格代价函数)都加起来,这样就能定义它们全体了。我们还需要对每个层定义权重,也就是一些额外的超参数,我们用λ[l]\lambda^{[l]}来表示,这样将使你能够在神经网络中使用不同的层,包括之前的一些可以测量类似边缘这样的低级特征的层,以及之后的一些能测量高级特征的层,使得我们的神经网络在计算风格时能够同时考虑到这些低级和高级特征的相关系数。这样,在基础的训练中我们在定义超参数时,可以尽可能的得到更合理的选择。

为了把这些东西封装起来,现在可以定义一个全体代价函数:

J(G)=aJcontent(C,G)+βJstyle(S,G)J(G) = a J_{\text{content}( C,G)} + \beta J_{{style}}(S,G)

之后用梯度下降法,或者更复杂的优化算法来找到一个合适的图像GG,并计算J(G)J(G)的最小值,这样的话,将能够得到非常不错的结果。

七、一维到三维推广

我们已经学习了许多关于卷积神经网络的知识,从卷积神经网络框架,到如何使用它进行图像识别、对象检测、人脸识别与神经网络转换。即使我们大部分讨论的图像数据,某种意义上而言都是2D数据,考虑到图像如此普遍,许多所掌握的思想不仅局限于2D图像,甚至可以延伸至1D,乃至3D数据。

7.1 一维数据

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

2D卷积,输入一个14×14的图像,并使用一个5×5的过滤器进行卷积,通过这个操作得到10×10的输出。如果使用了多通道,比如14×14×3,那么相匹配的过滤器可能是5×5×3,如果使用了多重过滤,比如16,最终你得到的是10×10×16。

事实证明,这个想法也同样可以用于1维数据,举个例子,左边是心电图(EKG信号),每一个峰值都对应着一次心跳。如果想使用EKG信号进行医学诊断,那么我们将处理1维数据,因为EKG数据是由时间序列对应的每个瞬间的电压组成,这次不是一个14×14的尺寸输入,而可能只有一个14尺寸输入,在这种情况下需要使用一个1维过滤进行卷积,且只需要一个1×5的过滤器,而不是一个5×5的。

二维数据的卷积是将同一个5×5特征检测器应用于图像中不同的位置,最后会得到10×10的输出结果。

所有这些二维的方法也可以应用于1维数据,我们可以在不同的位置使用相同的特征检测器,比如说,为了区分EKG信号中的心跳的差异,可以在不同的时间轴位置使用同样的特征来检测心跳。

所以卷积网络同样可以被用于1D数据,对于许多1维数据应用,实际上会使用递归神经网络进行处理,但是有些人依旧愿意尝试使用卷积网络解决这些问题。

7.2 三维数据

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

CT扫描为例,这是一种使用X光照射,然后输出身体的3D模型,CT扫描实现的是它可以获取你身体不同片段。

假设3D数据现在具备一定长度、宽度与高度,其中每一个切片都与躯干的切片对应。如果我们想要在3D扫描或CT扫描中应用卷积网络进行特征识别,我们可以从2D和1D里得到想法,并将其应用到3D卷积中。为了简单起见,假设有一个14×14×14的3D对象(图像不是必须以矩形呈现,3D对象也不是一定是一个完美立方体,所以长和宽可以不一样,同样CT扫描结果的长宽高也可以是不一致的。为了简化讨论,我仅使用14×14×14为例)。

吴恩达神经网络和深度学习课程自学笔记(十二)之人脸识别

如果现在使用5×5×5过滤器进行卷积,过滤器现在也是3D的,这将会给你一个10×10×10的结果输出,因为这是一个3D模块,所以过滤器需要再乘1,因为通道的数目必须与过滤器匹配。如果你使用16个过滤器处理5×5×5×1,接下来的输出将是10×10×10×16,这将成为3D数据卷积网络上的一层。

接着下一层卷积使用5×5×5×16维度的过滤器再次卷积,通道数目也与往常一样匹配,如果有32个过滤器,操作也与之前相同,最终你得到一个6×6×6×32的输出。

某种程度上3D数据也可以使用3D卷积网络学习,这些过滤器实现的功能正是通过你的3D数据进行特征检测。CT医疗扫描是3D数据的一个实例,另一个数据处理的例子是你可以将电影中随时间变化的不同视频切片看作是3D数据,你可以将这个技术用于检测动作及人物行为。