上周4-3 Coursera吴恩达《卷积神经网络》 第三周课程笔记-目标检测我们学习的主要内容是目标检测(object detection)(计算机视觉领域中一个新兴的应用方向)的相关概念:目标定位,特征点检测,交并比函数,非极大值抑制和候选区域等,以及讲解了一些论文(YOLO、R-CNN、Fast R-CNN和Faster R-CNN等)。欢迎来到第四周,即这门课卷积神经网络课程的最后一周(last week)。到目前为止,我们已经学了很多卷积神经网络的知识。本周将展示一些重要的卷积神经网络的特殊应用,我们将从人脸识别(face recognition)开始,之后讲神经风格迁移(neural style transfer),同时介绍了一些经典的论文(附加论文的下载链接),那我们开始吧。
目录
《4.1 什么是人脸识别》What is face recognition?
《4.2 One-Shot学习》One-shot learning
《4.3 Siamese 网络》Siamese network
《4.5 人脸验证与二分类》Face verification and binary classification
《4.6 什么是神经风格迁移?》What is neural style transfer?
《4.7 深度卷积网络学习什么?》What are deep ConvNets learning?
《4.9 内容代价函数》Content cost function
《4.10 风格代价函数》Style cost function
《4.11 一维到三维的推广》1D and 3D generalizations of models
《4.1 什么是人脸识别》What is face recognition?
从人脸识别开始,这里Andrew演示了百度的人脸识别系统(face recognition system)。

视频在百度的中国总部,进入公司不需要刷工卡,使用人脸识别,机器会识别人脸,然后可通过。

林元庆,IDL(百度深度学习实验室)的主管,尝试拿着Andrew的工卡,用头像照片而不是真人来通过,系统拒绝识别。
这个视频展示了人脸识别(face recognition)和活体检测(liveness detection),后一项技术确认你是一个活人。事实上,活体检测可以使用监督学习(supervised learning)来实现,去预测是不是一个真人。下面主要想讲的是,如何构造这个系统中的人脸识别这一部分。首先,了解一下人脸识别的术语。

在人脸识别的相关文献中,经常提到人脸验证(face verification)和人脸识别(face recognition)。这是人脸验证问题,如果你有一张输入图片,以及某人的ID或者是名字,这个系统要做的是,验证输入图片是否是这个人。这也被称作1对1问题,只需要弄明白这个人是否和他声称的身份相符。
而人脸识别问题比人脸验证问题难很多(1对多问题(1:K))。假设有一个验证系统,准确率是99%,还可以。如果你把这个验证系统应用在100个人的人脸识别上,犯错的机会就是100倍了。如果每个人犯错的概率是1%,如果你有一个上百人的数据库,如果你想得到一个可接受的识别误差或者构造一个验证系统,其准确率为99.9%或者更高,然后才可以在100人的数据库上运行,而保证有很大几率不出错。事实上,如果我们有一个100人的数据库,正确率可能需要远大于99%,才能得到很好的效果。
之后的几个视频主要讲如何构造人脸验证,作为基本模块(building block),如果准确率够高,你就可以把它用在识别系统上。
《4.2 One-Shot学习》One-shot learning
人脸识别所面临的一个挑战就是需要解决一次学习问题(one-shot learning problem),这意味着在大多数人脸识别应用中,你需要通过单单一张图片或者单单一个人脸样例就能去识别这个人。而历史上,当深度学习只有一个训练样例时,它的表现并不好,让我们看一个直观的例子,并讨论如何去解决这个问题。

如上图,假设数据库里有4张员工照片(deeplearning.ai的员工),分别是Kian,Danielle,Younes和Tian。现在假设有个人来到办公室,并且她想通过带有人脸识别系统的栅门,现在系统需要做的就是,仅仅通过一张已有的Danielle照片,来识别前面这个人确实是她。相反,如果机器看到一个不在数据库里的人,机器应该能分辨出她不是数据库中四个人之一。所以在一次学习问题中,只能通过一个样本进行学习,以能够认出同一个人。
有一种办法是,将人的照片放进卷积神经网络中,使用softmax单元来输出4种,或者说5种标签,分别对应这4个人,或者4个都不是,所以softmax里我们会有5种输出。但实际上这样效果并不好,因为如此小的训练集不足以去训练一个稳健的神经网络。而且如果有新人加入,难道重新训练神经网络吗?
所以要让人脸识别能够做到一次学习,为了能有更好的效果,你现在要做的应该是学习Similarity函数。

详细地说,神经网络要学习这样一个用d表示的函数,
![]()
上述公式以两张图片作为输入,然后输出这两张图片的差异值。如果输入同一个人的两张照片,你希望输出一个很小的值;如果输入两个长相差别很大的人的照片,则希望输出一个很大的值。在识别过程中,一般设置阈值,它是一个超参数。如果d大于阈值,则预测是两个不同的人。这是解决人脸验证的一个可行方法。
要注意这个过程中是如何解决一次学习问题的,只要你能学习这个函数d,通过输入一对图片,它将会告诉你这两张图片是否是同一个人。如果之后有新人加入,只需将他的照片加入数据库,系统依然能照常工作。
现在我们已经知道函数d是如何工作的,通过输入两张照片,它将让你能够解决一次学习问题。那么,下节视频中,我们将会学习如何训练神经网络学会这个函数d。
《4.3 Siamese 网络》Siamese network
上个视频函数d的作用就是输入两张人脸图片,然后输出相似度。实现这个功能的一个方式就是用Siamese网络。

上图是常见的卷积网络,输入图片x^(1),然后经过卷积层、池化层和全连接层,最终得到特征向量。假如它有128个数,它是由网络深层的全连接层计算出来的,给这128个数命个名字,f(x^(1)),可以看成是图像x^(1)的编码。建立一个人脸识别系统的方法就是:如果要比较两个图片的话,把第二张图片x^(2)喂给有同样参数的神经网络,然后得到一个不同的128维向量。这里x^(1)和x^(2)仅代表两个输入图片,是任意两个图片。
接下来定义d,将x^(1)和x^(2)的距离定义为这两种图片编码之差的范数:
![]()
对于两个不同的输入,运行相同的卷积神经网络,然后比较它们,这一般叫做Siamese网络架构(Siamese neural network architecture)。这里提到的很多观点,都来自于Yaniv Taigman,Ming Yang,Marc’ Aurelio Ranzato,Lior Wolf的这篇论文:DeepFace: Closing the gap to human-level performance in face verification
他们开发的系统叫做DeepFace。怎么训练这个Siamese神经网络呢?

由于两个网络有相同的参数,因此就是训练一个网络。你要做的就是学习参数,如果两张图片是同一个人,那两个编码的距离就很小;如果是不同的人,编码距离就大一些。如果你改变这个网络所有层的参数,你会得到不同的编码结果,你要做的就是用反向传播(back propagation)来改变这些所有的参数,以确保满足这些条件。
现在你已经了解了Siamese网络架构,并且知道你想要网络输出什么,即什么是好的编码。但是如何定义实际的目标函数(define an objective function),能够让你的神经网络学习并做到我们刚才讨论的内容呢?在下一个视频里,我们会看到如何用三元组损失函数达到这个目的。
《4.4 Triplet 损失》Triplet loss
要想通过学习神经网络的参数来得到优质的人脸图片编码,方法之一就是定义三元组损失函数(triplet loss function),然后应用梯度下降。

为了应用三元组损失函数,你需要比较成对的图像。用三元组损失的术语来说,你要做的通常是看一个 Anchor 图片,你想让Anchor图片和Positive图片(Positive意味着是同一个人)的距离很接近。然而,当Anchor图片与Negative图片(Negative意味着是非同一个人)对比时,你会想让他们的距离离得更远一点。这就是为什么叫做三元组损失,它代表你通常会同时看三张图片(Anchor图片、Postive图片和Negative图片),通常把它们简写成A、P、N。
把这些写成公式的话,你想要的是网络的参数或者编码能够满足以下特性:
![]()
公式两边分别对应如下距离:
![]()
这里的d可以看成距离(distance)函数。现在如果我把方程右边项移到左边,最终就得到:
![]()
值得注意的是,上面的表达式有一种情况:把所有东西都学成0,如果f总是输出0,0 - 0 = 0,也满足这个方程,但是没有用处。所以为了确保网络对于所有的编码不会总是输出0,也为了确保它不会把所有的编码都设成互相相等的。我们做一些改变,应该是比0还要小,小于一个-alpha值(另一个超参数),即:
![]()
按照惯例,一般写成这样:
![]()
这个参数也叫做间隔(margin)参数。间隔参数的作用是它拉大了Anchor和Positive 图片对和Anchor与Negative 图片对之间的差距。取下面的这个方框圈起来的方程式,然后定义三元组损失函数。

