利用神经网络轻松把照片转换成梵高风格

1,456 阅读2分钟

在今天的文章中,我们将实现风格转换效果。

为了做到这一点,我们必须更深入地理解卷积神经网络及其各层是如何工作的。

在本文的最后,您将能够创建并运行一个风格转换程序。

什么是风格转换

在我们开始我们的风格转换应用程序之前,让我们介绍一下我们正在努力实现的目标。

给定一个输入图像和一个样式图像,我们可以用原始内容和一个新的样式来计算一个输出图像。就像下面这个例子:

file

波士顿的天际线与梵高的《星夜》交相辉映

如何实现风格转换

1、我们获取输入图像和风格图像,并将它们调整为相同的形状。

2、我们加载一个预先训练好的卷积神经网络(VGG16)。

3、知道我们可以区分负责样式的层(基本形状、颜色等)和负责内容的层(特定于图像的特性),我们就可以分离这些层来独立处理内容和样式。

4、然后我们把我们的任务设置为一个优化问题,我们要最小化:

内容loss(输入和输出图像之间的距离-我们努力保持内容)

风格loss(样式与输出图像之间的距离—我们努力应用新样式)

total variation loss(正则化-对输出图像进行去噪的空间平滑度)

5、最后,我们使用L-BFGS算法设置梯度并进行优化。

代码讲解

你可以在GitHub上找到风格转换项目的完整代码库:

github.com/gsurma/styl…

输入:

# San Francisco
san_francisco_image_path = "https://www.economist.com/sites/default/files/images/print-edition/20180602_USP001_0.jpg"
​
#Input visualization 
input_image = Image.open(BytesIO(requests.get(san_francisco_image_path).content))
input_image = input_image.resize((IMAGE_WIDTH, IMAGE_HEIGHT))
input_image.save(input_image_path)
input_image

下图就是输入图片:

file

风格:

# Warsaw by Tytus Brzozowski, http://t-b.pl
tytus_image_path = "http://meetingbenches.com/wp-content/flagallery/tytus-brzozowski-polish-architect-and-watercolorist-a-fairy-tale-in-warsaw/tytus_brzozowski_13.jpg"
​
# Style visualization 
style_image = Image.open(BytesIO(requests.get(tytus_image_path).content))
style_image = style_image.resize((IMAGE_WIDTH, IMAGE_HEIGHT))
style_image.save(style_image_path)
style_image

风格图片:

file

数据预处理:

# Data normalization and reshaping from RGB to BGR
input_image_array = np.asarray(input_image, dtype="float32")
input_image_array = np.expand_dims(input_image_array, axis=0)
input_image_array[:, :, :, 0] -= IMAGENET_MEAN_RGB_VALUES[2]
input_image_array[:, :, :, 1] -= IMAGENET_MEAN_RGB_VALUES[1]
input_image_array[:, :, :, 2] -= IMAGENET_MEAN_RGB_VALUES[0]
input_image_array = input_image_array[:, :, :, ::-1]
​
​
style_image_array = np.asarray(style_image, dtype="float32")
style_image_array = np.expand_dims(style_image_array, axis=0)
style_image_array[:, :, :, 0] -= IMAGENET_MEAN_RGB_VALUES[2]
style_image_array[:, :, :, 1] -= IMAGENET_MEAN_RGB_VALUES[1]
style_image_array[:, :, :, 2] -= IMAGENET_MEAN_RGB_VALUES[0]
style_image_array = style_image_array[:, :, :, ::-1]

网络模型:

# Model
input_image = backend.variable(input_image_array)
style_image = backend.variable(style_image_array)
combination_image = backend.placeholder((1, IMAGE_HEIGHT, IMAGE_SIZE, 3))
​
​
input_tensor = backend.concatenate([input_image,style_image,combination_image], axis=0)
model = VGG16(input_tensor=input_tensor, include_top=False)

结果

经过运行程序,我们获得了如下结果:

file

本文仅供学习之用,侵删。

在学习Python的道路上肯定会遇见困难,别慌,我这里有一套学习资料,包含40+本电子书,800+个教学视频,涉及Python基础、爬虫、框架、数据分析、机器学习等,不怕你学不会!

shimo.im/docs/JWCghr… 《Python学习资料》

file