这两年,在深度学习的基础上,计算机视觉也得到了迅猛的发展,从而产生了大量令人振奋的应用:安全无人驾驶、精确面部识别、自动阅读放射成像等等。
通过这门课的学习,你将会:
- 理解如何搭建一个神经网络,包括最新的变体,例如残余网络。
- 知道如何将卷积网络应用到视觉检测和识别任务。
- 知道如何使用神经风格迁移生成艺术。
- 能够在图像、视频以及其他2D或3D数据上应用这些算法。
主要内容:
- 什么是人脸识别?
- One-Shot 学习
- Siamese 网络
- Triplet 损失
- 面部验证与二分类
- 什么是神经风格转换?
- 什么是深度卷积网络?
- 代价函数
- 内容代价函数
- 风格代价函数
- 一维到三维推广
计算机视觉是一个飞速发展的领域,这多亏了深度学习。深度学习与计算机视觉可以帮助汽车,查明周围的行人和汽车,并帮助汽车避开它们。还使得人脸识别技术变得更加效率和精准,你们即将能够体验到或早已体验过仅仅通过刷脸就能解锁手机或者门锁。当你解锁了手机,我猜手机上一定有很多分享图片的应用。在上面,你能看到美食,酒店或美丽风景的图片。有些公司在这些应用上使用了深度学习技术向你展示最为生动美丽以及与你最为相关的图片。机器学习甚至还催生了新的艺术类型。
吴恩达老师在其机器学习课程中展示了重要的卷积神经网络的特殊应用,我对该课的内容进行了翻译,并整理出了本文内容。课程中从人脸识别开始,之后讲到神经风格迁移,学完之后你将有机会在编程作业中实现这部分内容,创造自己的艺术作品。以下为课程的翻译、整理内容。
什么是人脸识别?(What is face recognition?)让我们先从人脸识别开始,我这里有一个有意思的演示。我在领导百度AI团队的时候,其中一个小组由林元庆带领的,做过一个人脸识别系统,这个系统非常棒,让我们来看一下。
以下内容为演示视频内容:
我想演示一个人脸识别系统,我现在在百度的中国总部,很多公司要求进入公司的时候要刷工卡,但是在这里我们并不需要它,使用人脸识别,看看我能做什么。当我走近的时候,它会识别我的脸,然后说欢迎我(Andrew NG),不需要工卡,我就能通过了。
让我们看看另一种情况,在旁边的是林元庆,IDL(百度深度学习实验室)的主管,他领导开发了这个人脸识别系统,我把我的工卡给他,上面有我的头像,他会试着用我的头像照片,而不是真人来通过。
林元庆语:我将尝试用 Andrew 的工卡骗过机器,看看发生什么,系统不会识别,系统拒绝识别。现在我要用我自己的脸(系统语音:“欢迎您”)(林元庆顺利通过)。
类似于这样的人脸识别系统在中国发展很快,我希望这个技术也可以在其他的国家使用。
挺厉害的吧,你刚看到的这个视频展示了人脸识别和活体检测,后一项技术确认你是一个活人。事实上,活体检测可以使用监督学习来实现,去预测是不是一个真人,这个方面我就不多说了。我主要想讲的是,如何构造这个系统中的人脸识别这一部分。
首先,让我们了解一下人脸识别的一些术语。
在人脸识别的相关文献中,人们经常提到人脸验证(FaceVerification)和人脸识别(Face Recognition)。
这是人脸验证问题,如果你有一张输入图片,以及某人的 ID 或者是名字,这个系统要做的是,验证输入图片是否是这个人。有时候也被称作1对1问题,只需要弄明白这个人是否和他声称的身份相符。
而人脸识别问题比人脸验证问题难很多(整理者注:1对多问题[$1:k$]
)),为什么呢?假设你有一个验证系统,准确率是99%,还可以。但是现在,假设在识别系统中,[$k=100$]
,如果你把这个验证系统应用在100个人身上,人脸识别上,你犯错的机会就是100倍了。如果每个人犯错的概率是1%,如果你有一个上百人的数据库,如果你想得到一个可接受的识别误差,你要构造一个验证系统,其准确率为99.9%或者更高,然后才可以在100人的数据库上运行,而保证有很大几率不出错。事实上,如果我们有一个100人的数据库,正确率可能需要远大于99%,才能得到很好的效果。
在之后的几个视频中,我们主要讲构造一个人脸验证,作为基本模块,如果准确率够高,你就可以把它用在识别系统上。
下一个视频中,我们将开始讨论如何构造人脸验证系统,人脸验证之所以难,原因之一在于要解决“一次学”(One-ShotLearning Problem)问题。让我们看下什么是一次学习问题。
One-Shot 学习(One-shot learning)人脸识别所面临的一个挑战就是你需要解决一次学习问题,这意味着在大多数人脸识别应用中,你需要通过单单一张图片或者单单一个人脸样例就能去识别这个人。而历史上,当深度学习只有一个训练样例时,它的表现并不好,让我们看一个直观的例子,并讨论如何去解决这个问题。
假设你的数据库里有4张你们公司的员工照片,实际上他们确实是我们 deeplearning.ai 的员工,分别是 Kian,Danielle,Younes和Tian。现在假设有个人(编号1所示)来到办公室,并且她想通过带有人脸识别系统的栅门,现在系统需要做的就是,仅仅通过一张已有的 Danielle 照片,来识别前面这个人确实是她。相反,如果机器看到一个不在数据库里的人(编号2所示),机器应该能分辨出她不是数据库中四个人之一。
所以在一次学习问题中,只能通过一个样本进行学习,以能够认出同一个人。大多数人脸识别系统都需要解决这个问题,因为在你的数据库中每个雇员或者组员可能都只有一张照片。
有一种办法是,将人的照片放进卷积神经网络中,使用 softmax 单元来输出4种,或者说5种标签,分别对应这4个人,或者4个都不是,所以 softmax 里我们会有5种输出。但实际上这样效果并不好,因为如此小的训练集不足以去训练一个稳健的神经网络。
而且,假如有新人加入你的团队,你现在将会有5个组员需要识别,所以输出就变成了6种,这时你要重新训练你的神经网络吗?这听起来实在不像一个好办法。
所以要让人脸识别能够做到一次学习,为了能有更好的效果,你现在要做的应该是学习 Similarity 函数。详细地说,你想要神经网络学习这样一个用 [$d$]{.MathJax_Preview}
表示的函数,[$d(img1,img2)= \text{degree of difference between images}$]
,它以两张图片作为输入,然后输出这两张图片的差异值。如果你放进同一个人的两张照片,你希望它能输出一个很小的值,如果放进两个长相差别很大的人的照片,它就输出一个很大的值。所以在识别过程中,如果这两张图片的差异值小于某个阈值[$τ$]
,它是一个超参数,那么这时就能预测这两张图片是同一个人,如果差异值大于 τ,就能预测这是不同的两个人,这就是解决人脸验证问题的一个可行办法。
要将它应用于识别任务,你要做的是拿这张新图片(编号6),然后用 [$d$]
函数去比较这两张图片(编号1和编号6),这样可能会输出一个非常大的数字,在该例中,比如说这个数字是10。之后你再让它和数据库中第二张图(编号2)片比较,因为这两张照片是同一个人,所以我们希望会输出一个很小的数。然后你再用它与数据库中的其他图片(编号3、4)进行比较,通过这样的计算,最终你能够知道,这个人确实是 Danielle。
对应的,如果某个人(编号7)不在你的数据库中,你通过函数 [$d$]
将他们的照片两两进行比较,最后我们希望 [$d$]
会对所有的比较都输出一个很大的值,这就证明这个人并不是数据库中4个人的其中一个。
要注意在这过程中你是如何解决一次学习问题的,只要你能学习这个函数 [$d$]
,通过输入一对图片,它将会告诉你这两张图片是否是同一个人。如果之后有新人加入了你的团队(编号5),你只需将他的照片加入你的数据库,系统依然能照常工作。
现在你已经知道函数 $d$
是如何工作的,通过输入两张照片,它将让你能够解决一次学习问题。那么,下节中,我们将会学习如何训练你的神经网络学会这个函数 [$d$]
。
上面你学到的函数 d 的作用就是输入两张人脸,然后告诉你它们的相似度。实现这个功能的一个方式就是用 Siamese 网络,我们看一下。
你经常看到这样的卷积网络,输入图片 [$x^{(1)}$]
,然后通过一些列卷积,池化和全连接层,最终得到这样的特征向量(编号1)。有时这个会被送进 softmax 单元来做分类,但在这个视频里我们不会这么做。我们关注的重点是这个向量(编号1),假如它有128个数,它是由网络深层的全连接层计算出来的,我要给这128个数命个名字,把它叫做 [$f(x^{(1)})$]
。你可以把 [$f(x^{(1)})$]
看作是输入图像 [$x^{(1)}$]
的编码,取这个输入图像(编号2),在这里是 Kian 的图片,然后表示成128维的向量。
建立一个人脸识别系统的方法就是,如果你要比较两个图片的话,例如这里的第一张(编号1)和第二张图片(编号2),你要做的就是把第二张图片喂给有同样参数的同样的神经网络,然后得到一个不同的128维的向量(编号3),这个向量代表或者编码第二个图片,我要把第二张图片的编码叫做 [$f(x^{(1)})$]
。这里我用 [$x^{(1)}$]
和 [$x^{(2)}$]
仅仅代表两个输入图片,他们没必要非是第一个和第二个训练样本,可以是任意两个图片。
最后如果你相信这些编码很好地代表了这两个图片,你要做的就是定义 d,将 [$x^{(1)}$]
和 [$x^{(2)}$]
的距离定义为这两幅图片的编码之差的范数,[$d(x^{(1)}),x^{(2)}=||f(x^{(1)})-f(x^{(2)})||^{(2)}_2$]
。
对 x^{(1)}
于两个不同的输入,运行相同的卷积神经网络,然后比较它们,这一般叫做 Siamese 网络架构。这里提到的很多观点,都来自于 Yaniv Taigman,Ming Yang,Marc’ Aurelio Ranzato,Lior Wolf 的一篇论文,他们开发的系统叫做 DeepFace。
怎么训练这个 Siamese 神经网络呢?不要忘了这两个网络有相同的参数,所以你实际要做的就是训练一个网络,它计算得到的编码可以用于函数 d,它可以告诉你两张图片是否是同一个人。更准确地说,神经网络的参数定义了一个编码函数 [$f(x^{(i)})$]
,如果给定输入图像 [$x^{(i)}$]
,这个网络会输出 [$x^{(i)}$]
的128维的编码。你要做的就是学习参数,使得如果两个图片 [$x^{(i)}$]
和 [$x^{(j)}$]
是同一个人,那么你得到的两个编码的距离就小。前面几个幻灯片我都用的是 [$x^{(1)}$]
和 [x^{(2)}]