如何使用Python3和PyTorch执行神经风格转移

机器学习或ML是AI的一个子领域,专注于从数据中学习模型的算法。在本教程中,您将使用Jupyter Notebook和Linux命令行应用神经样式传输,以获取如下图像:

介绍

机器学习或ML是AI的一个子领域,专注于从数据中学习模型的算法。 DigitalOcean提供机器学习一键式图像 这个决定背后的主要动机之一不仅是为了尽可能减少数据科学家和机器学习工程师的DevOps时间,而且还可以提高个人从想法到结果的速度。

让我们来看看计算机视觉领域的机器学习的实际应用,称为神经风格转移 2015年,研究人员利用深度学习技术创建了将一幅图像的内容与另一幅图像的艺术风格相融合的算法。 这种新算法产生了独特的图像,同时也提供了一个独特的视角,了解我们的视觉系统如何推断新的艺术概念。

顾名思义,神经风格转移依靠神经网络来执行这个任务。 此实施的具体细节超出了本教程的范围,但您可以在本博客文章中了解更多关于艺术风格转移或从原始研究手稿的更多信息

在本教程中,您将使用Jupyter Notebook和Linux命令行应用神经样式传输,以获取如下图像:

火箭sammy的形象

并通过应用文森特梵高的“星空之夜”的艺术风格来形成这个形象:

Starry的夜晚风格的形象转移到了火箭sammy

先决条件

要完成本教程,您将需要:

  • 一个新的Droplet使用机器学习一键 ,它附带了一个预先建立的Jupyter笔记本和本教程所需的所有依赖。

要么

使用机器学习模型可能是内存密集型的,所以您的机器应至少有8GB的内存来执行本教程中的一些计算。

第1步 - 安装依赖关系并克隆PyTorch样式传输GitHub存储库

在本教程中,我们将使用由Hang Zhang提供的“ PyTorch-Style-Transfer”提供的神经样式传输的开源实现。 这个特定的实现使用PyTorch库。 PyTorch预先安装了DigitalOcean Machine Learning One-Click Image。

注意 :如果您不使用此图像,则应安装PyTorch和torchvision软件包:

pip3 install http://download.pytorch.org/whl/cu75/torch-0.1.12.post1-cp35-cp35m-linux_x86_64.whl
pip3 install torchvision 

请注意,对于本教程,我们需要torch-0.1.12_2

为了避免使用文件style_transfer您的主目录,请创建一个名为style_transfer的新目录,并将其用作工作目录:

mkdir style_transfer
cd style_transfer

接下来,使用git clone命令将PyTorch-Style-Transfer存储PyTorch-Style-Transfer到工作目录。 您可以在此Git教程系列中了解有关Git的更多信息。

git clone https://github.com/zhanghang1989/PyTorch-Style-Transfer.git

该存储库的作者将PyTorch-Style-Transfer存储库的experiments文件夹中使用的代码放在一起,因此一旦克隆了所有文件,就切换到该目录:

cd PyTorch-Style-Transfer/experiments

看一下experiments目录的内容:

ls

您将看到以下目录:

camera_demo.py  dataset  images  main.py  models  myutils  net  option.py  __pycache__

在本教程中,您将使用包含库存图像的images/目录和main.py脚本,该脚本用于将神经样式传输应用于图像。

在转到下一节之前,您还需要下载运行神经风格转移所需的预训练深层学习模型。 这些模型可能很大,因此不适合存储在GitHub上,因此作者提供了一个小脚本下载文件。 你会在models/download_model.sh找到脚本。

首先,使脚本可执行:

chmod +x ./models/download_model.sh

然后执行脚本下载模型:

./models/download_model.sh

现在所有的东西都已经下载了,我们来使用这些工具来转换一些图像。

第2步 - 运行您的第一个样式转移实验

为了说明神经样式传递的工作原理,我们先来PyTorch-Style-Transfer存储库的作者提供的例子。 由于我们需要显示和查看图像,所以使用Jupyter笔记本会更加方便。

如果您正在使用DigitalOcean Machine Learning One-Click应用程序,Jupyter Notebook已经在运行。 在浏览器中打开http:// your_server_ip :8888/?token= YOUR_SECRET_TOKEN来访问它。

如果您没有使用一键式应用程序,请从终端启动Jupyter:

jupyter notebook

