前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何通过神经风格转换获得漂亮的结果

如何通过神经风格转换获得漂亮的结果

作者头像
代码医生工作室
发布2020-04-14 16:30:03
1.5K0
发布2020-04-14 16:30:03
举报
文章被收录于专栏:相约机器人相约机器人

作者 | Eugen Hotaj

来源 | Medium

编辑 | 代码医生团队

最近开始对使用机器学习生成中型个人资料图片感兴趣。深入到了神经风格转换领域。尽管NST在概念上很容易理解,但要生成高质量图像却出奇地困难。为了获得良好的结果,必须正确实施许多复杂的细节和未提及的技巧。在本文中,将深入研究神经风格转换,并详细研究这些技巧。

在Medium和其他出版物上都有大量有关NST的扎实介绍,因此不会浪费任何时间来学习基础知识。如果不知道NST是什么(或者想跟着本文一起学习),一个很好的入门方法是查看官方PyTorch教程。不幸的是,与许多其他入门文章一样,最终实现充其量只能产生中等程度的结果(图1)。将在接下来的几节中更新教程代码以提高传输质量,但是首先要切线。

本文的所有随附代码都可以在GitHub上找到。

https://github.com/EugenHotaj/nn-hallucinations

图1:两种不同实现的神经风格转换质量比较。(左下)要匹配其内容的图像。(左上)要匹配其样式的图像。(中)使用PyTorch教程实现的样式转换结果。(右)使用本文详细介绍的实现的样式转移结果。生成的图像在视觉上具有较高的质量,并且更加忠实地匹配样式图像的样式。

旁白:为什么Gram矩阵会衡量样式?

大多数盖蒂人等。纸里面介绍神经式转换是简单明了的了解。但是一个尚未解决的问题是,为什么Gram矩阵是一种自然的方式来表示样式(即纹理)?

在较高的层次上,Gram矩阵可测量同一层中不同特征图之间的相关性。特征图只是卷积层的激活后输出。例如,如果一个卷积层有64个滤镜,它将输出64个特征图。然后,Gram矩阵可测量图层中每个特征图与每个其他特征图之间的相关性(相似性),而不必关心确切的像素位置。为了说明为什么这是对纹理的合理衡量,假设有两个过滤器,一个过滤器检测蓝色物体,另一个检测螺旋体。可以将这些滤镜应用于输入图像,以生成2个滤镜图并测量其相关性。如果滤镜图高度相关,则图像中存在的任何螺旋几乎可以肯定是蓝色的。

尽管这种解释仍然有些不安,但正如本文所解释的那样,在Gram矩阵对应于样式的情况下,似乎是纹理合成社区中一个广为接受的事实。此外不能否认使用Gram矩阵获得的结果令人印象深刻。

修复PyTorch实现

改善传输质量的第一步是修复PyTorch教程实施。本教程尽量忠实于Gatys等人。但一路上错过了一些东西。一方面,论文作者用代替MaxPool2d,AvgPool2d因为发现可以产生更高质量的结果。另一个细节是本教程将计算卷积的ContentLoss和StyleLoss,而不是ReLU激活。这更像是挑剔,因为在实验中,并未发现使用卷积与ReLU之间有很大的差异。

图2:VGG19网络及其层

本教程与论文之间最令人震惊的区别在于,“错误”层分别用于ContentLoss和StyleLoss。由于层的选择在很大程度上是主观的,并且在很大程度上取决于产生最令人愉悦的样式的方式,因此在引号中写错了。话虽如此,可以使用一些经验法则来指导决定。在测量内容相似度时,当content_img和生成的像素之间存在像素完美匹配时,下层往往会激活得最高input_img。进入网络的深度越深,各层对精确匹配的关注就越少,而当要素通常位于正确的位置时,它们就会激活得更多。为了可视化每个层最关注的内容,可以style_weight=0随机设置和运行训练过程input_img使用不同的图层作为content_layer。

图3:可视化VGG19网络的不同层响应什么内容。右侧更远的层在网络中更深。

本教程使用第4卷积(conv2_2图2中)作为内容层。正如在上面的图3中可以看到的那样,由于网络仍然关心在此深度精确匹配像素,因此该层可能太低而无法用于内容。Gatys等。请conv4_2改用,而不是单个像素,而是更多地关注整体特征的布置。

就样式而言,较低的层响应较小的重复特征,而较高的层捕获更抽象的全局特征。因此,为了将整个样式(style_img从低级细节转变为总体主题),我们应包括网络中各个深度的图层。本教程使用前5个卷积层,但是它们在网络中都相当低,并且不太可能捕获全局特征。Gatys等。使用conv1_1,conv2_1,conv3_1,conv4_1,和conv5_1,层的整个网络中的层次结构中的很好的分布。可以使用与内容相同的方法来可视化每个图层选择正在优化的样式。为此设置content_weight=0,指定style_layers要使用的内容,并随机运行训练过程input_img。

图4 :(左)由PyTorch教程中选择的图层产生的样式。(右)由Gatys等人选择的图层产生的样式。

正如预期的那样,由教程层优化的样式可以捕获低级的重复性功能,但是无法捕获高级的全局性功能。