三元组损失函数的定义基于三张图片,假如三张图片A、P、N,即anchor样本、positive样本和negative样本,其中positive图片和anchor图片是同一个人,但是negative图片和anchor不是同一个人。如上图,为了定义这个损失函数,我们取这个和0的最大值:
![]()
这个max函数的作用是只要你能使画绿色下划线部分小于等于0,只要你能达到这个目标,那么这个例子的损失就是0。另一方面,如果绿色下划线部分大于0,则它是最大值,得到一个正的损失值,通过最小化损失函数使得这部分小于或等于0。

这是一个三元组定义的损失,整个网络的成本函数J应该是训练集中这些单个三元组损失的总和(sum)。假如你有一个10000个图片的训练集,里面是1000个不同的人的照片,你要做的就是取这10000个图片,然后生成这样的三元组,然后训练你的学习算法,对这种代价函数用梯度下降,这个代价函数就是定义在你数据集里的这样的三元组图片上。
注意,为了定义三元组的数据集需要成对的A和P,即同一个人的成对的图片,为了训练你的系统你确实需要一个数据集,里面有同一个人的多个照片。如果你只有每个人一张照片,那么根本没法训练这个系统。当然,训练完这个系统之后,你可以应用到你的一次学习问题上,对于你的人脸识别系统,可能你只有想要识别的某个人的一张照片。但对于训练集,你需要确保有同一个人的多个图片,至少是你训练集里的一部分人,这样就有成对(pairs)的Anchor和Positive图片了。
下面看如何选择这些三元组来形成训练集(training set)。

一个问题是如果你从训练集中,随机地选择A、P和N,遵守A和P是同一个人,而A和N是不同的人这一原则。随机选择的话约束条件很容易满足,因为A和N比A和P差别很大的概率很大,这样网络并不能从中学到什么。所以要尽可能的选择难(hard)训练的A、P和N,使得d(A,P)和d(A,N)很接近,即:
![]()
这样你的学习算法会竭尽全力使右边这个式子变大,或者使左边这个式子变小,这样左右两边至少有一个间隔(margin),并且选择这样的三元组还可以增加你的学习算法的计算效率。因此,只有选择难的三元组梯度下降法才能发挥作用,使得这两边离得尽可能远。
如果感兴趣的话,这篇论文中有更多细节,作者是Florian Schroff, Dmitry Kalenichenko, James Philbin,他们建立了这个叫做FaceNet的系统,Florian Schroff, Dmitry Kalenichenko, James Philbin (2015). FaceNet: A Unified Embedding for Face Recognition and Clustering

总结一下,如上图,训练这个三元组损失你需要取你的训练集,然后把它做成很多三元组。定义了这些包括A、P和N的数据集之后,还需要最小化成本函数J。这样做的效果就是反向传播到网络中的所有参数来学习到一种编码,使得如果两个图片是同一个人,那么它们的d就会很小,如果两个图片不是同一个人,它们的d就会很大。
这就是三元组损失,并且如何用它来训练网络输出一个好的编码用于人脸识别。现在的人脸识别系统,尤其是大规模的商业人脸识别系统(large-scale commercial face recognition)都是在很大的数据集上训练。幸运的是,一些公司已经训练了这些大型的网络并且上传了模型参数。这一领域的一个实用操作就是下载别人的预训练模型(pretrained model),而不是一切都要从头开始(do everything from scratch yourself)。但是即使你下载了别人的预训练模型,Andrew认为了解怎么训练这些算法也是有用的,以防针对一些应用你需要从头实现这些想法。
《4.5 人脸验证与二分类》Face verification and binary classification
Triplet loss是一个学习人脸识别卷积网络参数的好方法,还有其他学习参数的方法,让我们看看如何将人脸识别当成一个二分类问题(binary classification problem)。

