src: https://www. pyimagesearch.com/2018/ 08/27/neural-style-transfer-with-opencv/ 、
source code: https:// app.monstercampaigns.com /c/tortsem7qkvyuxc4cyfi
author: Adrian Rosebrock
学完这篇教程你将掌握通过 OpenCV、Python 还有深度学习来对 图片进行神经风格迁移(neural style transfer),到了本文最后你将能够制作自己的风格迁移图片。
最初的神经风格迁移算法是由 Gatys 等人于 2015 年的 A Neural Algorithm of Artistic Style [1] 论文中发布。
到了 2016 年 Johnson 等人发表了 Perceptual Losses for Real-Time Style Transfer and Super-Resolution(实时风格转移和超分辨率的感知损失)[2] 这将神经网络描述为使用感知损失的超分辨率问题。最终的结果是使一个神经风格迁移算法比 Gatys 等人的方法要快上三个数量级(其中也存在一些缺陷,我将在后文说到)。
我今天提到的方法能够在 CPU 上运行,并且还将在 GPU 上获得更好的表现。
我们将从对神经风格迁移的简短讨论开始,包括它是什么以及它的机制。之后我们将应用 OpenCV 和 Python 来实际应用神经风格迁移。
图像 1:内容图片(左);风格图片(中);风格化输出(右)
神经风格迁移的处理过程如下:
图 1 中展示了一个处理的例子,左边是我们的内容图片 —— 原作者本人在德国黑森林山顶喝啤酒眺望巴登。
中间的是我们用于获取风格的图片,Vincent van Gogh [3] 的 Starry Night。
右边的是将梵高的星夜风格应用到原作者本人照片后的输出。请注意我们是如何在应用过星夜的风格后,还能保留住起伏的山丘、森林、原作者甚至是啤酒的,就好像是梵高本人亲手绘出的一样。
问题是,我们该如何定义神经网络进行神经风格迁移?这有可能吗?
到此处你可能挠破头皮还在想刚才那句话:“我们该如何定义神经网络进行神经风格迁移?”
有趣的是在最早 2015 年 Gatys 等人的论文中提出了一种根本不需要新结构的神经风格迁移算法,因此我们才能使用一个已预先训练过的网络,并定义一个损失函数,来实现我们风格迁移的最终目标并且能够优化损失函数。
现在的问题已不再是我们应该使用什么神经网络了,而是我们应该使用什么损失函数?
答案是一个三分量(three-component)的损失函数,包括有:
其中每一 component 都被独立计算,并且之后被结合为一个单独的 meta-loss function。通过最小化 meta-loss function 我们也同时将一起优化了 content, style and total-variation loss。
虽然 Gatys 等人的方法可以产生很好的神经风格迁移结果,但问题是这样真是太慢了。
2016 年 Johnson 等人在 Gatys 等人的基础上提出了一种快上前者三个数量级的神经风格迁移算法,Johnson 等人将神经网络描述为了基于感知损失的超分辨率问题。
Johnson 等人的方法确实很快,但其最大的弊端是你不能随意选择你的风格图片。
取而代之的是您首先需要对网络进行训练,使其重现你想要图片的风格。一旦网络训练完成,你就可以将其应用到任何你想要的内容上了。你应该将 Johnson 等人的方法看作是对风格图像的投资,你最好要喜欢你所选的风格图像,因为你将一直训练你的网络来让其更好的在内容图片上重现出来。
Johnson 等人官方的神经风格模型训练文档可以在 GitHub 上找到。[4]
最后还有值得一看的是 Ulyanov 等人在2017 年发表的 Instance Normalization: The Missing Ingredient for Fast Stylization [5],将批标准化(batch normalization)改为实例正则化(instance normalization)将获得更快的实时性能也更具美感。
Johnson 与 Ulyanov 等人的模型都已经包含在了 “下载” 部分,一定要下载下来才能跟进本指南的剩余部分。
你还可以在原作者的书中 Deep Learning for Computer Vision with Python [6] 学到更多有关神经风格迁移的内容。
项目中的文件你都可以在 ”下载“ 部分找到,下载之后你就可以使用 tree 命令来探查文件结构:
4 directories,
有了这些之后你就不用继续寻找别的东西了,我为在 images 目录中你准备了一些内容图片,也在 models 目录中为你准备好了由 Johnson 等人训练过的模型了,还有三个你将会用到的 Python 文件。
现在就是用 OpenCV 和 Python 来实现神经风格迁移的部分了,打开你的 neural_style_transfer.py 文件并且加入以下代码:
# import the necessary packages
首先我们导入了必要的包并且进行了命令行参数的解析,要注意的有:
执行程序时我们还需加上两个命令行参数:
参数都是在程序运行时被传递与处理的,如果你还不熟悉命令行参数的解析原理,你一定要读读原作者的命令行参数解析一文。[7]
现在有意思的部分来了,我们将加载我们的图片与模型并且来计算出神经风格迁移的结果:
# load the neural style transfer model from disk
这个代码块中我们进行了如下的处理:
接下来,我们必须对输出图像进行后期处理:
# reshape the output tensor, add back in the mean subtraction, and
举例 NumPy 数组的值为 (1, 3, 452, 600):
上表代码的非注释第一行,我们将图像重塑简化为 (3, H, W) 后继续处理:
最后一步就是向我们的屏幕输出结果了:
# show information on how long inference took
在你都下载齐全后,打开你的终端执行如下命令:
这样我们就创造了深度学习的艺术品,终端的输出结果将显示出不同模型的不同处理时间。
[1] https://arxiv.org/abs/1508.06576
[2] https://cs.stanford.edu/people/jcjohns/eccv16/
[3] https://en.wikipedia.org/wiki/Vincent_van_Gogh
[4] https://github.com/jcjohnson/fast-neural-style
[5] https://arxiv.org/abs/1607.08022
[6] https://pyimagesearch.com/deep-learning-computer-vision-python-book/
[7] https://pyimagesearch.com/2018/03/12/python-argparse-command-line-arguments/
[8] https://pyimagesearch.com/2017/11/06/deep-learning-opencvs-blobfromimage-works/