Coursera | Andrew Ng (04-week4)—特殊应用:人脸识别和神经风格迁移
在吴恩达深度学习视频以及大树先生的博客提炼笔记基础上添加个人理解,原大树先生博客可查看该链接地址大树先生的博客- ZJ
****:http://blog.****.net/JUNJUN_ZHAO/article/details/79281361
Part 1:人脸识别
4.1 什么是人脸识别? what is face recognition?
基于以上所学的卷积神经网络的知识,接下来介绍,一些重要的 ConvNet 的特殊应用。
- 人脸验证和人脸识别
人脸验证(Verification):
- Input:图片、名字/ID;
- Output:输入的图片是否是对应的人。
- 1 to 1 问题。
人脸识别(Recognition):
- 拥有一个具有 K 个人的数据库;
- 输入一副人脸图片;
- 如果图片是任意这 K 个人中的一位,则输出对应人的 ID。
个人理解:目前 My company 用的是 Face Verification. 百度用的是 Face Recognition.
人脸识别问题对于人脸验证问题来说,具有更高的难度。如对于一个验证系统来说,如果我们拥有 99% 的精确度,那么这个验证系统已经具有了很高的精度;但是假设在另外一个识别系统中,如果我们把这个验证系统应用在具有K个人的识别系统中,那么系统犯错误的机会就变成了 K 倍。所以如果我们想在识别系统中得到更高的精度,那么就需要得到一个具有更高精度的验证系统。
4.2 one shot learning
人脸识别挑战:对于大多数的人脸识别系统都存在的一个问题就是 one shot learning 一次学习问题。
什么是 one shot learning:
对于一个人脸识别系统,我们需要仅仅通过先前的一张人脸的图片或者说一个人脸的样例,就能够实现该人的识别,那么这样的问题就是 one shot 问题。对于存在于数据库中的人脸图片,系统能够识别到对应的人;而不在数据库中的人脸图片,则系统给出无法通过识别的结果。
对于 one shot learning 问题,因为只有单个样本,是不足以训练一个稳健的卷积神经网络来进行不同人的识别过程。而且,在有新的样本成员加入的时候,往往还需要对网络进行重新训练。所以我们不能以传统的方法来实现识别系统。
Similarity 函数:
为了能够让人脸识别系统实现一次学习,需要让神经网络学习 Similarity 函数:
- d(img1, img2):两幅图片之间的差异度
- 输入:两幅图片
- 输出:两者之间的差异度
- 如果 ,则输出“same”;
- 如果 ,则输出“different”.
注: 发音 /tau/
对于人脸识别系统,通过将输入的人脸图片与数据库中所拥有的图片成对输入 Similarity 函数,两两对比,则可解决 one shot problem。如果有新的人加入团队,则只需将其图片添加至数据库即可。
4.3 Siamese 网络 network
如何实现上面提到的 Similarity 函数呢?:利用 Siamese 网络来实现 Similarity 函数。
构建网络:
对于一个卷积神经网络结构,我们去掉最后的 softmax 层,将图片样本1 输入网络,最后由网络输出一个 N 维的向量(图中实例以 128 表示),这 N 维向量则代表输入图片样本1 的编码。将不同人的图片样本输入相同参数的网络结构,得到各自相应的图片编码。
Similarity 函数实现:
将 Similarity 函数表示成两幅图片编码之差的范数:
那么也就是说:
- 我们的神经网络的参数定义了图片的编码;
- 学习网络的参数,使我们得到好的 Similarity 函数:
- 如果 x1,x2 是同一个人的图片,那么得到的 很小;
- 如果 x1,x2 不是同一个人的图片,那么得到的 很大。
4.4 Triplet Loss
上面提到了神经网络的参数定义了图片的编码; 接下来->
如何通过学习神经网络的参数,得到优质的人脸图片的编码?方法之一就是定义 Triplet 损失函数,并在其之上运用梯度下降。
学习目标:
为了使用Triplet 损失函数,我们需要比较成对的图像(三元组术语):
- Anchor (锚)(A): 目标图片;(锚,理解上就是目标)
- Positive(P):与 Anchor 属于同一个人的图片;
- Negative(N):与 Anchor不属于同一个人的图片。
对于 Anchor 和 Positive,我们希望二者编码的差异小一些;对于Anchor 和Negative,我们希望他们编码的差异大一些。所以我们的目标以编码差的范数来表示为:
也就是:
上面的公式存在一个问题就是,当 时,也就是神经网络学习到的函数总是输出 0 时,或者 时,也满足上面的公式,但却不是我们想要的目标结果。所以为了防止出现这种情况,我们对上式进行修改,使得两者差要小于一个较小的负数:
一般将 写成 ,称为“margin”。即:
不同 margin 值的设置对模型学习具有不同的效果,margin 的作用就是拉大了 Anchor 与 Positive 图片对 和 Anchor 与 Negative 图片对之间的差距。
Triplet 损失函数:
Triplet 损失函数的定义基于三张图片:Anchor、Positive、Negative。
整个网络的代价函数:
假设我们有一个 10000 张片的训练集,里面是 1000 个不同的人的照片样本。我们需要做的就是从这 10000 张训练集中抽取图片生成(A,P,N)的三元组,来训练我们的学习算法,并在 Triplet 损失函数上进行梯度下降。
注意:为了训练我们的网络,我们必须拥有 Anchor 和 Positive 对,所以这里我们必须有每个人的多张照片,而不能仅仅是一张照片,否则无法训练网络。
三元组(A,P,N)的选择:
在训练的过程中,如果我们随机地选择图片构成三元组(A,P,N),那么对于下面的条件是很容易满足的:
所以,为了更好地训练网络,我们需要选择那些训练有“难度”的三元组,也就是选择的三元组满足:
算法将会努力使得 变大,或者使得 变小,从而使两者之间至少有一个 的间隔;
增加学习算法的计算效率,避免那些太简单的三元组。
最终通过训练,我们学习到的参数,会使得对于同一个人的图片,编码的距离很小;对不同人的图片,编码的距离就很大。
对于大型的人脸识别系统,常常具有上百万甚至上亿的训练数据集,我们并我容易得到。所以对于该领域,我们常常是下载别人在网上上传的预训练模型,而不是从头开始。
4.5 脸部验证和二分类 Face verification and binary classification
除了利用 Triplet 损失函数来学习人脸识别卷积网络参数的方法外,还有其他的方式。我们可以将人脸识别问题利用 Siamese 网络当成一个二分类问题,同样可以实现参数的学习。
Siamese 二分类改进:
对两张图片应用 Siamese 网络,计算得到两张图片的 N 维编码,然后将两个编码输入到一个 logistic regression 单元中,然后进行预测。如果是相同的人,那么输出是 1;如果是不同的人,输出是 0。那么这里我们就将人脸识别的问题,转化为一个二分类问题。
对于最后的 sigmoid 函数,我们可以进行如下计算:
其中, 代表图片 的编码,下标 k 代表选择 N 维编码向量中的第 k 个元素。
我们以两个图片编码向量对应元素之间的差值作为特征输入到 logistic regression 的单元中,增加参数和,通过训练得到合适的参数权重和偏置,进而判断两张图片是否为同一个人。
同时输入逻辑回归单元的特征可以进行更改,如还可以是:
上式也被称为 方公式,有时也称为 方相似度。
在实际的人脸识别系统中,我们可以对数据库的人脸图片进行预计算,存储卷积网络得到的编码。当有图片进行识别时,运用卷积网络计算新图片的编码,与预计算保存好的编码输入到逻辑回归单元中进行预测。这样可以提高我们系统预测的效率,节省计算时间。
总结:
利用 Siamese 网络,我们可以将人脸验证当作一个监督学习,创建成对的训练集和是否同一个人的输出标签。
我们利用不同的图片对使用反向传播的算法对 Siamese 网络进行训练,进而得到人脸验证系统。
Part 2:神经风格迁移
4.6 什么是神经风格迁移? what is neural style transfer?
最近,ConvNets 最有趣的应用,是神经风格迁移。
Content :内容图片
Style:风格图片
Generated: 生成图片
4.7 深度网络学习内容可视化 what are deep ConvNets learning?
疑问:深度卷积神经网络究竟在学习什么?接下来通过可视化的例子去理解。
如何可视化:
假设我们训练了一个卷积神经网络如下所示:
我们希望看到不同层的隐藏单元的计算结果。依次对各个层进行如下操作:
- 在当前层挑选一个隐藏单元;
- 遍历训练集,找到最大化地**了该运算单元的图片或者图片块;
- 对该层的其他运算单元执行操作。
个人理解:某个隐藏单元都在寻找类似样式的图片块。也就是只要是符合这个隐藏单元所寻找的样式 图片块,都会**这个隐藏单元的。
对于在第一层的隐藏单元中,其只能看到卷积网络的小部分内容,也就是最后我们找到的那些最大化**第一层隐层单元的是一些小的图片块。我们可以理解为第一层的神经单元通常会寻找一些简单的特征,如边缘或者颜色阴影等。
各层网络可视化:
观察可知:对于卷积网络的各层单元,随着网络深度的增加,隐藏层计算单元随着层数的增加,从简单的事物逐渐到更加复杂的事物。
例如:从检测一些边缘,到检测某一个部分,再到检测出 狗,人 等等。
4.8 神经风格迁移代价函数 Cost function
代价函数:
为了实现神经风格迁移,我们需要为生成的图片定义一个代价函数。(代价函数的目的永远是最小化代价函数,用的是梯度下降法)
对于神经风格迁移,我们的目标是由内容图片 C 和风格图片 S,生成最终的风格迁移图片 G:
所以为了实现神经风格迁移,我们需要定义关于 G 的代价函数 J,以用来评判生成图片的好坏:
其中
- 代表生成图片 G 的内容和内容图片 C 的内容的相似度;
- 代表生成图片 G 的内容和风格图片 S 的内容的相似度;
- 两个超参数用来表示以上两者之间的权重。
执行过程:
- 随机初始化生成图片 G,如大小为 100×100×3;
- 使用梯度下降算法最小化上面定义的代价函数 J(G),
对于上图的内容图片 C 和风格图片 S,通过梯度下降算法一次次的训练,我们可以由初始的噪声图片得到最终的风格迁移图片 (具有 C的内容,又具有 S 的风格的)图片 G。
4.9 内容代价函数(Content cost function)
由上可知,风格迁移网络的代价函数,具有一个内容代价部分,还有一个风格代价部分。
- 假设我们使用隐藏层 来计算内容代价。(如果选择的 太小,那么代价函数就会使得我们的生成图片 G 在像素上非常接近内容图片;然而用很深的网络,那么生成图片 G 中就会产生与内容图片中所拥有的物体。所以对于 一般选在网络的中间层,既不深也不浅);
使用一个预训练的卷积网络。(如,VGG 或其他); - 令和分别代表内容图片 C 和生成图片 G 的 层的**值;
- 如果和相似,那么两张图片就有相似的内容;
定义内容代价函数如下:
在对代价函数运行梯度下降算法时,会激励这里的内容代价函数,努力使得生成图片 G 隐含层的**值和内容图片 C 隐含层 的**值相似。
个人理解:某一层的 某个**函数的**值相似,就是某种程度上,应该是类似的 图片块可以引起的。
4.10 风格代价函数(Style cost function)
“Style”的含义:
对于一个卷积网络中,我们选择网络的中间层 , 定义“Style”表示 层的各个通道**项之间的相关性。
相关性大小的度量:
上面是我们选出的 层的**项,对于不同的通道值,代表不同的神经元所学习到的特征,这里假如红色的通道可以找到图片中含有垂直纹理特征的区域,黄色通道可以找出橙色的区域。
而相关性大小的含义就是,如假设中,图片出现垂直纹理特征的区域显示橙色可能的大小。
我们将相关系数应用到风格图片 S 和生成图片 G 的对应通道上,就可以度量风格图片和生成图片的相似度。
Style 矩阵:
- 令表示在(i,j,k)位置的**值,其中 i、j、k 分别代表**值的高、宽、通道;
-
是一个大小的矩阵:
上面的矩阵在线性代数中又称为 Gram 矩阵,这里称为风格矩阵。
代价函数:
内容代价函数和风格代价函数前面的归一化可以加也可以不加,因为总体的代价函数前面有权重系数。
如果对各层都使用风格代价函数,那么会让结果变得更好:
4.11 1D to 3D 卷积 一维到三维推广 1D and 3D generalizations of model
在我们上面学过的卷积中,多数是对图形应用 2D 的卷积运算。同时,我们所应用的卷积运算还可以推广到 1D 和 3D 的情况。
2D和1D卷积:
- 2D卷积:14×14×3∗5×5×3——>10×10×
- 1D卷积:14×1∗5×1——>10×
3D卷积:
- 3D 卷积:14×14×14×1∗5×5×5×1——>10×10×10×
- 3D 数据:如医疗 CT 扫描中的即可产生身体的 3D 模型;电影切片也属于 3D 数据。
confidence 置信.
参考文献:
[1]. 大树先生.吴恩达Coursera深度学习课程 DeepLearning.ai 提炼笔记(4-4)– 特殊应用:人脸识别和神经风格迁移
PS: 欢迎扫码关注公众号:「SelfImprovementLab」!专注「深度学习」,「机器学习」,「人工智能」。以及 「早起」,「阅读」,「运动」,「英语 」「其他」不定期建群 打卡互助活动。