另一个训练神经网络的方法是选取一对神经网络,选取Siamese网络,使其同时计算这些嵌入(embedding),比如说128维的嵌入,或者更高维,然后将其输入到逻辑回归单元,然后进行预测,如果是相同的人,那么输出是1,若是不同的人,输出是0。这就把人脸识别问题转换为一个二分类问题,训练这种系统时可以替换Triplet loss的方法。
最后的逻辑回归单元是怎么处理的?比如说sigmoid函数应用到某些特征上,关注编码之间的差异,即:

其中,下标k表示选择这个向量中的第k个元素。有一种做法,把这128个元素当作特征(features),然后把他们放入逻辑回归中,最后的逻辑回归可以增加参数w_i和b,就像普通逻辑回归一样。你将在这128个单元上训练合适的权重,用来预测两张图片是否是一个人,这是一个很合理的方法来学习预测0或者1,即是否是同一个人。
当然,上图中绿色标记(这两个编码取元素差的绝对值)也可以用卡方公式来代替(卡方平方相似度):

- Yaniv Taigman, Ming Yang, Marc'Aurelio Ranzato, Lior Wolf (2014). DeepFace: Closing the gap to human-level performance in face verification
这些公式及其变形在这篇DeepFace论文中有讨论,之前也引用过。

如上图的红色标记,输入是一对图片(a pair of images),这是你的训练输入x,输出y是0或者1,取决于你的输入是相似图片还是非相似图片。和之前类似,上面这个神经网络拥有的参数和下面神经网络的相同,两组参数是绑定的,这样的系统效果很好。
这里有一个计算技巧(computational trick)可以帮助显著提高部署效果,如果是数据库中的图片,不需要每次都计算这个嵌入,可以提前计算好(pre-compute),这个预先计算的思想,可以节省大量的计算(save a significant computation),这个预训练的工作可以用在Siamese网路结构中,将人脸识别当作一个二分类问题,也可以用在学习和使用Triplet loss函数上。

如上图,总结一下,把人脸验证(face verification)当作一个监督学习(supervised learning),创建一个只有成对图片的训练集,输入不是三个一组,而是成对的图片(pairs of images),目标标签(target label)是1表示一对图片是一个人,目标标签是0表示图片中是不同的人。利用不同的成对图片,使用反向传播算法去训练神经网络,训练Siamese神经网络。处理人脸验证和人脸识别扩展为二分类问题,这样的效果也很好。
《4.6 什么是神经风格迁移?》What is neural style transfer?
卷积神经网络最有趣的应用是神经风格迁移(neural style transfer)。什么是神经风格迁移?让我们看几个例子。

如上图左边,左边的照片是在斯坦福大学拍摄的,右边是梵高的星空,神经网络风格迁移可以生成下面这张照片。这仍是斯坦福大学的照片,但是用右边图像的风格画出来。
为了描述如何实现神经网络迁移,使用C来表示内容(content)图像,S表示风格(style)图像,G表示生成的图像(generated image)。
下面再看一个例子,上图右边。C代表旧金山的金门大桥,S是毕加索的风格,然后把这两张照片结合起来,得到G这张毕加索风格的金门大桥。
这是由Justin Johnson制作,在下面几个视频中将学习如何自己生成这样的图片。
为了实现神经风格迁移,我们需要知道卷积网络提取的特征,在不同的神经网络,深层的、浅层的。在深入了解如何实现神经风格迁移之前,Andrew将在下一个视频中直观地介绍卷积神经网络不同层之间的具体运算。
《4.7 深度卷积网络学习什么?》What are deep ConvNets learning?
深度卷积网络到底在学什么?在这个视频中将展示一些可视化的例子,可以帮助我们理解卷积网络中深度较大的层真正在做什么,这样有助于理解如何实现神经风格迁移。看一个例子。

