概述

风格画迁移,也被称为图像风格迁移,是一种计算机视觉技术,可以将一张图像的艺术风格应用到另一张图像上,从而创造出新的图像。这项技术使用深度学习算法,通过对两张图像的内容和风格进行分析,生成一个新的图像,使其保留原始图像的内容,但以另一张图像的艺术风格呈现。

在神经风格迁移算法中,我们使用一个预训练的 CNN 模型(如 VGG-19 模型)来提取输入图像和参考图像的特征。这些特征通常被认为是对于图像的高级语义信息,例如图像中的物体和纹理。然后,我们使用这些特征来计算输入图像和参考图像的风格表示。

神经风格迁移的主要目标是最小化合成图像与参考图像之间的风格距离和输入图像与合成图像之间的内容距离。这些距离可以用损失函数来计算。一般来说,损失函数由三部分组成:

  • 内容损失
  • 风格损失
  • 总变差损失。

通过最小化这些损失,我们可以得到一个合成图像,它在保留输入图像内容的同时,具有参考图像的艺术风格。

算法详解

源码连接

算法流程

  1. 首先,我们需要准备一张样式图像和一张内容图像,以及一个待生成的合成图像,合成图像可以是内容图像的副本或者是一张随机噪声图像。
  2. 接下来,我们需要加载预训练的卷积神经网络模型,通常使用 VGG-19 模型。
  3. 在模型中选择一些合适的层,包括一些用于提取内容信息的层和一些用于提取样式信息的层
  4. 对于每张图像,分别对其进行前向传播,并在每个选定的层中获取特征图,即 CNN 模型的输出。特征图可以通过在每个层后面添加一个钩子函数来获取。
  5. 接下来,我们可以使用内容损失、风格损失和总变差损失来计算总损失函数,并计算出相应的损失值。
  6. 然后,我们使用反向传播算法来计算相对于合成图像的梯度,并使用优化算法(如 L-BFGS 或 Adam)来最小化损失函数,从而更新合成图像的像素值。(这里要特别说明的是,对于用于提取特征的网络,其中的参数是固化的,而输入的内容图片是像素值可变的,这里所谓的风格和内容的合成,其实就是反向传播的时候,根据损失更新图片参数)
  7. 最后,我们不断重复步骤 4 至 6,直到合成图像达到我们期望的效果为止。

损失函数

内容损失(Content Loss)

内容损失用于度量合成图像与输入图像之间的内容相似度。计算内容损失的方法通常是基于卷积神经网络(CNN)的特征提取技术。具体而言,我们使用预训练的 CNN 模型(如 VGG-19 模型)来计算输入图像和合成图像的特征表示,然后比较这些特征表示的差异。

一种计算内容损失的方法是使用特定层的特征图之间的均方误差(Mean Squared Error,MSE)。具体而言,我们选择 CNN 模型中的某些层,并使用这些层的特征图之间的 MSE 来计算内容损失。

假设图像风格迁移pytorch vgg_图像风格迁移pytorch vgg图像风格迁移pytorch vgg_图像风格迁移pytorch vgg_02 分别表示输入图像和合成图像在 CNN 模型的第 图像风格迁移pytorch vgg_最小化_03层的特征图,则内容损失 图像风格迁移pytorch vgg_深度学习_04

图像风格迁移pytorch vgg_深度学习_05

其中,图像风格迁移pytorch vgg_最小化_06图像风格迁移pytorch vgg_最小化_07分别表示特征图的索引。上述公式中的图像风格迁移pytorch vgg_最小化_08是为了方便梯度下降计算,没有本质意义。通过最小化内容损失,我们可以使得合成图像与输入图像之间的内容相似度更高,从而保留输入图像的主要物体和结构。

风格损失(Style Loss)

风格损失用于度量合成图像与样式图像之间的风格相似度。这里的风格损失本质上也是使用均方差损失,但是如果直接用计算feature map的损失,就跟内容损失一样了,所以我们需要一种方法来衡量风格差异,刚好Gram 矩阵可以帮我们实现这样的效果。

计算过程如下:

假设 图像风格迁移pytorch vgg_深度学习_09图像风格迁移pytorch vgg_最小化_10 分别表示样式图像和合成图像在 CNN 模型的第 图像风格迁移pytorch vgg_最小化_03 层的 Gram 矩阵,则风格损失 图像风格迁移pytorch vgg_深度学习_12

图像风格迁移pytorch vgg_最小化_13

其中,图像风格迁移pytorch vgg_深度学习_14 表示 CNN 模型的层数,图像风格迁移pytorch vgg_神经网络_15 是用于比较两个 Gram 矩阵之间差异的函数,图像风格迁移pytorch vgg_计算机视觉_16

Gram 矩阵是指特征图之间的内积矩阵,可以表示出特征图之间的相关性。具体而言,假设 图像风格迁移pytorch vgg_深度学习_17 表示 CNN 模型的第 图像风格迁移pytorch vgg_最小化_03 层的特征图,则 图像风格迁移pytorch vgg_深度学习_09 的第 图像风格迁移pytorch vgg_最小化_06 行和第 图像风格迁移pytorch vgg_最小化_07

图像风格迁移pytorch vgg_图像风格迁移pytorch vgg_22

Gram 矩阵实际上是特征图协方差矩阵的简化形式,它可以保留样式特征的统计信息,而丢弃像素位置和空间信息。

通过最小化风格损失,我们可以使得合成图像与样式图像之间的风格相似度更高,从而保留样式图像的纹理、颜色和图案。

总变差损失(Total Variation Loss)

总变差损失是图像处理中一种用于平滑图像的技术,可以用于神经风格迁移算法中的正则化项,有助于生成更加平滑的合成图像。

总变差损失的计算方法是对合成图像的像素值求梯度,并计算这些梯度的绝对值之和。具体而言,假设 图像风格迁移pytorch vgg_计算机视觉_23 表示合成图像,图像风格迁移pytorch vgg_深度学习_24图像风格迁移pytorch vgg_深度学习_25 分别表示图像的宽度和高度,则总变差损失 图像风格迁移pytorch vgg_最小化_26

图像风格迁移pytorch vgg_图像风格迁移pytorch vgg_27

其中,图像风格迁移pytorch vgg_计算机视觉_28图像风格迁移pytorch vgg_深度学习_29 分别表示合成图像在位置 图像风格迁移pytorch vgg_深度学习_30

遇到问题

样式图和内容图大小不一致处理方案

1. 重新调整图片大小

一种解决方法是将两张图片的大小都调整为相同的大小。这可以通过 PIL 库中的 resize()
函数来实现。具体而言,我们可以将较小的图片调整为与较大的图片相同的大小。这种方法可以保证两张图片大小相同,使它们可以进行特征提取和损失计算等操作。

2. 逐层计算

另一种解决方法是逐层计算。在神经风格迁移算法中,通常会选择多个卷积层来提取图像的特征。如果输入的两张图片大小不同,可以在这些层之间进行切换,并根据当前层的大小来适当调整另一张图片的大小。

具体而言,对于每个卷积层,可以将两张图片都传递到该层,并计算它们的特征图。然后,可以将较小的特征图调整为与较大的特征图相同的大小,并计算损失。这样,在不同层之间切换时,就可以在保持特征图大小一致的情况下进行计算,从而避免了输入图片大小不同带来的影响。