目录
一、简要说明
二、具体实施步骤
2.1综述
2.2基本思路
2.3核心思路
2.4基本问题处理
三、代码的简要描述
四、成果展示
一、简要说明
本次学习的图像风格迁移算法是基于一个2015年由Gatys等人发表的文章A Neural Algorithm of Artistic Style_的一个代码复现
写这篇文章主要是做一下学习记录。
二、具体实施步骤
2.1综述
输入一张随机噪声构成的底图,通过计算Style Loss和Content Loss,迭代更新target,风格上与Style图像类似,内容上与原照片相似。正常的训练过程是通过loss反向传播更新网络参数,论文中则是用一个已经训练好的VGG16作为backbone,锁住参数,更新输入的底图。类比画家作画的话,随机噪声就是画家的画纸,网络提取更新的内容特征相当于画家打的线稿,风格特征则是画家写真的风景对象(晴天,雨天,雪天等等各种风格)。
具体说,论文用 Gram 矩阵来对图像中的风格进行建模和提取,再利用慢速图像重建方法,让重建后的图像以梯度下降的方式更新像素值,使其 Gram 矩阵接近风格图的 Gram 矩阵(即风格相似),然后,用VGG网络提取的高层feature map来表征图像的内容信息,通过使 VGG 网络对底图的提取的高层feature map接近目标图高层的feature map来达到内容相似,实际应用时候经常再加个总变分 TV 项来对结果进行平滑,最终重建出来的结果图就既拥有风格图的风格,又有内容图的内容。
Gram矩阵是论文的核心思想,是一种基于统计分布的参数化纹理建模方法,使用Gram矩阵可以很好的提取图像风格。
在进行图像内容特征提取的过程中,这里使用VGG网络高层特征表达目标图像的内容特征。得益于对神经网络黑盒特性的不断研究,学者们发现,神经网络的中间层提取到的图像特征是不一样的,越靠近输入层的中间层提取到的特殊是浅层特征(即,点,线,色块等低级特征);越靠近输出层的中间层提取到的特征是高级特征(例如,边,角,轮廓等)。因此,图像的内容信息可以使用神经网络提取到的高级特征来表达(实际上,Gram矩阵是对神经网络提取的浅层特征做变换得到的,用来表示风格)。
2.2基本思路
其实代码的核心思想并不复杂,就是利用CNN提取内容图片的内容和风格图片的风格,然后输入一张新的图像。对输入的图像提取出内容和风格与CNN提取的内容和风格进行Loss计算,Loss的度量可以使用MSE,然后逐步对Loss进行优化,使Loss值达到最理想,将被优化的参数进行输出,这样输出的图片就达到了风格迁移的目的。
2.3核心思路
1、使用现成的识别网络,提取图像不同层级的特征。
(该项目使用的现成的识别网络是VGG19模型。)
2、低层次响应描述图像的风格,高层次响应描述图像的内容。
3、使用梯度下降方法,可以调整输入响应,在特定层次获得特定的响应。
4、多次迭代之后,输入响应即为特定风格和内容的图像。
2.4基本问题处理
1、内容损失(conten loss):对输入的content图像与生成的target目标图像进行欧式距离计算任取一张图像,将其输入到分类网络中,其中第L卷积层的响应记为,尺寸为HL*WL*NL。对于目标target图像,同样送入该网络,可以得到该层的响应,若希望和内容相似,我们则需要最小化如下的二范数误差:
这一误差可以对本层响应的每一元素求导:
其中h=1,2……H,w=1,2……W,k=1,2,3……N
进一步,利用链式法则,可以求得误差对输入图像的每一元素的导数
。这一步就是神经网络经典的back-propagation方法。利用
来更新,可以获得一个新的输入图像,其在第L层的响应更接近目标图像的响应。也就是说,可以目标target图像的内容更加接近。
2、风格损失(style loss)使用Gram矩阵代表图像的风格
引入一个
的特征矩阵:
i=1,2……N,j=1,2,3……N
由第L 层的响应计算而来,但是消除了响应的位置信息,可以看做对于风格的描述。ij位置的元素描述第i通道响应和第j通道响应的相关性。对于目标图像相应层的风格,最小化如下误差可以使和的风格近似:
可以求得误差对本层响应的导数:
同样可以通过back-propagation求得
,进而更新使其风格接近
3、总损失:将style loss 与content loss 进行相加。
4、图像中的信息:
使用分类网络中卷积层的响应来表达图像的风格和内容
5、为什么Gram矩阵能够定义图像的风格?
因为CNN卷积过后提取了图像的特征图,每个数字就是原图像的特性大小,而Gram矩阵是矩阵的内积运算,运算过后特征图中越大的数字会变得更大,这就相当于对图像的特性进行了缩放,使得特征突出了,也就相当于提取到了图片的风格。
三、代码的简要描述
- 获取VGG19模型中的features部分
- 冻结所有VGG参数
- 判断是否有GPU,如果有GPU则使用GPU来处理代码,否则使用CPU来执行
- 导入content图片和style风格图片,并且要求图片的参数为400*400像素(图片过大会影响效率,所以要处理一下)
- 加载content图像和style风格图像
- 在形成目标图像之前,只获取一次内容和样式特征
- 计算样式表示的每一层的gram矩阵
- 设置迭代参数
- 在VGG的基础上迭代构建我们自己的CNN网络
迭代内容:
1、获取目标图像target的特征
2、计算内容损失(content图像与target图像的距离)
3、初始化风格损失(style图像与target图像之间的距离)
4、迭代计算风格损失
5、计算总的损失
6、更新target图像
7、保存中间图像并打印损失
(其中还需编写函数方法实现计算Gram矩阵、获取图像特征features、tensor格式到图像的转换)
四、成果展示