然后按照提供的说明访问Jupyter。

显示Jupyter后,通过从右上角的下拉菜单中选择New> Python 3来创建一个新笔记本:

Jupyter笔记本

这将打开一个新的笔记本,您可以在其中输入代码。

在笔记本的顶部,添加以下代码来加载所需的库。

笔记本
import torch
import os
import subprocess
from IPython.display import Image
from IPython.display import display

除了torch ,我们还导入标准库ossubprocess进程,我们将直接从Jupyter笔记本运行Python脚本。 我们还包括IPython.display库,它可以让我们在Jupyter笔记本中显示图像。

注意 :键入ALT+ENTER (或MacOS上的SHIFT+ENTER )运行代码并移动到笔记本内的新代码块。 在本教程中的每个代码块后执行此操作以查看结果。

PyTorch-Style-Transfer存储库的README文件中提供的示例使用位于images/目录和main.py脚本中的库存图片。 为了运行main.py脚本,您需要至少提供五个参数:

  • 内容图片的路径(位于/images/content )。
  • 风格图像的路径(位于/images/21styles )。
  • 用于执行样式转移(位于/models )的预先训练的GAN(生成对对网络)模型的路径。
  • 输出图像的路径和名称。
  • 深度学习模式在GPU上运行得更快。 如果有一个可用,则指定--cuda=1参数,否则使用--cuda=0

要运行神经样式传输代码,我们将指定所需的参数,并使用subprocess库在shell中运行该命令。

首先,我们来定义我们工作目录的路径。 我们将存储在一个名为workingdir的变量中:

笔记本
# define the path to the working directory
experiment_dir = 'style_transfer/PyTorch-Style-Transfer/experiments'
workingdir = '{}/{}'.format(os.environ['HOME'], experiment_dir)

当我们指向图像和其他文件时,我们将在整个代码中使用此变量。

现在我们来定义main.py脚本的路径,以及我们将用作此测试运行输入的参数列表。 我们将指定内容图像为venice-boat.jpg ,样式图像为starry_night.jpg ,我们将将神经样式传输的输出保存到名为starry_night.jpg的文件中:

笔记本
# specify the path to the main.py script
path2script = '{}/main.py'.format(workingdir)

# specify the list of arguments to be used as input to main.py
args = ['eval',
        '--content-image',
        '{}/images/content/venice-boat.jpg'.format(workingdir),
        '--style-image',
        '{}/images/21styles/starry_night.jpg'.format(workingdir),
        '--model',
        '{}/models/21styles.model'.format(workingdir),
        '--output-image',
        '{}/test.jpg'.format(workingdir),
        '--cuda=0']

在运行测试示例之前,您可以通过在笔记本中执行此代码,快速查看您为此示例选择的内容和样式图像:

笔记本
content_image = Image('{}/images/content/venice-boat.jpg'.format(workingdir))
style_image = Image('{}/images/21styles/starry_night.jpg'.format(workingdir))
display(content_image)
display(style_image)

您将在输出中看到这些图像:

您的第一个神经样式转移示例的内容图像

您的第一例神经样式转移的风格图像

最后,将调用连接到main.py及其参数列表,并使用main.py函数在shell中运行它:

笔记本
# build subprocess command
cmd = ['python3', path2script] + args

# run the command
x = subprocess.check_output(cmd, universal_newlines=True)

根据机器上可用的内存量,这可能需要一两分钟才能运行。 一旦完成,您应该在工作目录中看到一个test.jpg文件。 从Jupyter笔记本,您可以使用Ipython魔术命令在Jupyter笔记本中显示您的工作目录的内容:

笔记本
!ls $workingdir

或者,您可以在终端中使用ls命令。 无论哪种方式,您将看到以下输出:

__pycache__ dataset  main.py  myutils  option.py
camera_demo.py  images   models   net      test.jpg

您将看到一个名为test.jpg的新文件,其中包含使用输入内容和样式图像进行神经样式传输的结果。

使用Image功能显示test.jpg的内容:

笔记本
Image('{}/test.jpg'.format(workingdir))

星夜的风格转移到我们的维多利亚小船形象的内容

Vincent van Vogh的“星空之夜”帆布的艺术风格已经映射到我们的维尼日亚船图像的内容。 您已经使用教科书的例子成功应用神经样式转移,所以让我们尝试用不同的图像重复这个练习。

