这是一篇 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 有一个恰当的深度(够抽象,又不过于抽象),就将 Layer 的输出值视为对图像的一套「编码」(Encoding)。
当我们生成的图像与目标图像足够接近时,它们的「编码」应当是非常接近的(两张相同的图片会输出相同的编码)。我们的思路就是不断地生成图像,(每次生成都基于前一次的图像做修正),直到修正出风格非常接近的图像。
注意到了吗?——平时我们训练的是「神经网络」自身,现在神经网络本身是固定的,我们要训练的是神经网络的输入:某个图像。
为了达到这个目的,像所有的机器学习工程一样,我们需要定义一个 Cost Function。在迭代的训练过程中对输入求导(梯度下降),使 Cost 值变小,以接近我们的目标。
考虑 Neural Style Transfer 的特殊性,我们的 Cost Function 将由2部分组成。其一用于计算生成图(G)与原图(C)的相似性,另一用于计算生成图(G)与风格图(S)的相似性。
(1)
对于每一次输入的生成图(G), 计算了它与原图(C)的相似性, 计算了它与风格图(S)的相似性。 和 也就是两个子 cost function,它们的值也都是越小越好。
为这两项分别加上系数 和 ,通过这两个系数来控制我们期望生成图更接近原图还是风格图。
接下来的风格迁移过程就很简单了:
- 随机生成一张图片
- 使用 Gradient Descent 方法使 尽可能的小
迭代过程就像这样:
但是事情显然没有那么简单,别忘了 和 还没定义!
(2)
的定义非常简单,就是对神经网络的某一层 ,计算所有(activation, 这层网络的输出值)的方差。这个方差就相当于是两张图编码出来之后的结果的「距离」——离得太远就说明两张图「太不像」了。
的定义就稍微复杂一点。因为我们表征风格的相似性用到了一个新的矩阵 。
(3)
这里不再是两张图的输出(a)求方差了,而是对两个G矩阵(Gram Matrix)。
(4)
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,我们选定了参数 和 ,也就是风格化相似性的重要度远高于原图相似性。
与上文的简化版本不同,经验上,人们发现:对网络的每一层都计算 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 逐渐增加。即:我们对 和 的选择决定了算法策略:请尽量风格化一些,不那么像原图也没关系!
训练到最后图像已经固定下来了,再继续跑也没有变化。意味着算法已经尽力平衡两种 cost 了,没法继续降低 total cost。辛苦了!VGG-19!
Neural Style Transfer 的一些实践是很有启发性的。
深度神经网络较深的层次里包含了特定抽象概念的信息,因而可以把深层的输出值视作是对原图的一种「编码」。这个编码是原图的另一种抽象表达,虽然人类不太能看懂,但却能用它来做识别和计算——另一个典型应用就是人脸识别系统。人脸识别应用中,通过使用深层的编码来比对是否是同一个人。
另一方面:发明者认为 channel 之间的相关性表征了作品的风格。仔细想来是有道理的。因为在卷积神经网络中,每一层的 channel 其实是由上一层的 filter 定义的。那些 filter 筛选了不同的信息:色彩、材质、图像边缘…… 于是当作品的色彩、材质、线条组合在一起时,正是某种鲜明「风格」的表达。就算是人类画师,要模仿别人的作品,也一样是在模仿调色方案、绘画线条等等。
同时,利用这种生成思路,不仅可以用来生成艺术图像,还可以给大家创造二次元老婆、生成古风歌曲等等。
发表回复