:【迁移】用神经风格迁移生产美图,你也是梵高( 二 )


本文插图
VGG19网络各层的响应内容可视化 。 图片越往右 , 层在网络中的位置越深 。
教程使用第4层卷积作为内容层 。 如上图所示 , 对于内容来说该层数可能太低了 , 因为处于这个深度的网络仍在关心像素匹配是否精确 。 Gatys等人使用conv4_2替代conv2_2 , 因为conv4_2更关心整体特征分布而非单个像素 。
对于风格来说 , 低层捕捉较小的重复特征 , 较高层捕捉更抽象的整体特征 。 因此 , 为了对style_img的整体风格进行迁移(从低层细节到整体图案) , 应该包含网络中所有深度的层 。
该教程使用前5个卷积层 , 但它们在网络中的位置太低 , 不大能捕捉到整体特征 。 Gaty等人使用 conv1_1、 conv2_1、conv3_1、conv4_1和conv5_1 , 在整个网络体系中形成了良好的层分布 。 可以使用与内容层相同的方法 , 对每个层选择要优化的样式进行可视化 。
为了实现这一点 , 设置content_weight=0 , 指定想要使用的style_layers , 然后基于随机的input_img运行训练过程 。
:【迁移】用神经风格迁移生产美图,你也是梵高
本文插图
PyTorch教程选择的层生成的风格(左);Gatys等人的文章选择的层生成的风格(右)
意料之中 , 教程选择的层优化的风格捕捉低层次的重复性特征 , 但不能捕捉高层次的整体性特征 。
提高迁移质量
截至目前 , 我们实现的修复质量应该已经相当接近Gatys等人的文章中所看到的质量 。 现在将进一步深入 , 采取以下措施以生成更好的图像 。
笔者对文章所做的第一个修改就是将优化程序从L-BFGS转换为Adam 。 文章表述L-BFGS能生成更高质量的迁移 。
但笔者在实验中并未发现这两者的使用效果有什么差异 , 此外Adam的稳定性似乎更好 , 尤其在训练大量步骤时或者有着庞大的style_weight时 。 在这些情况下,L-BFGS可能会报错 , 这大概是因为梯度爆炸(笔者并未深入研究) 。
:【迁移】用神经风格迁移生产美图,你也是梵高
本文插图
另一个轻微调整是将mse_loss (即L2loss)转换为l1_loss 。 笔者想不出L2_loss对于风格迁移有什么好处(除了在0处具有可微性) , 因为平方值将会对异常值做出严重干扰 。
正如前一节所述 , 我们并不关心像素匹配是否精确 , 并且可以容忍生成图像中出现一些异常值 。 实际上 , 当风格特征和内容特征混合在一起时 , 异常值可能会使得视觉效果更佳 。 最后 , 《特征可视化》(Feature Visualization , 接触相关话题必须阅读的一篇文章)的作者也许是出自类似原因 , 在其任务中使用l1_loss 。
实际上 , 许多用于生成高质量特征可视化(FV)的技巧都优雅地过渡到了神经风格迁移上 。
FV和NST在概念上十分相似 , 只在生成input_img的方式上有所不同 。 在NST中 , input_img经过优化后 , 可与content_img 和style_img以相同的方式激活网络中不同层 。 而FV则不使用content_img 或style_img , 而是生成input_img , 最大程度地刺激不同层的神经元 。
:【迁移】用神经风格迁移生产美图,你也是梵高
本文插图
积极的数据增强使生成图片的右上角产生旋转伪影
笔者从FV中借用了一个小技巧 , 即在input_img上使用数据增强 。 这与常规分类任务的工作原理完全相同:每一步都要对input_img进行增强(如旋转、裁剪、缩放等) , 然后运行模型并计算损失 。
通过每一步的增强 , 我们迫使input_img生成抗微小扰动的鲁棒性特征 。 这些特征应该包含较少的高频伪影 , 并更具有视觉吸引力 。 然而 , 我发现《特征可视化》文章所使用的增强过大 , 必须适当缩小 。 即使如此 , 生成图片(上图)边缘仍然有一些旋转伪影 。 消除这些伪影的最简单方法就是将边缘的一些像素剪切掉 。


推荐阅读