这是一个Alexnet,轻量级网络,我们希望看到不同层之间隐藏单元的计算结果。从第一层的隐藏单元(hidden unit)开始,假设遍历了训练集,然后找到那些使得单元激活最大化的一些图片,或者是图片块(image patches)。即弄明白哪一张图片最大限度地激活特定的单元(peculiar unit activation)。注意在第一层的隐藏单元,只能看到小部分卷积神经,如果要画出来哪些激活了激活单元,只有一小块图片块是有意义的,因为这就是特定单元所能看到的全部。选择一个隐藏单元,发现有9个图片最大化了单元激活,可能找到这样的9个图片块(编号1),似乎是图片浅层区域显示了隐藏单元所看到的,找到了边缘或者线,这就是那9个最大化地激活了隐藏单元激活项的图片块。然后你可以选一个另一个第一层的隐藏单元,重复刚才的步骤,这是另一个隐藏单元,似乎第二个由这9个图片块(编号2)组成。看来这个隐藏单元在输入区域,寻找这样的线条,我们也称之为接受域(receptive field)。对其他隐藏单元也进行处理,会发现其他隐藏单元趋向于激活类似于这样的图片。这个似乎对垂直明亮边缘左边有绿色的图片块(编号3)感兴趣,这一个隐藏单元倾向于橘色,这是一个有趣的图片块(编号4),红色和绿色混合成褐色或者棕橙色,但是神经元仍可以激活它。
以此类推,这是9个不同的代表性神经元(representative neurons),每一个不同的图片块都最大化地(maximally)激活了。
这个视频中使用的所有例子来自于Matthew Zener和Rob Fergus的这篇论文,题目是( Visualizing and Understanding Convolutional Networks)《可视化理解卷积神经网络》。论文也提出了一些更复杂的(sophisticated)方式来可视化卷积神经网络的计算。
接下来,在深层(deeper)的隐藏单元中会进行怎样的运算呢?

如上图,是Layer1-Layer5得到的图片块。在Layer2中,可视化显示了第二层的9个隐藏单元,每一个又有9个图片块使得隐藏单元有较大的输出(very large output)或是较大的激活(very large activation)。上图放大了第一层,第一个隐藏单元(红色标记)大概是这个角度的边缘。(1)第一层的隐藏单元通常会找一些简单的特征(simple features),比如说边缘(edge)或者颜色阴影(particular shade of color)。

如上图,(2)第二层似乎检测到更复杂的形状和模式(more complex shapes and patterns),比如说这个隐藏单元(编号1),找到有很多垂线的垂直图案(vertical texture),这个隐藏单元(编号2)似乎在左侧有圆形图案(roundish shape)时会被高度激活,这个的特征(编号3)是很细的垂线(very thin vertical lines),以此类推,第二层检测的特征变得更加复杂。


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

(4)再看第四层,检测到的模式和特征更加复杂,左上角的隐藏单元学习成了一个狗的检测器,但是这些狗看起来都很类似,并不清楚这些狗的种类。右上角的这个隐藏单元检测水吗?第6个隐藏单元似乎检测到鸟的脚等等。

(5)第五层检测到更加复杂的事物,注意到右下角的这个神经元,似乎是一个狗检测器,但是可以检测到的狗似乎更加多样性。左上角这个可以检测到键盘,或者是键盘质地的物体,可能是有很多点的物体。第4个神经元可能检测到文本,但是很难确定。第7个检测到花。总的来看,检测已经有了一些进展,从检测简单的事物,比如说,第一层的边缘,第二层的质地,到深层的复杂物体。
本节视频可以更直观地了解卷积神经网络的浅层和深层是如何计算的,接下来让我们使用这些知识开始构造神经风格迁移算法。
《4.8 代价/成本函数》Cost function
要构建一个神经风格迁移系统,需要为生成的图像定义一个成本函数(cost function),通过最小化成本函数,可以生成你想要的任何图像。

