Deeplearning.AI 卷积神经网络 Week4 6-11
目录
- 神经风格转换
- 可视化深层卷积神经网络
- 神经风格迁移代价函数
- 内容代价函数
- 神经风格损失函数
- 向一维和三维推广
精神风格转换
什么是精神风格转换
- 精神风格转换是卷积神经网络比较有趣的一个应用,相信很多人的手机里面都有一些比较有趣的滤镜,比如你用手机拍摄一张图片,并用手机一些特定风格的滤镜加以处理,就可以自动生成一张具有你图片内容和滤镜风格的图片,这是一项特别有趣的功能,我也曾用手机相机的这项功能拍摄过我校的图书馆。如下图:
上图就是一张用手机拍摄的原图。
这是手机自带滤镜之一,选自梵高的星夜,印象派代表作之一。我们看看两者的结合是什么样子的呢?
上图提取了我拍摄的图书馆的内容和梵高星夜的风格组合成了一张神奇的图片,怎么样?有没有感受到神经风格转换的神奇之处呢?让我们继续讨论一个神经风格转换神经网络是如何实现的吧!
可视化深层卷积神经网络
如何可视化卷积神经网络?
- 在讨论风格迁移之前,首先我觉得我们应该明白卷积神经网络在干什么?是如何提取特征的?为了明白神经网络每一层在干什么,我们要对卷积神经网络可视化,可视化具体由以下三个步骤组成:
- 在你希望了解的隐藏层选取一个隐藏单元
- 遍历整个训练集选取n个最大化激活该隐藏单元的像素(在课件中选取的 n = 9 n=9 n=9)
- 对于每一个隐藏单元重复上述步骤
这样你就可以看到每一个隐藏神经元提取到了什么样的特征。
每一层提取到了什么样的特征?
- 第一个隐藏层往往提取到的是一些边缘或颜色阴影等特征。之前在讲为什么卷积神经网络会有效的时候,曾经提到过过滤器如何通过分辨明暗的差异来找出边缘特征。
- 第二个隐藏层能提取出一些质地特征,如下图所示:
我们可以看到,有的隐藏单元检测到了一些垂直或竖直的线,有的检测到了土黄色的背景,有的检测到了左侧的圆圈,总之在第二个隐藏层可以检测到比第一个范围更广的信息。 - 在后面的隐藏层中每个隐藏单元可以检测到的东西的类别变得更加具体,每个隐藏单元都会对特定类别的东西敏感(比如:有的单元对于狗比较敏感,有的单元对于车胎敏感等等),实现了分别不同物体的功能。
神经风格迁移代价函数
如何定义神经风格迁移代价函数?
- 我们约定内容图片为C(content),风格图片为S(Style),生成的神经风格迁移图片为G(Generated)。所以,我们如下定义损失函数:
J ( G ) = α ∗ J c o n t e n t ( C , G ) + β ∗ J s t y l e ( S , G ) J(G)=\alpha*J_{content}(C,G)+\beta*J_{style}(S,G) J(G)=α∗Jcontent(C,G)+β∗Jstyle(S,G)
神经风格迁移的代价函数是由内容代价函数和风格代价函数共同决定的,即神经风格迁移的代价函数依次考量了生成的图片与内容图片和风格函数的近似程度。此外 α \alpha α和 β \beta β是两个超参数负责调节权重。
如何生成一张神经风格迁移的图片?
- 将图片随机初始化成你需要的尺寸。比如:100x100x3
- 使用梯度下降的方法最小化代价函数
J
(
G
)
J(G)
J(G):
G = G − ∂ ∂ G J ( G ) G=G-\frac{\partial }{\partial G}J(G) G=G−∂G∂J(G)
内容代价函数
- 选择一个隐藏层 l l l作为计算的对象。但是这个**隐藏层选取往往不是太深也不是太浅,会选择相对中间的层。**因为如果隐藏层太浅了那么代价函数就会使得我们的生成图片G在像素上非常接近内容图片;然而用很深的网络,那么生成图片G中就会产生与内容图片中所拥有的物体。(此处我也不是很理解,先记录下来。)
- 选取一个卷积神经网络作为预训练模型(比如: V G G n e t w o r k VGG network VGGnetwork)
- 规定
a
[
l
]
(
C
)
a^{[l](C)}
a[l](C)和
a
[
l
]
(
G
)
a^{[l](G)}
a[l](G)是来卷积神经网络内容图片和生成图片的第
l
l
l层的激活函数值,则定义代价函数:
J c o n t e n t ( C , G ) = ∣ a [ l ] ( C ) − a [ l ] ( G ) ∣ 2 J_{content}(C,G)=|a^{[l](C)}-a^{[l](G)}|^{2} Jcontent(C,G)=∣a[l](C)−a[l](G)∣2
注意,因为这里面的 a [ l ] ( C ) a^{[l](C)} a[l](C)和 a [ l ] ( G ) a^{[l](G)} a[l](G)是向量所以两者的差也是一个向量,向量的模方相当于对向量中的每一项分别取平方再相加。
风格代价函数
如何衡量两张图片的风格是否相似?
- 首先我们选取卷积神经网络的一个隐藏层 l l l的激活函数的值来定义这个图片的风格。
- 图片的风格的衡量来源于每两个通道之间的相关系数(这里的相关系数和统计中的相关系数不是一个东西)。相关系数大代表两个通道之间的关系很大,相关系数小代表两个通道之间关系小。比较两个不同图片相同通道之间的相关系数,如果两个图片的相关系数相差较小,证明这两个图片的风格相近。根据每两个通道间的相关系数我们可以定义一个风格矩阵 G [ l ] G^{[l]} G[l]的概念,在后面我们会详细介绍。
- 你可能会疑问,为啥两个图片的相关系数相近,则两个图片风格相似?这就涉及到了相关系数能代表什么?我们看看下图的例子:
在学过本周第7节(也就是notes上面写的深度卷积神经网络都干点啥那一节),你应该知道同一层的不同通道实际上是提取了数据集不同的特征加以分类,如果在某张图片中某两个特征同时出现,那么在这张图片中这两个通道的相关系数就会很高。
比如在上面图片中红色通道对应提取了竖直条纹这一特征,黄色通道提取了土黄色这一特征。如果在一张图片上两者同时出现,那么两者的相关系数就较高。如果在另一张图片上两者也同时出现你,那么在那一张图片上两者的相关系数也会很高。所以两张图片相关系数的差值就会很小。相反,如果两者都没有出现,那么两者的相关系数都会比较低,这样两者相关系数的差值也会很小。
所以,如果两张图片风格相似,那么不同特征同时出现或者同时不出现的情况应该是相似的,故而我们引入了风格矩阵这一概念来依次比较任意两个通道相关系数的差值和,从而确定两张图片的风格是否类似。 - 下一部分我们将接受如何定义风格矩阵和风格代价函数。
如何建立风格代价函数?
- 约定一些符号:
- a i , j , k [ l ] a^{[l]}_{i,j,k} ai,j,k[l]代表的是第 l l l层的激活函数在第 k k k个通道的第 i i i行、第 j j j列的值。
- n H nH nH、 n W nW nW和 n C nC nC则分别代表第 l l l层对应的结果的长宽高三个维度的大小。 n H nH nH、 n W nW nW和 n C nC nC则分别代表第 l l l层对应的结果的长宽高三个维度的大小。
- G [ l ] G^{[l]} G[l]代表风格矩阵,是我们要求的一个参数,为了区分是风格图片还是生成图片的风格矩阵,我们用 G [ l ] ( s ) G^{[l](s)} G[l](s)代表风格图片的风格矩阵, G [ l ] ( G ) G^{[l](G)} G[l](G)代表生成图片的风格矩阵。
- 求风格矩阵
- 风格矩阵实际上就是由任意两个通道( k k k和 k ′ {k}' k′)的相关系数构成的矩阵,矩阵中第 k k k行第 k ′ {k}' k′列对应的就是第 k k k个通道和第 k ′ {k}' k′个通道的相关系数。所以风格矩阵是一个 n C nC nC* n C nC nC大小的矩阵。
- 下面给出求相关系数的公式:
G k k ′ [ l ] = ∑ i = 0 n H ∑ j = 0 n W a i j k [ l ] ∗ a i j k ′ [ l ] G^{[l]}_{kk'}=\sum _{i=0}^{nH}\sum _{j=0}^{nW}a^{[l]}_{ijk}*a^{[l]}_{ijk'} Gkk′[l]=∑i=0nH∑j=0nWaijk[l]∗aijk′[l]
这个公式就是将第 k k k个通道和第 k ′ {k}' k′个通道中的每一个元素对应相乘并求和作为两个通道的相关系数,这有点像交叉熵的思想。 - 将每一个相关系数依次罗列起来就求得风格矩阵了。
- 代价函数:
- 第
l
l
l层的代价函数:
J s t y l e [ l ] ( S , G ) = 1 2 n H [ l ] n W [ l ] n C [ l ] 2 ∗ ∣ G [ l ] ( S ) − G [ l ] ( G ) ∣ 2 J^{[l]}_{style}(S,G)=\frac{1}{2n^{[l]}_Hn_{W}^{[l]}n_{C}^{[l]}}^{2}*|G^{[l](S)}- G^{[l](G)}|^{2} Jstyle[l](S,G)=2nH[l]nW[l]nC[l]12∗∣G[l](S)−G[l](G)∣2
注意,因为这里面的 G [ l ] ( S ) G^{[l](S)} G[l](S)和 G [ l ] ( G ) G^{[l](G)} G[l](G)是向量所以两者的差也是一个向量,向量的模方相当于对向量中的每一项分别取平方再相加。此外,前面的一项是一个归一化参数。 - 风格代价函数:
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}\lambda ^{[l]}*J_{style}^{[l]}(S,G) Jstyle(S,G)=∑lλ[l]∗Jstyle[l](S,G)
这个代价函数的意思就是不要只根据某一层的数据来判断两幅图片的风格,多看几层并加以权重,这样会更加具有泛化能力。
向一维和三维推广
我们学习了许多关于2D图像卷积的例子,有时候我们也需要处理1D或者3D的数据,实际上卷积在这些应用场景同样适用。
我们思考一个问题2D神经网络输入卷积的输入数据大小是
n
H
∗
n
W
∗
n
C
nH*nW*nC
nH∗nW∗nC(由
n
H
nH
nH长、
n
W
nW
nW宽和
n
C
nC
nC个通道构成的),过滤器大小是
n
H
′
∗
n
W
′
∗
n
C
nH'*nW'*nC
nH′∗nW′∗nC,两者的通道数相同。这就说明2D卷积的过滤器组成是除了两个长宽维度外加上通道数3个维度。对于nD的卷积过程实际上就是n给维度+通道个数。
2D向1D的推广
- 按照上面的推广方式1D卷积的过滤器应该由长度维度和通道数组成,我们举个例子:
上图是一个检测人体心跳数据的例子,我们知道心跳是一个只跟时间有关的函数,所以是一个一维的例子。如图输入数据是一个 14 ∗ 1 14*1 14∗1的数据,所以过滤器也应该选择合适的大小 ∗ 1 *1 ∗1(原数据有一个通道),这里选择是一个 5 ∗ 1 5*1 5∗1的过滤器,过滤器个数选为 16 16 16个,故而经过卷积得到的数据大小为 10 ∗ 16 10*16 10∗16。
由2D向3D推广
- 与2D向1D推广类似的,3D卷积的过滤器应该选择合适的长宽深和通道数并进行卷积操作,在这里不再赘述。