点击量:1232
本文介绍Coursera-Deep Learning第四课卷积神经网络最后一节内容:神经风格转换(Neural Style Transfer)。
什么是神经风格转换?
这个概念其实没有明确的定义,但是看一张图就能一目了然了:
最左边是一张古城的照片,而右边则是梵高的著名油画作品:星夜。现在我们在两者的基础上合成一张含有星夜的风格的古城照片,这就是神经风格转换。这应该是神经网络应用里最有趣最好玩的一个了,那么它具体是如何实现的呢?
问题描述
为了后面的解释更清楚,我们先做一些定义:
- 内容图片称为Content Image,简写为C
- 风格图片称为Style Image,简写为S
- 合成图片称为Generated Image,简写为G
直觉上,最后合成的图像G至少应该满足以下两个条件:
- 1.内容要和内容图片的内容尽可能接近
- 2.风格要和风格图片的风格尽可能接近
损失函数
要实现一个有趣的神经网络应用,最重要的是你如何去定义或者说找到它的损失函数。根据上面所说的条件,那么神经风格转换的损失函数应该由两部分组成,它的大致形式如下:
$$
J(G) = \alpha J_{content}(G,C) + \beta J_{style}(G,S)
$$
其中,\(J_{content}(G,C)\)代表的是内容代价函数;而\(J_{style}(G,S)\)代表的风格代价函数;\(\alpha\)和\(\beta\)则是调节系数。
内容代价函数
我们如何定义“内容要和内容图片尽可能接近”呢?我们知道卷积神经网络有一种直观的解释是:每一层的神经元的数值其实是代表了图像的某种特征,而且随着层数的递增,这些特征会越来越复杂,比如第一层只是提取出一些边缘,色彩等,而到后面则会提取出一些比较抽象的特征:
那么我们就可以选取其中某一层\(l\)的神经元作为计算对象,计算他们之间的数值差即可作为他们内容的差异性。于是,内容代价函数就可以定义为:
$$
J_{content}(C,G) = ||a^{[l](C)}-a^{[l](G)}||^2
$$
其中,\(a^{[l](C)}\)表示内容图片在\(l\)层的神经元;\(a^{[l](G)}\)表示合成图片在\(l\)层的神经元;
风格代价函数
内容代价函数是很好理解的,那么风格代价函数该如何定义呢?要定义风格代价函数,我们首先得解决一个问题:如何定义风格?
这篇论文里是这样定义风格的:不同通道之间神经元的相关性决定了该图像的风格。这个怎么理解呢?比如通道1是黄色的,通道2是带有竖条的栅栏,如果通道1和通道2在数值上是相关的,那么我们就可以推断这幅图像的一个风格是:黄色的栅栏。这样解释是说的通的。相关性一般的计算方式是通过协方差,这里我们用的是非标准的形式,只是两个数值相乘,并没有减去均值。因此,风格图像S和合成图像G在第\(l\)层的风格值定义如下:
$$
G_{kk’}^{[l](S)} = \sum_{i=1}^{n_h}\sum_{j=1}^{n_w} a_{i,j,k}^{[l](S)}a_{i,j,k’}^{[l](S)} \\
G_{kk’}^{[l](G)} = \sum_{i=1}^{n_h}\sum_{j=1}^{n_w} a_{i,j,k}^{[l](G)}a_{i,j,k’}^{[l](G)}
$$
其中,
- \(a_{i,j,k}^{[l]}\)是在通道\(k\),高度\(i\),宽度\(j\)处的神经元
- \(k\)和\(k’\)都取自\([1,n_c]\),所以我们不难发现\(G_{kk’}^{[l](S)} \)和\(G_{kk’}^{[l](G)}\)其实是一个对称矩阵,这种矩阵也被称为Gram Matrix.
在明确了风格的定义之后,风格代价函数自然也就很简单了,只要两者作差即可:
$$
J_{style}(S,G)^{[l]} = ||G_{}^{[l](S)} – G_{}^{[l](G)}||^2
$$
$$
J_{style}(S,G)^{[l]} = \sum_{k}\sum_{k’} (G_{kk’}^{[l](S)} – G_{kk’}^{[l](G)})^2
$$
有时候为了更好的效果,我们会把各层的风格损失函数累加起来,于是我们有:
$$
J_{style}(S,G) = \sum_{l=1}^{L}J_{style}(S,G)^{[l]}
$$