提高传输质量

到目前为止,已经实施的修复程序应该使相当接近Gatys等人所见的质量。从这里开始,将更深入地研究如何采取进一步的步骤来生成更好的图像。

从本文中更改的第一件事就是将优化器从切换L-BFGS为Adam。在这篇论文中,作者声称可以带来L-BFGS更高的质量转移,但是Adam在实验中使用时,没有发现任何区别。此外,它Adam似乎更稳定,尤其是在训练大量步骤或使用大踏板进行训练时style_weight。在这些情况下,可能L-BFGS似乎NaN是由于梯度爆炸(尽管我对它的了解并不深)。

另一个较小的调整是将mse_loss(即L2损耗)切换为l1_loss。想不出有充分的理由使用L2损失进行样式转移(除了0处的可微性),因为平方项会严重影响离群值。正如上一节所提到的,并不十分在乎精确匹配像素,而是可以容忍所生成图像中的一些离群值。确实,将样式和内容特征融合在一起,离群值甚至可能导致视觉效果更好。最后,功能可视化的作者(必须阅读有关相关主题的文章)也l1_loss可能出于类似原因而用于任务。

实际上,用于生成高质量特征可视化的许多技巧可以优雅地转换为神经样式转换。实际上,FV和NST在概念上非常相似,只是它们的生成方式不同input_img。在NST中,input_img经过优化以与content_img和相同的方式激活网络中的不同层style_img。另一方面,FV不使用content_img和style_img而是生成一个input_img,最大程度地激发不同层的神经元。

图5:由激进的数据扩充引起的生成图像右上角的旋转伪像。

从FV借来的一个技巧是在上使用数据增强input_img。这与常规分类任务的工作原理完全相同:在每个步骤中,都会对模型进行一些扩充input_img(例如旋转,裁剪,调整大小等),然后再对其进行遍历并计算损失。通过input_img在每个步骤中增加,我们强制input_img生成对较小扰动具有鲁棒性的特征。这些健壮的功能应包含较少的高频伪像,并且通常看起来更具视觉吸引力。但是发现“功能可视化”文章中使用的增强功能非常激进,因此必须适当缩小比例。即使这样,仍然在生成的图像的边缘周围形成一些旋转伪像(图5)。消除这些伪像的最简单方法是将图像裁剪几像素。

最后,所做的最后修改是将切换content_layer为conv3_2而不是conv4_2Gatys等。用。我读过的大多数文章也都推荐使用conv4_2,尽管我发现细腻的细节会被淘汰,conv4_2并且样式压倒了所生成图像中的内容。另一方面,conv3_2仍然保持这些精细的细节,而不会像下部图层那样过度牺牲像素的完美性。确实,我们可以再次查看图3来确认是这种情况。

进一步提高质量

现在,已经讨论了我在神经风格转换代码中实现的所有技巧。至此已经在原始PyTorch教程的基础上大大提高了传输质量。此外,content_weight和style_weight对特定的图像选择更为强大。例如,在PyTorch教程中,发现如果style_weight没有适当的调整,一组图像上的好图像不会轻易转移到另一组图像上。

https://github.com/EugenHotaj/nn-hallucinations

话虽如此,通过尝试消除生成的图像中的高频噪声,可以获得更好的结果。我遇到的最有趣的方法是来自“ 差异图像参数化”一文 -另一个必须读的内容涉及相似的主题。在本文中,作者input_img首先通过在(去皮)傅里叶空间而不是(去皮)像素空间中进行参数化来生成。由于input_img是通过梯度下降生成的,因此对输入进行解相关可作为前置条件,通过允许梯度下降更快地找到最小值来简化优化(类似于在监督学习任务中删除相关特征)。w ^ HY导致更高质量的转移并不完全清楚,除了波状的解释(例如在与装饰相关的空间中找到极小值)之外,其解释更广泛,更可靠。

一种更简单的方法是通过直接或间接惩罚高频噪声来抑制它。噪声可直接通过将惩罚总变异损失的input_img的优化目标。相反,可以通过在每个梯度下降步骤之后进行模糊处理,或在将梯度应用于之前对它们进行模糊处理来隐式惩罚噪声。两种方法的一个问题是它们还不利地惩罚了真实的高频特征。通过缩小训练过程中的总变化损失或模糊量,可以稍微改善这一点。input_imginput_img

结论

如果到此为止,现在应该对使用Neural Style Transfer生成漂亮的图像有很多了解。虽然从概念上讲很简单,但要获得高质量的结果需要多加注意。最初目标是使用机器学习来生成中型个人资料图片。经过多次尝试和错误,认为我偶然发现了一些看起来很惊人的东西。整个过程中最令人兴奋的部分是神经网络的端到端可区分性。只需很少的努力,就可以“反转”最初训练用来区分猫和狗的模型,并使用它来生成无数种不同样式的图像。尝试使用随机森林进行操作。

所有代码都可以在GitHub上找到。

https://github.com/EugenHotaj/nn-hallucinations

脚注

强大的功能也被证明以产生非VGG架构高质量传输的结果。由于尚未理解的原因,非VGG架构无法直接使用于神经样式转换。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 相约机器人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档