重新描述一下问题:给定一个内容图像C和一个风格图片S,目标是生成一个新图片G。为了实现神经风格迁移,定义一个关于G的成本函数J(G)来评判生成图像的好坏,然后使用梯度下降法最小化J(G)来生成新的图像G。定义成本函数的公式如下:
![]()
第一部分被称作内容代价(content cost),这是一个关于内容图片和生成图片的函数,它是用来度量生成图片G的内容与内容图片C的内容有多相似。第二部分是风格代价函数(style cost),是关于S和G的函数,用来度量图片G的风格和S的风格的相似度。同时两者之间的权重使用两个超参数来确定。Andrew觉得一个超参数似乎就够了,但提出神经风格迁移的原始作者使用了两个不同的超参数。
关于神经风格迁移算法的接下来几段视频中展示的,是基于Leon Gatys, Alexandra Ecker和Matthias Bethge的这篇论文。Leon A. Gatys, Alexander S. Ecker, Matthias Bethge, (2015). A Neural Algorithm of Artistic Style
论文不是很难读懂,推荐看看论文。

如上图,为了生成一个新图像,要做的是(1)随机初始化生成图像G,它可能是100×100×3,可能是500×500×3,又或者是任何你想要的尺寸。(2)使用梯度下降法使成本函数J(G)最小化,更新公式:
![]()
在这个步骤中,实际上更新的是图像G的像素值,也就是100×100×3。
看上图的这个例子。假设你从这张内容图片(编号1)和风格(编号2)图片(毕加索画作)开始,当你随机初始化G,随机初始化的生成图像可能就是这张随机选取像素的白噪声图(编号3)。接下来运行梯度下降算法,最小化代价函数J(G),逐步处理像素,这样慢慢得到一个生成图片(编号4、5、6),越来越像用风格图片的风格画出来的内容图片。
在这段视频中我们看到了神经风格迁移算法的概要(overall outline),定义一个生成图片G的代价函数,并将其最小化。接下来我们需要了解怎么去定义内容代价函数和风格代价函数,让我们从下一个视频开始学习这部分内容吧。
《4.9 内容代价函数》Content cost function
我们先定义内容代价函数(content cost function)。

如上图,(1)用隐含层l来计算内容代价函数,如果l是个很小的数,比如用隐含层1,这个代价函数就会使生成图片像素上非常接近内容图片。然而如果你用很深的层,那么你就会问,内容图片里是否有狗,然后它就会确保生成图片里有一个狗。所以在实际中,这个层l在网络中既不会选的太浅也不会选的太深。具体例子里通常会选择在网络的中间层,既不太浅也不很深,(2)然后用一个预训练的卷积模型,可以是VGG网络或者其他的网络也可以。接下来你需要衡量假如有一个内容图片和一个生成图片他们在内容上的相似度,(3)我们令这个a^[l][C]和a^[l][C],分别代表这两个图片C和G的l层的激活函数值。(4)如果这两个激活值相似,那么就意味着两个图片的内容相似。
衡量两个激活值不同或相似的程度用如下公式:
![]()
取l层的隐含单元的激活值,按元素相减,然后取平方,前面可以加上归一化或者不加,比如1/2。这里用的符号都是展成向量形式(vectors)的,因此对应元素相减变成了L2范数的平方。然后用梯度下降法来找到图像G,使得隐含层的激活值和你内容图像的相似。
这就是如何定义风格迁移网络的内容代价函数,接下来让我们学习风格代价函数。
《4.10 风格代价函数》Style cost function
学习了内容代价函数之后,这节课我们来了解风格代价函数(style cost function)。

这是一张彩色图片,现在我们选择了某一层l(蓝色框部分)去为图片的风格定义一个深度测量(deep measure),接下来将图片的风格定义为l层中各个通道之间激活项的相关系数(correlation)。
如上图,假设有5个通道(channels),这里用五种颜色表示。一般而言,神经网络中会有许多通道。在第一个通道中含有某个激活项,第二个通道也含有某个激活项,于是它们组成了一对数字。同理,可以得到很多数字对(pairs)。

