使用深度学习自动生成某一风格的图片

时间:2022-11-16 19:11:24

先贴上效果图,让前面两张图片具有梵高的星空之夜风格。

使用深度学习自动生成某一风格的图片
其中原始的图片为下面两张图片。
使用深度学习自动生成某一风格的图片

上面所展示的图片中,直观的理解是把梵高中的图片的这种风格揉到前面两张图片当中。但是,这种图片风格生成的并不是简单得让图片C尽量同时和图片A、B相似。(假设A是原始的想要变化的图片,B是风格图片(比如星空之夜),C是将要生成的图片,所以,这里可以叫A为内容图片,B为风格图片,C为生成图片),而是让C和A的“内容”尽量相似,同时让C的“风格”跟B的“风格”尽量相似。换句话说便是保留图片A的内容,但是要改变它的风格。这一点的具体实现将体现再损失函数的定义上面。如何定义C的内容以及它的风格呢?不用担心,下面会讲到的。

总体思路

使用深度学习自动生成某一风格的图片
在卷积神经网络中,如果下面是输入上面是输出,那么,从下到上卷积层所获取的图片特征将越来越全面。在风格转换卷积层中,选取中间某一个卷积层作为作为内容图片A,将A于生成图片C比较它们的相似度,越相似越好,两个矩阵(图片)对应像素之差的平方之和便是相似度,下面会给出具体的公式。同时,选取相关的卷积层作为风格图片B,然后和C比较风格相似度。选取风格图片有一点不一样,其中一种选取方法是,如果卷积层有5层,那么分别选取这5层,然后都分别乘以0.2的权重,然后相加之后得到风格图片。这里的权重可以改为其他的值,这只是其中的一种选择方法。只是不同的权重值将影响生成图片C最后的效果。(这一点暂时无法理解也没关系)

要进行风格的比较,首先需要使用数学公式表示出图片的风格。

两张图片可以理解为两个矩阵,格拉姆矩阵/Gram matrix可以表示矩阵中不同行和列之间的关联程度。而行和列的关联程度在图片上体现的是图片风格。所以,最终我们要比较的是两个图片的格拉姆矩阵的相似程度。

对于图片B,它的格拉姆矩阵为 G B = B B T ,对于C,它的格拉姆矩阵为 G C = C C T ,然后这两个格拉姆矩阵对应位置元素相减平方再求和,便可以得到两个格拉姆矩阵的相似度,也就是两个图片的风格的相似度了。

我们的目的是使得两个相似度都很高,分别是图片A和C的内容相似度,图片B和C的风格相似度。这样的图片C正是我们所想要的。由此便可以得出我们的损失函数,然后使用反向传播来训练模型,得到最后的结果。

这便是模型的总体思路。

损失函数

内容损失函数

使用深度学习自动生成某一风格的图片
其中。 a ( C ) a ( G ) 分别表示的是图片A和图片C某一卷积层激活函数的输出值。nH和nW以及nC分别表示图片的高、宽和通道个数。

风格损失函数

使用深度学习自动生成某一风格的图片
其中G表示的是格拉姆矩阵/Gram matrix。

最终的损失函数为:

使用深度学习自动生成某一风格的图片
其中系数a和β是全局系数,用它们来调节图片风格的严重程度。比如,如果a比β大很多,那么原始图片只有稍微一点点变化。

前向传播函数

使用VGG16作为我们的网络模型,同时使用别人已经训练好的VGG16模型参数来加快我们的模型的训练速度。
使用深度学习自动生成某一风格的图片

我们知道,神经网络模型最重要的是把模型的损失函数表达出来,这里,我们从上面的模型中可以获得内容图片和风格图片,然后成功表达出了损失函数。

所以,上面VGG16模型的全连接层是没有作用的。

优化问题

这里使用别人已经训练好的VGG16模型参数来加快我们的模型的训练速度。所以,在代码中将会看到如何提取预训练好的模型的参数。

预训练VGG16模型下载地址:https://pan.baidu.com/s/1o9qEW3K
源代码下载地址:https://github.com/liangyihuai/my_tensorflow/tree/master/com/huai/converlution/project/style_tranfer

总结:本文的思路使用了tensorflow框架实现。生成一张风格图片需要较长的时间,大概半个小时。现在已经有更快的方法。可以阅读这篇论文:
快速风格转移算法https://arxiv.org/pdf/1603.08155.pdf

本文中的思路由这篇论文得来:Leon A. Gatys, Alexander S. Ecker, Matthias Bethge, (2015). A Neural Algorithm of Artistic Style (https://arxiv.org/abs/1508.06576)