Deeplearning.ai吴恩达笔记之卷积神经网络4

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35564813/article/details/86506016

Face Recognition

What is face recognition?

首先简单介绍一下人脸验证(face verification)和人脸识别(face recognition)的区别。

  • 人脸验证:输入一张人脸图片,验证输出与模板是否为同一人,即一对一问题。

  • 人脸识别:输入一张人脸图片,验证输出是否为K个模板中的某一个,即一对多问题。

一般地,人脸识别比人脸验证更难一些。因为假设人脸验证系统的错误率是1%,那么在人脸识别中,输出分别与K个模板都进行比较,则相应的错误率就会增加,约K%。模板个数越多,错误率越大一些。

One Shot Learning

在这里插入图片描述

对于one shot learning 问题,因为只有单个样本,是不足以训练一个稳健的卷积神经网络来进行不同人的识别过程。而且,在有新的样本成员加入的时候,往往还需要对网络进行重新训练。所以我们不能以传统的方法来实现识别系统。

为此,我们使用相似函数(similarity function)。相似函数表示两张图片的相似程度,用d(img1,img2)来表示。相似函数可以在人脸验证中使用:

  • d(img1,img2) τ \leq \tau :一样
  • d(img1,img2) τ \geq \tau :不一样

对于人脸识别问题,则只需计算测试图片与数据库中K个目标的相似函数,取其中d(img1,img2)最小的目标为匹配对象。若所有的d(img1,img2)都很大,则表示数据库没有这个人。

在这里插入图片描述

Siamese Network

若一张图片经过一般的CNN网络(包括CONV层、POOL层、FC层),最终得到全连接层FC,该FC层可以看成是原始图片的编码encoding,表征了原始图片的关键特征。这个网络结构我们称之为Siamese network。也就是说每张图片经过Siamese network后,由FC层每个神经元来表征。

在这里插入图片描述

建立Siamese network后,两张图片 x ( 1 ) x^{(1)} x ( 2 ) x^{(2)} 的相似度函数可由各自FC层 f ( x ( 1 ) ) f(x^{(1)}) f ( x ( 2 ) ) f(x^{(2)}) 之差的范数来表示:
d ( x ( 1 ) , x ( 2 ) ) = f ( x ( 1 ) ) f ( x ( 2 ) ) 2 d(x^{(1)},x^{(2)})=||f(x^{(1)})−f(x^{(2)})||^2

在这里插入图片描述

Triplet Loss

如何通过学习神经网络的参数,得到优质的人脸图片的编码?方法之一就是定义 Triplet 损失函数,并在其之上运用梯度下降。

学习目标:

在这里插入图片描述

  • Anchor(A):目标图片
  • Positive(P):与Anchor属于同一个人的图片
  • Negative(N):与Anchor不属于同一个人的图片

对于Anchor和Positive,我们希望两者编码的差异小一点;对于Anchor 和Negative,我们希望他们编码的差异大一些。所以我们的目标以编码差的范数来表示为:

d ( A , P ) = f ( A ) f ( P ) 2 f ( A ) f ( N ) 2 = d ( A , N ) d(A,P)=||f(A)−f(P)||^2⩽||f(A)−f(N)||^2=d(A,N)

也就是:

f ( A ) f ( P ) 2 f ( A ) f ( N ) 2 0 ||f(A)−f(P)||^2−||f(A)−f(N)||^2⩽0

上面的公式存在一个问题就是,当f(A)=f§=f(N)=0时,也就是神经网络学习到的函数总是输出0时,或者f(A)=f§=f(N)时,也满足上面的公式,但却不是我们想要的目标结果。所以为了防止出现这种情况,我们对上式进行修改,使得两者差要小于一个较小的负数:
f ( A ) f ( P ) 2 f ( A ) F ( N ) 2 α ||f(A)−f(P)||^2−||f(A)−F(N)||^2≤−α
f ( A ) f ( P ) 2 f ( A ) F ( N ) 2 + α 0 ||f(A)−f(P)||^2−||f(A)−F(N)||^2+α≤0

这里的 α α 也被称为边界margin,类似与支持向量机中的margin。举个例子,若d(A,P)=0.5, α α =0.2,则d(A,N)≥0.7。

Triplet损失函数:

Triplet损失函数的定义基于三张图片:Anchor、Positive、Negative。

L ( A , P , N ) = m a x ( f ( A ) f ( P ) 2 f ( A ) f ( N ) 2 + α , 0 ) L(A,P,N)=max(||f(A)−f(P)||^2−||f(A)−f(N)||^2+α, 0)

整个网络的代价函数:

J = i = 1 m L ( A ( i ) , p ( i ) , N ( i ) ) J=\sum_{i=1}^mL(A^{(i)},p^{(i)},N^{(i)})

假设我们有一个10000张片的训练集,里面是1000个不同的人的照片样本。我们需要做的就是从这10000张训练集中抽取图片生成(A,P,N)的三元组,来训练我们的学习算法,并在Triplet 损失函数上进行梯度下降。

注意:为了训练我们的网络,我们必须拥有Anchor和Positive对,所以这里我们必须有每个人的多张照片,而不能仅仅是一张照片,否则无法训练网络。

三元组的选择:

同一组训练样本,A,P,N的选择尽可能不要使用随机选取方法。因为随机选择的A与P一般比较接近,A与N相差也较大,毕竟是两个不同人脸。这样的话,也许模型不需要经过复杂训练就能实现这种明显识别,但是抓不住关键区别。所以,最好的做法是人为选择A与P相差较大(例如换发型,留胡须等),A与N相差较小(例如发型一致,肤色一致等)。这种人为地增加难度和混淆度会让模型本身去寻找学习不同人脸之间关键的差异,“尽力”让d(A,P)更小,让d(A,N)更大,即让模型性能更好。

如下所示:

在这里插入图片描述

对于大型的人脸识别系统,常常具有上百万甚至上亿的训练数据集,我们并不容易得到。所以对于该领域,我们常常是下载别人在网上上传的预训练模型,而不是从头开始。

Face Verification and Binary Classification

除了构造triplet loss来解决人脸识别问题之外,还可以使用二分类结构。做法是将两个siamese网络组合在一起,将各自的编码层输出经过一个逻辑输出单元,该神经元使用sigmoid函数,输出1则表示识别为同一人,输出0则表示识别为不同人。结构如下:

在这里插入图片描述

每组训练样本包含两张图片,每个siamese网络结构和参数完全相同。这样就把人脸识别问题转化成了一个二分类问题。引入逻辑输出层参数w和b,输出ŷ表达式为:

y ^ = σ ( k = 1 K w k f ( x ( i ) ) k f ( x ( j ) ) k + b ) \hat{y} =\sigma(\sum_{k=1}^Kw_k|f(x^{(i)})_k−f(x^{(j)})_k|+b)

其中参数 w k w_k 和b都是通过梯度下降算法迭代训练得到。

y ^ \hat{y} 的另外一种表达式为:

y ^ = σ ( k = 1 K w k ( f ( x ( i ) ) k f ( x ( j ) ) k ) 2 f ( x ( i ) ) k + f ( x ( j ) ) k + b ) \hat{y} =\sigma(\sum_{k=1}^Kw_k\frac{(f(x^{(i)})_k−f(x^{(j)})_k)^2}{f(x^{(i)})_k+f(x^{(j)})_k}+b)

上式被称为 χ \chi 方公式,也叫 χ \chi 方相似度。

在训练好网络之后,进行人脸识别的常规方法是测试图片与模板分别进行网络计算,编码层输出比较,计算逻辑输出单元。为了减少计算量,可以使用预计算的方式在训练时就将数据库每个模板的编码层输出f(x)保存下来。因为编码层输出f(x)比原始图片数据量少很多,所以无须保存模板图片,只要保存每个模板的f(x)即可,节约存储空间。而且,测试过程中,无须计算模板的siamese网络,只要计算测试图片的siamese网络,得到的 f ( x ( i ) ) f(x^{(i)}) 直接与存储的模板 f ( x ( j ) ) f(x^{(j)}) 进行下一步的逻辑输出单元计算即可,计算时间减小了接近一半。这种方法也可以应用在上一节的triplet loss网络中。

Neural Style Transfer

What is neural style transfer?

下面列出几个神经风格迁移的例子:
在这里插入图片描述

一般用C表示内容图片,S表示风格图片,G表示生成的图片。

What are deep ConvNets learning?

典型的CNN网络如下所示:

在这里插入图片描述

那么如何可视化呢?

在这里插入图片描述

可以看出,第一层隐藏层一般检测的是原始图像的边缘和颜色阴影等简单信息。

继续看CNN的更深隐藏层,随着层数的增加,捕捉的区域更大,特征更加复杂,从边缘到纹理再到具体物体。

在这里插入图片描述

Cost Function

神经风格迁移生成图片G的cost function由两部分组成:C与G的相似程度和S与G的相似程度。
J ( G ) = α J c o n t e n t ( C , G ) + β J s t y l e ( S , G ) J(G)=α⋅J_{content}(C,G)+β⋅J_{style}(S,G)
其中,α,β是超参数,用来调整Jcontent(C,G)与Jstyle(S,G)的相对比重。

在这里插入图片描述

神经风格迁移的基本算法流程是:首先令G为随机像素点,然后使用梯度下降算法,不断修正G的所有像素点,使得J(G)不断减小,从而使G逐渐有C的内容和G的风格,如下图所示。

在这里插入图片描述

Content Cost Function

  • 假设我们使用隐藏层l来计算内容代价。(如果选择的l太小,那么代价函数就会使得我们的生成图片G在像素上非常接近内容图片;然而用很深的网络,那么生成图片G中就会产生与内容图片中所拥有的物体。所以对于l一般选在网络的中间层,既不深也不浅);

  • 使用一个预训练的卷积网络。(如,VGG或其他);

  • a [ l ] ( C ) a^{[l](C)} a [ l ] ( G ) a^{[l](G)} 分别代表内容图片C和生成图片G的l层的激活值;

  • 如果 a [ l ] ( C ) a^{[l](C)} a [ l ] ( G ) a^{[l](G)} 相似,那么两张图片就有相似的内容;

    定义内容代价函数如下:
    J c o n t e n t ( C , G ) = 1 2 a [ l ] ( C ) a [ l ] ( G ) 2 J_{content}(C,G)=\frac{1}{2}||a^{[l](C)}−a^{[l](G)}||^2
    在对代价函数运行梯度下降算法时,会激励这里的内容代价函数,努力使得生成图片G隐含层l的激活值和内容图片C隐含层l的激活值相似。

Style Cost Function

“Style”的含义:

对于一个卷积网络中,我们选择网络的中间层l, 定义“Style”表示 l 层的各个通道激活项之间的相关性。

例如我们选取第l层隐藏层,其各通道使用不同颜色标注,如下图所示。因为每个通道提取图片的特征不同,比如1通道(红色)提取的是图片的垂直纹理特征,2通道(黄色)提取的是图片的橙色背景特征。那么计算这两个通道的相关性大小,相关性越大,表示原始图片及既包含了垂直纹理也包含了该橙色背景;相关性越小,表示原始图片并没有同时包含这两个特征。也就是说,计算不同通道的相关性,反映了原始图片特征间的相互关系,从某种程度上刻画了图片的“风格”。

在这里插入图片描述

接下来我们就可以定义图片的风格矩阵(style matrix)为:

G k k [ l ] = i = 1 n H [ l ] j = 1 n W [ l ] a i j k [ l ] a i j k [ l ] G_{kk'}^{[l]}=\sum_{i=1}^{n_H^{[l]}}\sum_{j=1}^{n^{[l]}_W}a^{[l]}_{ijk}a^{[l]}_{ijk'}

其中,[l]表示第l层隐藏层,k,k’分别表示不同通道,总共通道数为 n C [ l ] n^{[l]}_C 。i,j分别表示该隐藏层的高度和宽度。风格矩阵 G k k [ l ] G^{[l]}_{kk′} 计算第l层隐藏层不同通道对应的所有激活函数输出和。 G k k [ l ] G^{[l]}_{kk′} 的维度为 n c [ l ] n^{[l]}_c x n c [ l ] n^{[l]}_c 。若两个通道之间相似性高,则对应的 G k k [ l ] G^{[l]}_{kk′} 较大;若两个通道之间相似性低,则对应的 G k k [ l ] G^{[l]}_{kk′} 较小。

风格矩阵 G k k [ l ] ( S ) G^{[l](S)}_{kk'} 表征了风格图片S第l层隐藏层的“风格”。相应地,生成图片G也有 G k k [ l ] ( G ) G^{[l](G)}_{kk′} 。那么, G k k [ l ] [ S ] G^{[l][S]}_{kk′} G k k [ l ] [ G ] G^{[l][G]}_{kk′} 越相近,则表示G的风格越接近S。这样,我们就可以定义出 J s t y l e [ l ] ( S , G ) J^{[l]}_{style}(S,G) 的表达式: J s t y l e [ l ] ( S , G ) = 1 ( 2 n H [ l ] n W [ l ] n C [ l ] ) k = 1 n C [ l ] k = 1 n C [ l ] G k k [ l ] [ S ] G k k [ l ] [ G ] 2 J^{[l]}_{style}(S,G)=\frac{1}{(2n^{[l]}_Hn^{[l]}_Wn^{[l]}_C)}\sum_{k=1}^{n^{[l]}_C} \sum_{k′=1}^{n^{[l]}_C}||G^{[l][S]}_{kk′}−G^{[l][G]}_{kk′}||^2

定义完 J s t y l e [ l ] ( S , G ) J^{[l]}_{style}(S,G) 之后,我们的目标就是使用梯度下降算法,不断迭代修正G的像素值,使 J s t y l e [ l ] ( S , G ) J^{[l]}_{style}(S,G) 不断减小。

值得一提的是,以上我们只比较计算了一层隐藏层l。为了提取的“风格”更多,也可以使用多层隐藏层,然后相加,表达式为:
J s t y l e ( S , G ) = l λ [ l ] J s t y l e [ l ] ( S , G ) J_{style}(S,G)=\sum_lλ^{[l]}⋅J^{[l]}_{style}(S,G)
其中, λ [ l ] λ^{[l]} 表示累加过程中各层 J s t y l e [ l ] ( S , G ) J^{[l]}_{style}(S,G) 的权重系数,为超参数。
根据以上两小节的推导,最终的cost function为:
J ( G ) = α J c o n t e n t ( C , G ) + β J s t y l e ( S , G ) J(G)=α⋅J_{content}(C,G)+β⋅J_{style}(S,G)
使用梯度下降算法进行迭代优化。

1D and 3D Generalizations

我们之前介绍的CNN网络处理的都是2D图片,举例来介绍2D卷积的规则:

在这里插入图片描述

  • 输入图片维度:14 x 14 x 3
  • 滤波器尺寸:5 x 5 x 3,滤波器个数:16
  • 输出图片维度:10 x 10 x 16

将2D卷积推广到1D卷积,举例来介绍1D卷积的规则:

在这里插入图片描述

  • 输入时间序列维度:14 x 1
  • 滤波器尺寸:5 x 1,滤波器个数:16
  • 输出时间序列维度:10 x 16

对于3D卷积,举例来介绍其规则:

在这里插入图片描述

  • 输入3D图片维度:14 x 14 x 14 x 1
  • 滤波器尺寸:5 x 5 x 5 x 1,滤波器个数:16
  • 输出3D图片维度:10 x 10 x 10 x 16

猜你喜欢

转载自blog.csdn.net/qq_35564813/article/details/86506016