在这里,这个红色的通道对应的第2个神经元,它能找出图片中的特定位置是否含有这些垂直的纹理,而第二个通道(黄色的通道),对应第4个神经元,它可以粗略地找出橙色的区域。
什么时候两个通道拥有高度相关性呢?如果有高度相关性,那么这幅图片中出现垂直纹理的地方,那么很大概率也是橙色的。如果说它们是不相关的,这意味着图片中有垂直纹理的地方很大概率不是橙色的。而相关系数描述的就是当图片某处出现这种垂直纹理时又同时是橙色的可能性。因此,相关系数提供了一种去测量这些不同的特征的方法。
如果我们使用相关系数来描述通道的风格,你能做的就是测量你的生成图像中第一个通道(红色)是否与第二个通道(黄色)相关,通过测量,你能得知在生成的图像中垂直纹理和橙色同时出现或者不同时出现的频率,这样你将能够测量生成的图像的风格与输入的风格图像的相似程度。接下来具体讲解。

如上图,对于这两个图像(风格图像S和生成图像G),需要计算一个风格矩阵(style matrix),说得更具体一点就是用l层来测量风格。其中a^[l]_i,j,k表示隐藏层l中(i,j,k)位置的激活值,i,j,k分别表示该位置的高度、宽度以及对应的通道数。计算关于l层和风格图像的一个矩阵,即G^[l][S],这是一个n_c*n_c的矩阵,高度和宽度都是l层的通道数。矩阵中的k和k'被用来描述k通道和k'通道之间的相关系数。输入的风格图像S构成的风格矩阵具体表现为:

备注:用符号i,j表示下届,对i,j,k位置的激活值乘以同样位置的激活值,然后i和j分别加到l层的高度和宽度。严格来说,它是一种非标准的互相关函数(unnormalized cross-covariance),因为没有减去平均数,而是直接相乘。这是输入的风格图像构成的风格矩阵,然后对生成图像G做同样的操作:

风格矩阵就是把图中各个高度和宽度的激活项都遍历一遍,并将k和k'通道中对应位置的激活项都进行相乘。现在分别从风格图像S和生成图像G得到两个矩阵。过程见下图:

最后,上图所示,将S和G代入到风格代价函数中去计算,得到这两个矩阵的误差,这里用的Frobenius范数,实际上是计算两个矩阵对应元素相减的平方的和。把这个式子展开,从k和k'开始作差,然后把所有的结果加起来,作者使用了一个归一化常数(renormalization constant),再在外面加一个平方,一般我们只要将它乘以一个超参数beta就行。

如上图,最后,这是对l层定义的风格代价函数J^[l],实际上,如果各层都使用风格代价函数,结果会更好,你可把各个层的结果(各层的风格代价函数)都加起来,对每个层定义权重,即额外的(extra)超参数,用lambda^[l]表示。这样将在神经网络中使用不同的层,包括之前的一些可以测量类似边缘这样的低级特征的层,以及之后的一些能测量高级特征的层,使得我们的神经网络在计算风格时能够同时考虑到这些低级和高级特征的相关系数。这样,在基础的训练中你在定义超参数时,可以尽可能的得到更合理的选择。
把这些东西封装起来,就定义了一个全体代价函数:
![]()
接着用梯度下降法或者其他优化算法来寻找合适的图像G,并计算J(G)的最小值,这样将能够得到非常好看的结果。
《4.11 一维到三维的推广》1D and 3D generalizations of models
到目前为止我们已经学习了许多关于卷积神经网络(ConvNets)的知识,从卷积神经网络框架,到如何使用它进行图像识别、目标检测、人脸识别与神经网络转换。即使我们大部分讨论的图像数据,某种意义上而言都是2D数据,考虑到图像如此普遍,我们所掌握的思想不仅局限于2D图像,甚至可以延伸至1D,乃至3D数据。

