这是一篇 Neural Style Transfer 的简要介绍。一方面是我的学习笔记,另一方面想向大家介绍这种有趣的神经网络应用。
我不知道是否该翻译为「风格迁移神经网络」。但它的英文原名清晰地给出了3个信息:

Neural-神经 Style-风格 Transfer-传输/转换/迁移

这也是它最核心的3个属性。

Neural Style Transfer能做什么呢,就是学习一种图像的风格,然后把别的图像转换为这种风格。像下图所示:

开始之前,先介绍一篇论文:Visualizing and Understanding Convolutional Networks
它介绍了如何可视化呈现和理解一个卷积神经网络:神经网络的每一层都执行着不同的筛选动作,对于特定的一层,你可以随机选取其中几个 Unit,来看看它被哪些输入强烈地激发(activation 很高,意味着这个 Unit 关注这项特征),然后把这几个最强的输入 print 出来看看:

这样就能知道某个 Unit 最关注的是什么内容。
通过观察可以看到:随着网络深度的增加,其中 Unit 关注的内容越来越抽象/高级。从一开始的点、线、纹理,到后面的层数里关注的车轮、人脸。
接着人们发现,深度神经网络足够深的时候,就能识别出图像的抽象概念。也就是说,很深的 layer 里,Units 学会了输入图像的「风格」。这个风格可以被用来生成新的图像。
以上就是 Neural Style Transfer 的理论基础,或者说 Intuition。


具体实现上,假如已有一个经过良好训练的神经网络,它的每个 Unit 都已经有了自己关注的图像特征。然后我们假定它的 Layer l 有一个恰当的深度(够抽象,又不过于抽象),就将 Layer l 的输出值视为对图像的一套「编码」Encoding)。

拦截了 layer l 的输出,将其作为图像 A 的一套编码 A’

当我们生成的图像与目标图像足够接近时,它们的「编码」应当是非常接近的(两张相同的图片会输出相同的编码)。我们的思路就是不断地生成图像,(每次生成都基于前一次的图像做修正),直到修正出风格非常接近的图像。

注意到了吗?——平时我们训练的是「神经网络」自身,现在神经网络本身是固定的,我们要训练的是神经网络的输入:某个图像。
为了达到这个目的,像所有的机器学习工程一样,我们需要定义一个 Cost Function。在迭代的训练过程中对输入求导(梯度下降),使 Cost 值变小,以接近我们的目标。

考虑 Neural Style Transfer 的特殊性,我们的 Cost Function 将由2部分组成。其一用于计算生成图(G)原图(C)的相似性,另一用于计算生成图(G)风格图(S)的相似性。

(1)   \begin{equation*} J(G) = \alpha J_{content}(C,G) + \beta J_{style}(S,G)\end{equation*}

对于每一次输入的生成图(G)J_{content} 计算了它与原图(C)的相似性,J_{style} 计算了它与风格图(S)的相似性。 J_{content}J_{style} 也就是两个子 cost function,它们的值也都是越小越好。

为这两项分别加上系数 \alpha\beta,通过这两个系数来控制我们期望生成图更接近原图还是风格图。

接下来的风格迁移过程就很简单了:

  1. 随机生成一张图片
  2. 使用 Gradient Descent 方法使 J(G) 尽可能的小

迭代过程就像这样:

但是事情显然没有那么简单,别忘了 J_{content}J_{style} 还没定义!

(2)   \begin{equation*}   J_{content}(C,G) =  \frac{1}{4 \times n_H \times n_W \times n_C}\sum _{ \text{all entries}} (a^{(C)} - a^{(G)})^2\end{equation*}

J_{content} 的定义非常简单,就是对神经网络的某一层 l,计算所有a(activation, l 这层网络的输出值)的方差。这个方差就相当于是两张图编码出来之后的结果的「距离」——离得太远就说明两张图「太不像」了。

J_{style} 的定义就稍微复杂一点。因为我们表征风格的相似性用到了一个新的矩阵 G

(3)   \begin{equation*}   J_{style}(S,G) = \frac{1}{(2 \times {n_C} \times n_H \times n_W)^2} \sum _{i=1}^{n_C}\sum_{j=1}^{n_C}(G^{(S)}_{i,j} - G^{(G)}_{i,j})^2\end{equation*}

这里不再是两张图的输出(a)求方差了,而是对两个G矩阵(Gram Matrix)。

(4)   \begin{equation*}   G_{kk^{'}} =  \sum_{i=1}^{n_H} \sum_{j=1}^{n_W} a_{ijk} a_{ijk^{'}}\end{equation*}

Gram Matrix 是线性代数中用于计算两个向量是否线性相关的一种方式。
在眼前这个例子中,我们知道神经网络的一个卷积层有3个维度:height、width、channel。
Neural Style Transfer 的发明者认为 channel 之间的相关性表征了图像的「风格」。因此,我们使用 Gram Matrix 对每个 channel 计算相关性,得出的矩阵就是这种风格的数学表达。
两个矩阵的差越小,就认为它们风格更相近。

好咯!有了这些理论基础,我们就可以搭建一个 Neural Style Transfer 工程了!更多细节参见论文原文: A Neural Algorithm of Artistic Style


来实践看看:

我们使用的是一个预训练好的神经网络VGG-19,它在图像识别方面已经「很有经验」(参数经过很好的调整,在大量图片的训练集上跑过训练,因此性能已经很好)。它的架构大致长这样:

前面讲过,神经网络自身是固定不动的,无需参数学习和调整。而选择一个恰当的「深度」作为编码的输出是很关键的,这里我们选择了"conv4_2"这层作为实验对象。

对于最终的 cost function,我们选定了参数 \alpha=10\beta=40 ,也就是风格化相似性的重要度远高于原图相似性

与上文的简化版本不同,经验上,人们发现:对网络的每一层都计算 Gram Matrix(风格相关性矩阵),把两张图所有的G之间的差距都加起来算 style cost 会更有效。因此我们在实践中也使用这个更复杂版的 style cost function。

  • 风格图(S):印象派画师莫奈的作品
  • 原图(C):我在九寨沟拍的照片

几轮训练跑下来的生成图结果如下:

完成!

观察训练的过程中 cost 变化:

Iteration 0 :
total cost = 4.46494e+09
content cost = 7673.14
style cost = 1.11622e+08
Iteration 20 :
total cost = 9.2457e+08
content cost = 13632.9
style cost = 2.31108e+07
Iteration 40 :
total cost = 4.98088e+08
content cost = 16207.1
style cost = 1.24482e+07
Iteration 60 :
total cost = 3.40788e+08
content cost = 17608.4
style cost = 8.5153e+06
Iteration 80 :
total cost = 2.59515e+08
content cost = 18401.5
style cost = 6.48327e+06

可以看到 content cost 从第一轮训练开始就降到非常低(我们的算法快速地生成出了与原图很接近的图),然而 style cost 高出很多个数量级(风格完全不同)。

随着迭代的进行,sytle cost 逐渐降低,content cost 逐渐增加。即:我们对 \alpha\beta 的选择决定了算法策略:请尽量风格化一些,不那么像原图也没关系!

训练到最后图像已经固定下来了,再继续跑也没有变化。意味着算法已经尽力平衡两种 cost 了,没法继续降低 total cost。辛苦了!VGG-19!

经过160轮迭代后输出的图像

Neural Style Transfer 的一些实践是很有启发性的。

深度神经网络较深的层次里包含了特定抽象概念的信息,因而可以把深层的输出值视作是对原图的一种「编码」。这个编码是原图的另一种抽象表达,虽然人类不太能看懂,但却能用它来做识别和计算——另一个典型应用就是人脸识别系统。人脸识别应用中,通过使用深层的编码来比对是否是同一个人。

另一方面:发明者认为 channel 之间的相关性表征了作品的风格。仔细想来是有道理的。因为在卷积神经网络中,每一层的 channel 其实是由上一层的 filter 定义的。那些 filter 筛选了不同的信息:色彩、材质、图像边缘…… 于是当作品的色彩、材质、线条组合在一起时,正是某种鲜明「风格」的表达。就算是人类画师,要模仿别人的作品,也一样是在模仿调色方案、绘画线条等等。

同时,利用这种生成思路,不仅可以用来生成艺术图像,还可以给大家创造二次元老婆、生成古风歌曲等等。