须知:本文作者建议各位读者结合Coursera上Andrew NG(吴恩达)教授的DeeLearning.ai课程一同学习,理解效果更佳。本文为《Convolutional Neural Networks》第四周 特殊应用:人脸识别和神经风格迁移的学习笔记。
神经风格迁移是卷积神经网络最有趣的应用之一,简单来说就是通过一种人工神经系统,实现了图像内容与风格的分离,从而允许以任何其他图像的风格重铸一个图像的内容。
我们来看几个例子。
先来看上图左半部分照片,Content(简记为C)是在斯坦福大学拍摄的,你想利用右边照片的风格来重新创造原本的照片,右边的Style(简记为S)是梵高的星空,利用神经风格迁移生成下方这幅梵高风格的Generated image(简记为G)。
再看上图右半部分照片,Content(简记为C)是在旧金山的金门大桥,右边的Style(简记为S)是毕加索的风格,利用神经风格迁移生成下方这幅张毕加索风格的的金门大桥 Generated image(简记为G)。
为了实现神经风格迁移,你需要知道卷积网络在不同的神经网络(深层的、浅层的)是如何提取特征的。我们先来看一下深度卷积网络到底在学什么?
以AlexNet为例,你希望将看到不同层之间隐藏单元的计算结果。
可以这样做:
从第一层的隐藏单元开始,将训练集经过神经网络,然找出哪一张图像最大限度地激活特定的单元。注意:在第一层的隐藏单元只能看到小部分卷积网络。
对其它层重复上述过程。
我们将每一层得到的最大程度激活的9个隐藏单元可视化出来,如下图:
将第二层的结果放大,我们发现,第二层似乎检测到更复杂的形状和模式,比如说这个隐藏单元(编号1),它会找到有很多垂线的垂直图案,这个隐藏单元(编号2)似乎在左侧有圆形图案时会被高度激活,这个的特征(编号3)是很细的垂线,以此类推,第二层检测的特征变得更加复杂。
第五层检测到更加复杂的事物,注意到这(编号1)也有一个神经元,似乎是一个狗检测器,但是可以检测到的狗似乎更加多样性。这个(编号2)可以检测到键盘,或者是键盘质地的物体,可能是有很多点的物体。我认为这个神经元(编号3)可能检测到文本,但是很难确定,这个(编号 4)检测到花。
感兴趣的话,更多细节可阅读这篇论文:
Visualizing and Understanding Convolutional Networks
我们发现,从第一层的边缘,到第二层的质地,……,到深层的复杂物体,越往后会越找到复杂的形状和模式。
要构建一个神经风格迁移系统,需要为生成的图像定义一个代价函数,通过最小化此代价函数,生成我们想要的图像。
换言之,我们的问题是,给了一个内容图像 C C C,给定一个风格图片 S S S,而目标是生成一个新图片 G G G。为了实现神经风格迁移,你要做的是定义一个关于 G G G的代价函数 J J J用来评判某个生成图像的好坏,我们将使用梯度下降法去最小化 J ( G ) J(G) J(G),以便于生成这个图像。
代价函数分为两部分:
第一部分被称作内容代价函数,这是一个关于内容图片和生成图片的函数,它是用来度量生成图片 G G G的内容与内容图片 C C C的内容有多相似。
第二部分是风格代价函数,也就是关于 S S S和 G G G的函数,用来度量生成图片 G G G的风格和风格图片 S S S的风格的相似度。
α \alpha α、 β \beta β是两个超参数,用来确定内容代价和风格代价的权重。
有兴趣的可以阅读一下这篇论文:A Neural Algorithm of Artistic Style
算法如何运行?
举个例子:
假设你从这张内容图片(编号1)和风格(编号2)图片(毕加索)开始,当你随机初始化 G G G生成的图像就是这张随机选取像素的白噪声图(编号3)。接下来运行梯度下降算法,最小化代价函数 J ( G ) J(G) J(G),逐步处理像素,这样慢慢得到一个生成图片(编号4、5、6),越来越像用风格图片的风格画出来的内容图片。
我们已经知道,神经风格迁移网络的代价函数由内容代价函数和风格代价函数两部分组成。
那么什么是内容代价函数呢?
如果 l l l是个很小的数,比如用隐含层1,这个代价函数就会使你的生成图片像素上非常接近你的内容图片。然而如果你用很深的层,那么就会问,内容图片里是否有狗,然后它就会确保生成图片里有一个狗。所以在实际中,这个层 l l l在网络中既不会选的太浅也不会选的太深。
- 取 l l l层的隐含单元的激活值,求L2范数。
- 1/2 类似于归一化,也可取其他值,也可以不取,因为代价函数前有权重系数。
- 注意这里都为向量形式。
对于一个卷积神经网络,我们选择某一层 l l l(如图中编号1),用这一层去为图片做一个深度测量,而图片的风格定义为 l l l层中各个通道之间激活项的相关系数。
将 l l l 层的激活项取出,是一个 n H ∗ n W ∗ n C n_H*n_W*n_C nH∗nW∗nC的三维数据块。如何知道这些不同通道之间激活项的相关系数呢?
什么时候两个通道拥有高度相关性呢?
如果它们有高度相关性,那么这幅图片中出现垂直纹理的地方(编号 2),那么这块地方(编号 4)很大概率是橙色的。
如果说它们是不相关的,这意味着图片中有垂直纹理的地方很大概率不是橙色的。
相关系数描述的就是当图片某处出现这种垂直纹理时,该处又同时是橙色的可能性。
我们将相关系数应用到风格图片S和生成图片G的对应通道上,就可以度量风格图片和生成图片的相似度。
G k , k ′ [ l ] ( S ) = ∑ i = 1 n H [ l ] ∑ j = 1 n W [ l ] a i , j , k [ l ] ( S ) a i , j , k ′ [ l ] ( S ) G_{k,k'}^{[l](S)}=\sum_{i=1}^{n_H^{[l]}}\sum_{j=1}^{n_W^{[l]}}a_{i,j,k}^{[l](S)}a_{i,j,k'}^{[l](S)} Gk,k′[l](S)=i=1∑nH[l]j=1∑nW[l]ai,j,k[l](S)ai,j,k′[l](S)
G k , k ′ [ l ] ( G ) = ∑ i = 1 n H [ l ] ∑ j = 1 n W [ l ] a i , j , k [ l ] ( G ) a i , j , k ′ [ l ] ( G ) G_{k,k'}^{[l](G)}=\sum_{i=1}^{n_H^{[l]}}\sum_{j=1}^{n_W^{[l]}}a_{i,j,k}^{[l](G)}a_{i,j,k'}^{[l](G)} Gk,k′[l](G)=i=1∑nH[l]j=1∑nW[l]ai,j,k[l](G)ai,j,k′[l](G)
- G G G是一个矩阵,高度和宽度都是 l l l层的通道数
- i , j i,j i,j是激活块中对应位置的坐标,也就是该激活项所在的高和宽, i i i会从1加到 n H [ l ] n_H^{[l]} nH[l], j j j会从1加到 n W [ l ] n_W^{[l]} nW[l]
- 用 G k , k ′ [ l ] G_{k,k'}^{[l]} Gk,k′[l]来描述 k k k通道和 k ′ k' k′通道激活项之间的相关系数, k k k和 k ′ k' k′会在1到 n c n_c nc之间取值, n c n_c nc就是 l l l层通道的总数
- 将 k k k通道和 k ′ k' k′通道上对应位置的激活项相乘
- 上标( S S S)和( G G G)分别表示风格图像 S S S和生成图像 G G G
- 是一种非标准的互协方差,因为我们并没有减去均值而只是把这些元素直接相乘,这就是计算图像风格的方法。
同内容代价函数一样,前面的归一化常数可以去掉,因为代价函数前有权重系数。
我们大部分讨论的图像数据,某种意义上而言都是2D数据。许多你所掌握的思想不仅局限于2D图像,也可以延伸至1D,乃至3D数据。