如上图第一行,回忆之前学习的2D卷积,输入一个14×14的图像,并使用一个5×5的过滤器进行卷积,通过这个操作得到10×10的输出。如果你使用了多通道,比如14×14×3,那么相匹配的过滤器可能是5×5×3,如果你使用了多重过滤,比如16,最终你得到的是10×10×16。
事实证明该想法也同样可以用于1维数据,举个例子(上图第二行),左边是一个EKG信号(signal),或者说是心电图(electrocardiogram),当在胸部(chest)放置一个电极(electrode),电极透过胸部测量心跳带来的微弱电流,正因为心脏跳动,产生的微弱电波能被一组电极测量,这就是人心跳产生的EKG,每一个峰值都对应着一次心跳(heartbeat)。
如果你想使用EKG信号,比如医学诊断(medical diagnosis),那么你将处理1维数据,因为EKG数据是由时间序列对应的每个瞬间的电压组成,这次不是一个14×14的尺寸输入,你可能只有一个14尺寸输入,在这种情况下你可能需要使用一个1维过滤(one-dimensional filter)进行卷积,你只需要一个1×5的过滤器,而不是一个5×5的,可在不同位置应用类似2D的方法。当你对这个1维信号使用卷积,你将发现一个14维的数据与5维数据进行卷积,并产生一个10维输出。
再一次如果你使用多通道,在这种场景下可能会获得一个14×1的通道。如果你使用一个EKG,就是5×1的,如果你有16个过滤器,可能你最后会获得一个10×16的数据,这可能会是你卷积网络中的某一层。
对于卷积网络的下一层,如果输入一个10×16数据,你也可以使用一个5维过滤器进行卷积,这需要16个通道进行匹配,如果你有32个过滤器,另一层的输出结果就是6×32,如果你使用了32个过滤器的话。
下一门课将讨论序列模型(sequence models),包括递归神经网络(recurrent neural networks)、LCM与其他类似模型。我们将探讨使用1D卷积网络的优缺点,对比于其它专门为序列数据而精心设计的模型。
这也是2D向1D的进化,对于3D数据来说如何呢?什么是3D数据?与1D数列或数字矩阵不同,你现在有了一个3D块,一个3D输入数据。以你做CT扫描为例,如下图:

这是一种使用X光照射(x-ray scan),然后输出身体的3D模型,CT扫描实现的是它可以获取你身体不同片段(图片信息),对人体躯干做切片。假设你的数据现在具备一定长度、宽度与高度,其中每一个切片都与躯干的切片对应。

如上图,如果你想要在3D扫描或CT扫描中应用卷积网络进行特征识别,也可以从第一张幻灯片(Convolutions in 2D and 1D)里受到启发,并将其应用到3D卷积中。如果你有一个3D对象,比如说是14×14×14,这也是输入CT扫描的宽度与深度(后两个14)。再次提醒,3D对象和CT扫描结果的长宽高也可以是不一致的。为了简化讨论,仅使用14×14×14为例。
如果你现在使用5×5×5过滤器(3D)进行卷积,将得到一个10×10×10的结果输出,技术上来说也可以再×1,如果这有一个1的通道。这仅仅是一个3D模块,但是你的数据可以有不同数目的通道,那种情况下也是乘1,因为通道的数目必须与过滤器匹配。如果你使用16个过滤器处理5×5×5×1,接下来的输出将是10×10×10×16,这将成为你3D数据卷积网络上的一层。
如果下一层卷积使用5×5×5×16维度的过滤器再次卷积,通道数目也与往常一样匹配,如果你有32个过滤器,操作也与之前相同,最终你得到一个6×6×6×32的输出。
某种程度上3D数据也可以使用3D卷积网络学习,这些过滤器实现的功能正是通过你的3D数据进行特征检测。医疗检测(medical scans)是3D数据的一个实例,另一个数据处理的例子是电影中随时间变化的不同视频切片看作是3D数据,可以将这个技术用于检测动作及人物行为。
总而言之这就是1D、2D及3D数据处理,图像数据无处不在,以至于大多数卷积网络都是基于图像上的2D数据。
Summary
这是本周最后一次视频,讲解了神经网络的特殊应用:人脸识别系统和神经风格转换以及一些经典论文,也是最后一次关于卷积神经网络的课程,我们已经学习了许多关于卷积网络的知识,Andrew希望在未来工作中发现许多思想对我们有所裨益,祝贺!
说明:记录学习笔记,如果错误欢迎指正!转载请联系我。

本篇博客深入解析卷积神经网络在人脸识别(通过FaceNet和Siamese网络)及神经风格迁移(艺术风格转换)的应用,涵盖理论讲解与关键算法,还介绍了相关经典论文。
1942

被折叠的 条评论
为什么被折叠?