第3步 - 转换自己的图像

到目前为止,您已经使用了我们使用的库的作者提供的图像。 让我们用自己的图片来代替。 为此,您可以找到您感兴趣的图像,并使用以下命令中的图像的URL,或使用提供的URL使用Sammy the Shark。

我们再次使用一些IPython魔法将镜像下载到我们的工作目录,并将其放入一个名为sammy.png的文件中。

笔记本
!wget -O - 'https://www.howtoing.com/wp-content/uploads/blog/static/sammy-the-shark-gets-a-birthday-makeover-from-simon-oxley/sammy-jetpack.png' > $workingdir/sammy.png

当您在笔记本中运行此命令时,您会看到以下输出:

--2017-08-15 20:03:27--  https://www.howtoing.com/wp-content/uploads/blog/static/sammy-the-shark-gets-a-birthday-makeover-from-simon-oxley/sammy-jetpack.png
Resolving assets.digitalocean.com (assets.digitalocean.com)... 151.101.20.233
Connecting to assets.digitalocean.com (assets.digitalocean.com)|151.101.20.233|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 10483 (10K) [image/png]
Saving to: 'STDOUT'

-                   100%[===================>]  10.24K  --.-KB/s    in 0.001s  

2017-08-15 20:03:27 (12.9 MB/s) - written to stdout [10483/10483]

使用Image命令在笔记本中显示新图像:

笔记本
Image('{}/sammy.png'.format(workingdir))

火箭sammy的形象

按照与测试运行相同的工作流程,让我们运用我们的艺术风格转移模型,使用Rocket Sammy作为内容图像,以及与我们的风格形象相同的“星空之夜”图片。

我们将使用与之前使用的相同的代码,但这次我们将把内容映像指定为sammy.png ,样式图像为starry_night.jpg ,并将输出写入名为starry_sammy.jpg的文件。 然后我们执行命令:

笔记本
# specify the path to the main.py script
path2script = '{}/main.py'.format(workingdir)

# specify the list of arguments to be used as input to main.py
args = ['eval',
        '--content-image',
        '{}/sammy.png'.format(workingdir),
        '--style-image',
        '{}/images/21styles/starry_night.jpg'.format(workingdir),
        '--model',
        '{}/models/21styles.model'.format(workingdir),
        '--output-image',
        '{}/starry_sammy.jpg'.format(workingdir),
        '--cuda=0']

# build subprocess command
cmd = ['python3', path2script] + args

# run the bash command
x = subprocess.check_output(cmd, universal_newlines=True)

然后使用Image功能查看将Vincent van Vogh的“星空之夜”的艺术风格转移到您的火箭Sammy图像的内容的结果。

笔记本
Image('{}/starry_sammy.jpg'.format(workingdir))

你会看到新的风格化的Rocket Sammy:

Starry的夜晚风格的形象转移到了火箭sammy

让我们再试一次,将不同的风格图像映射到我们的Rocket Sammy图片。 这次我们会使用毕加索的The Muse。 再次,我们使用sammy.png作为我们的内容图像,但我们将更改样式图像为la_muse.jpg 我们将输出保存到musing_sammy.jpg

笔记本
# specify the path to the main.py script
path2script = '{}/main.py'.format(workingdir)

# specify the list of arguments to be used as input to main.py
args = ['eval',
        '--content-image',
        '{}/sammy.png'.format(workingdir),
        '--style-image',
        '{}/images/21styles/la_muse.jpg'.format(workingdir),
        '--model',
        '{}/models/21styles.model'.format(workingdir),
        '--output-image',
        '{}/musing_sammy.jpg'.format(workingdir),
        '--cuda=0']

# build subprocess command
cmd = ['python3', path2script] + args

# run the bash command
x = subprocess.check_output(cmd, universal_newlines=True)

代码完成运行后,使用您指定的输出文件名和Image函数显示工作的输出:

笔记本
Image('{}/musing_sammy.jpg'.format(workingdir))

缪斯风格的形象转移到火箭sammy

到现在,你应该有一个好主意,如何使用这些转换。 如果还没有,请尝试使用自己的图片。

结论

在本教程中,您使用Python和开源PyTorch实现神经样式传输模型,以将风格传输应用于图像。 机器学习和AI的领域是巨大的,这只是其应用之一。 以下是您可以探索的其他一些事情: