什么是风格转化

什么是风格转化呢?比如让一幅手机拍摄的照片自动变成抽象派画风。我们看一下用卷积神经网络怎么实现呢?
用卷积神经网络来进行图片的风格转化,我们一般需要两张图片,一张Content 用C来表示,是你的输入,需要改变的图片。一张是Style图片,用S表示,是你希望的风格的图片。输出是Generated image。用G表示,是你的输入图片进行了风格转换后生成的图片。

深度卷神经网络在学什么

我们拿一个训练好的深度卷积神经网络来说,每一个卷积层都有很多Filter(也有叫做核函数)。filter进行卷积计算时会有一个activator方法。我们选取那些能让activator方法输出较大值的输入。反推回输入的图片,因为是卷积,它对应的应该是图片上的一块区域。卷积层越浅,对应的图像越小,也越是细节内容,后边卷积层越深,对应的图像区域越大,越是整体内容。比如:

第一层只有一些线条,第二层就有一些曲线,然后第三第四层就有一些图像的局部信息。第五层就出现人脸。

如何定义Cost Function

对于我们的风格迁移问题,应该如何定义Cost Function呢?
这个CostFunction应该要能反应两方面问题:
1. 是否忠于原图,生成的新图不能让人分辨不出是原图。
2. 是否有我们期望的风格。
所以它的Cost Function定义也有两部分:
J(G) = \alpha J_{content}(C,G) + \beta J_{style}(S,G)
其中的参数\alpha,\beta就是来控制生成图片G对上边两个问题的比重。这两部分分别叫做内容代价函数和风格代价函数。

如何生成图片G

  1. 生成一个随机图片G,比如是100*100*3的矩阵来代表分辨率为100*100分辨率的RGB3通道图片。
  2. 利用梯度下降算法来最小化我们定义的J(G)。这一步比较有意思,之前我们梯度下降更新的是weight值,现在我们更新的是输入图片。对于神经网络来说它更新的参数。之前我们是把网络的weight和bias作为参数,这里我们把input作为参数让梯度下降去更新。

比如我们的C和S图片分别为:

通过上边的算法,我们逐步把随机图片更新为:

内容代价函数

我们风格转化的总体代价函数是由两部分构成,一部分是内容代价函数,用来代表G和C的相似程度。那么我们该如何定义内容代价函数呢?

layer选取

我们知道深度卷积网络每个卷积层都会从图像里学到一些特征。那么那一层可以代表内容呢?如果选浅层,都是一些线条等低级特征。深层又是一些组合好的具体的图像。所以我们认为应该选在中层。

使用已有模型

我们可以使用之前训练好的图像识别的模型作为迁移学习的原始模型,比如我们可以使用VGG network。

如何定义内容代价函数

现在我们有了训练好的模型,也选好了一层,比如第l层。我们也有图像C和图像G。
我们的做法是比较图像C和G在l层的输出,也就是l层经过激活函数后产生的值。如果两个值比较接近,那么就说两个图类似。
J_{content}(C,G) = \frac{1}{2}{\left \| a^{[l](C)}-a^{[l](G)} \right \|}^2
上边的公式就是就是两个图片C,G 通过深度卷积网络l层输出的矩阵对应位置差值的平方和。

风格代价函数

风格代价函数比较有意思。什么叫做风格呢?不论什么风格,如果细分下去,无非颜色和线条等基本特征。而风格可以说就是一些特征的联合使用。比如红色+粗线条,白色+螺旋等。那我们应该怎样表示风格呢?就是不同特征的相关性。比如红色和线条相关,红色和螺旋不相关。这是一种风格,我们的卷积网络里的filter可以检测一个特征。那么特征的相关就可以转化为同一组input使用不同filter的输出是否相关。比如说对图像各个小的块同时用检测红色的filter和检测线条的filter进行计算,得到两组输出向量。如果发现这两组输出向量是线性相关的。那么我们就可以得出结论这幅画的风格是使用了大量的红色线条。那么我们生成的图里应该也要使用大量的红色线条才对。

我们给出更正式的定义:
首先我们假设第l层的输出为i*j*k 也就是长为i,宽为j,channel为k个,因为channel为k个,也就是这一层里我们检测了k个特征. 我们就要看一下这k个特征在l层的输入下的两两相关性.因为计算两两相关性,我们需要用k*k的矩阵来存这个相关性矩阵.
我们对于图像G和S分别在第l层计算出k*k大小的相关性矩阵。然后计算两个相关性矩阵对象位置的差值的平方和。就得到了风格代价函数。
对于风格,我们可以多选取一些层,或者使用所有的卷积层来计算风格损失函数,因为决定风格的特征既有细小的特征,也有组合的特征。

现在你应该可以列出风格转换函数总的代价函数了,它包含了内容代价函数和风格代价函数。然后利用梯度下降来改变输入的值,注意,不是改变weight的值。最终就得到一张既保留了我们原始内容也有新的风格的图片。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: