作者|Richmond Alake

编译|Flin

我不会绘画,但是机器学习可以…

使用TensorFlow Hub进行神经风格迁移_数据类型

介绍

我不是艺术鉴赏家,但是我觉得上面的画看起来不错。

我也不是画家,但是到本文结尾,我将创建一个图像,其绘画风格与上图相似。

本文将介绍以下内容:


  • 神经风格迁移的描述
  • 神经风格迁移如何工作
  • 风格迁移的代码实现

什么是神经风格迁移

神经风格迁移(NST)是一种技术,涉及利用深度卷积神经网络和算法从一幅图像中提取内容信息并从另一幅参考图像中提取风格信息。在提取风格和内容之后,将生成一个组合图像,其中生成的图像的内容和风格来自不同的图像。

NST是一种图像风格化方法,它是一种使用输入参考图像来提供从输入图像导出的风格变化的输出图像的过程。

Leon A Gatys等人在论文 “艺术风格的神经算法”中(​​https://arxiv.org/pdf/1508.06576.pdf)​​ 介绍了NST技术。

使用TensorFlow Hub进行神经风格迁移_数据类型_02

如何运作

深度神经网络(DNN),更具体地说,卷积神经网络(CNN)的关键特征是能够学习图像中内容和风格的空间表示。此特性使NST技术得以实现。

CNN生成的输入图像的空间表示形式捕获图像的风格和内容统计信息。NST将提取的风格和内容组合到生成的输出图像中。

CNN层结构内的中间层中的激活函数提供了捕获输入图像的内容和风格统计信息的功能。

CNN图层在卷积操作之后输出特征图,该卷积操作涉及在输入图像上有一个滤波器滑动。图像的内容实际上在每个图层的生成的特征图中。

从中间层的特征图中提取内容将提供输入图像的高级结构和几何信息。

特征图获取输入图像的风格。为了导出图像的风格,需要评估中间层中特征图的均值和相关性。此过程提供的信息提供输入图像的纹理图案信息。

使用TensorFlow Hub进行神经风格迁移_机器学习_03

编程

好东西来了。

我们将使用下面图像的内容和风格创建图像。

左:内容画面,右:风格图片

使用TensorFlow Hub进行神经风格迁移_github_04

为了使用两个参考图像成功实现神经风格迁移的过程,我们将利用TensorFlow Hub(​​https://www.tensorflow.org/hub)​​ 上的模块

TensorFlow Hub提供了一套可重用的机器学习组件,例如数据集,权重,模型等。

对于本文的实现部分,我们将利用一套工具和库来加载图像和执行数据转换。


  • TensorFlow:一个用于实施,训练和部署机器学习模型的开源平台。
  • Matplotlib:用于在Python中创建可视化图的工具,例如图表,图形等
  • numpy:启用数组数据结构的几种数学计算和运算。
  • TensorFlow Hub:可重用的机器学习组件库,例如模型,数据集等

它们的地址如下:

我们将使用Jupyter Notebook(​​https://jupyter.org/)​​ 进行代码实现。本文末尾还包括指向notebook的Github存储库的链接。

首先,我们将导入所需的工具和库。

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import PIL.Image
import tensorflow_hub as hub

接下来,我们声明两个变量,这些变量保存了图像的目录路径,以表示输出结果的内容和风格。另外,我们也将显示图像。

content_path = 'images/human.jpg'
style_path = 'images/painting.jpg'
content_image = plt.imread(content_path)
style_image = plt.imread(style_path)
plt.subplot(1, 2, 1)
plt.title('Content Image')
plt.axis('off')
imshow(content_image)
plt.subplot(1, 2, 2)
plt.title('Style Image')
plt.axis('off')
imshow(style_image)

使用TensorFlow Hub进行神经风格迁移_tensorflow_05

要求将图像转换为张量表示。对于下一步,我们将利用TensorFlow的图像处理方法。

我们将创建一个接受图像路径为参数的函数,然后使用“tf.io.read_file”将图像转换为张量。我们进一步使用'tf.image.decode_image'将张量中值的数据类型更改为在0和1之间的浮点数。

def image_to_tensor(path_to_img):
img = tf.io.read_file(path_to_img)
img = tf.image.decode_image(img, channels=3, dtype=tf.float32)

# Resize the image to specific dimensions
img = tf.image.resize(img, [720, 512])
img = img[tf.newaxis, :]
return img

需要执行与上述相反的操作才能可视化来自TensorFlow Hub模块的结果。我们需要将返回的张量转换为可以可视化的图像。

我们只需将每个元素乘以255,即可将包含0到1之间的值的张量反归一化为实际像素值。下一步是使用Numpy创建一个数组,其中包含我们需要的数据类型。

我们从张量返回一个图像对象。

def tensor_to_image(tensor):
tensor = tensor*255
tensor = np.array(tensor, dtype=np.uint8)
tensor = tensor[0]
plt.figure(figsize=(20,10))
plt.axis('off')
return plt.imshow(tensor)

到目前为止,我们已经完成了以下工作:


  • 查看内容和参考风格图像
  • 创建一个函数将图像转换为张量,并将张量转换为图像

现在,我们将图像转换为张量并通过TensorFlow Hub包中的​​.load()​​方法将其传递给模块。

我们期望从参考图像中获得风格和内容的组合结果;因此,我们将创建一个变量来保存来自模块的运算结果。

为了可视化结果,我们仅使用我们先前创建的​​tensor_to_image​​函数。

content_image_tensor = image_to_tensor(content_path)
style_image_tensor = image_to_tensor(style_path)
hub_module = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2')
combined_result = hub_module(tf.constant(content_image_tensor), tf.constant(style_image_tensor))[0]
tensor_to_image(combined_result)

使用TensorFlow Hub进行神经风格迁移_数组_06

结论

我们设法结合了两个参考图像的风格和内容,并生成了网格图像。

展望未来,我建议你更详细地探讨“神经风格迁移”主题。

以下是本文中提供的代码的GitHub存储库链接。

​https://github.com/RichmondAlake/tensorflow_2_tutorials/blob/master/03_neural_style_transfer.ipynb​

欢迎关注磐创AI博客站:

​http://panchuang.net/​

sklearn机器学习中文官方文档:

​http://sklearn123.com/​

欢迎关注磐创博客资源汇总站:

​http://docs.panchuang.net/​