1
在今天的文章中,我们将实现风格转换效果。为了做到这一点,我们必须更深入地理解卷积神经网络及其各层是如何工作的。在本文的最后,您将能够创建并运行一个风格转换程序。
02
什么是风格转换
在我们开始我们的风格转换应用程序之前,让我们介绍一下我们正在努力实现的目标。
给定一个输入图像和一个样式图像,我们可以用原始内容和一个新的样式来计算一个输出图像。就像下面这个例子:
波士顿的天际线与梵高的《星夜》交相辉映
03
如何实现风格转换
- 我们获取输入图像和风格图像,并将它们调整为相同的形状。
- 我们加载一个预先训练好的卷积神经网络(VGG16)。
- 知道我们可以区分负责样式的层(基本形状、颜色等)和负责内容的层(特定于图像的特性),我们就可以分离这些层来独立处理内容和样式。
- 然后我们把我们的任务设置为一个优化问题,我们要最小化:
- 内容loss(输入和输出图像之间的距离-我们努力保持内容)
- 风格loss(样式与输出图像之间的距离—我们努力应用新样式)
- total variation loss(正则化-对输出图像进行去噪的空间平滑度)
5. 最后,我们使用L-BFGS算法设置梯度并进行优化。
04
代码讲解
你可以在GitHub上找到风格转换项目的完整代码库:
https://github.com/gsurma/style_transfer
输入:
代码语言:javascript复制# 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
下图就是输入图片:
风格:
代码语言:javascript复制# 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
风格图片:
数据预处理:
代码语言:javascript复制# 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]
网络模型:
代码语言:javascript复制# 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)
05
结果
经过运行程序,我们获得了如下结果: