Как выполнить передачу нейронного стиля с помощью Python 3 и PyTorch

Вступление

Машинное обучение, или ML, является подполем ИИ, сфокусированным на алгоритмах, которые изучают модели на основе данных.

Давайте посмотрим на практическое применение машинного обучения в области компьютерного зрения под названиемneural style transfer. В 2015 году исследователи использовали методы глубокого обучения для создания алгоритма, который смешивал содержание одного изображения с художественным стилем другого. Этот новый алгоритм генерировал уникальные изображения, но также предлагал уникальный взгляд на то, как наша визуальная система может выводить новые художественные концепции.

Как следует из названия, передача нейронного стиля зависит от нейронных сетей для выполнения этой задачи. Точные детали этой реализации выходят за рамки этого руководства, но вы можете узнать больше оin this blog post on artistic style transfer илиoriginal research manuscript.

В этом уроке вы примените передачу нейронного стиля, используя Jupyter Notebook и командную строку Linux, чтобы получить изображение, подобное этому:

An image of Rocket Sammy

и преобразовать его, применяя художественный стиль «Звездной ночи» Винсента Ван Гога, чтобы создать этот образ:

An image of Starry night’s style transferred to Rocket Sammy

Предпосылки

Для завершения этого урока вам понадобится:

Работа с моделями машинного обучения может потребовать большого объема памяти, поэтому на вашем компьютере должно быть не менее 8 ГБ памяти для выполнения некоторых вычислений в этом руководстве.

[[step-1 -—- install-dependencies-and-cloning-the-pytorch-style-transfer-github-repository]] == Шаг 1. Установка зависимостей и клонирование репозитория PyTorch-Style-Transfer на GitHub

В этом руководстве мы будем использовать реализацию передачи нейронного стиля с открытым исходным кодом, предоставляемуюHang Zhang, которая называетсяPyTorch-Style-Transfer. Эта конкретная реализация использует библиотекуPyTorch.

Активируйте среду программирования и установите PyTorch и пакетtorchvision с помощью следующей команды:

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

Обратите внимание, что для этого урока нам понадобитсяtorch-0.1.12_2.

Чтобы не загромождать домашний каталог файлами, создайте новый каталог с именемstyle_transfer и используйте его в качестве рабочего каталога:

mkdir style_transfer
cd style_transfer

Затем клонируйте репозиторийPyTorch-Style-Transfer в свой рабочий каталог с помощью командыgit clone. Вы можете узнать больше о Git вthis Git tutorial series.

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

Автор этого репозитория поместил код, который мы будем использовать, в папкуexperiments репозиторияPyTorch-Style-Transfer, поэтому переключитесь в этот каталог, как только все файлы будут клонированы:

cd PyTorch-Style-Transfer/experiments

Взгляните на содержимое каталогаexperiments:

ls

Вы увидите следующие каталоги:

Outputcamera_demo.py  dataset  images  main.py  models  net.py  option.py  utils.py

В этом руководстве вы будете работать с каталогомimages/, который содержит стоковые изображения, и скриптомmain.py, который используется для переноса нейронного стиля к вашим изображениям.

Прежде чем перейти к следующему разделу, вам также необходимо загрузить предварительно обученную модель глубокого обучения, необходимую для запуска передачи нейронного стиля. Эти модели могут быть большими и поэтому не подходят для хранения на GitHub, поэтому автор предоставляет небольшой скрипт для загрузки файла. Вы найдете сценарий вmodels/download_model.sh.

Сначала сделайте скрипт исполняемым:

chmod +x ./models/download_model.sh

Затем выполните скрипт для загрузки модели:

./models/download_model.sh

Теперь, когда все загружено, давайте использовать эти инструменты для преобразования некоторых изображений.

[[step-2 -—- running-your-first-style-transfer-extract]] == Шаг 2. Запуск вашего первого эксперимента по переносу стиля

Чтобы проиллюстрировать, как работает передача нейронного стиля, давайте начнем с примера, предоставленного автором репозиторияPyTorch-Style-Transfer. Поскольку нам нужно будет отображать и просматривать изображения, будет удобнее использовать ноутбук Jupyter.

Запустите Jupyter с вашего терминала:

jupyter notebook

Затем получите доступ к Jupyter, следуя представленным инструкциям.

После отображения Jupyter создайте новый блокнот, выбравNew > Python 3 в правом верхнем раскрывающемся меню:

Jupyter Notebook

Это открывает новый блокнот, где вы можете ввести свой код.

В верхней части записной книжки добавьте следующий код для загрузки необходимых библиотек.

Блокнот

import torch
import os
import subprocess
from IPython.display import Image
from IPython.display import display

Наряду сtorch мы также импортируем стандартные библиотекиos иsubprocess, которые мы будем использовать для запуска скриптов Python непосредственно из записной книжки Jupyter. Мы также включаем библиотекуIPython.display, которая позволяет отображать изображения в записной книжке Jupyter.

[.note] #Note: введитеALT+ENTER (илиSHIFT+ENTER в macOS), чтобы запустить код и перейти в новый блок кода в записной книжке. Делайте это после каждого блока кода в этом руководстве, чтобы увидеть свои результаты.
#

В примере, приведенном в файлеREADME репозиторияPyTorch-Style-Transfer, используются стандартные изображения, расположенные в каталогеimages/, и сценарийmain.py. Для запуска сценарияmain.py вам необходимо указать как минимум пять аргументов:

  • Путь к изображению содержимого (находится в/images/content).

  • Путь к образу стиля (находится в/images/21styles).

  • Путь к предварительно обученной модели GAN (Generative Adversarial Network), используемой для выполнения передачи стиля (находится в/models).

  • Путь и имя выходного изображения.

  • Модели глубокого обучения работают намного быстрее на графических процессорах. Если он у вас есть, укажите параметр--cuda=1, в противном случае используйте--cuda=0.

Чтобы запустить код передачи нейронного стиля, мы укажем необходимые аргументы и воспользуемся библиотекойsubprocess для запуска команды в оболочке.

Во-первых, давайте определим путь к нашему рабочему каталогу. Мы сохраним в переменной под названием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, and we’ll save the output of our neural style transfer to a file called `test.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)

Вы увидите эти изображения в выводе:

The content image for your first example of neural style transfer

The style image for your first example of neural style transfer

Наконец, объедините вызовmain.py и его список аргументов и запустите его в оболочке с помощью функцииsubprocess.check_output:

Блокнот

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

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

В зависимости от объема памяти, доступного на вашем компьютере, запуск может занять одну или две минуты. По завершении вы должны увидеть файлtest.jpg в своем рабочем каталоге. В записной книжке Jupyter вы можете использоватьIpython magic commands для отображения содержимого вашего рабочего каталога в записной книжке Jupyter:

Блокнот

!ls $workingdir

В качестве альтернативы вы можете использовать командуls в своем терминале. В любом случае вы увидите следующий вывод:

Output__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))

Starry night’s style transferred to the content of our image of Venitian boats

Художественный стиль полотна «Звездной ночи» Винсента Ван Гога был сопоставлен с содержанием наших изображений венецианской лодки. Вы успешно применили передачу нейронного стиля на примере учебника, поэтому давайте попробуем повторить это упражнение с разными изображениями.

[[step-3 -—- transforming-your-own-images]] == Шаг 3. Преобразование ваших собственных изображений

До сих пор вы использовали изображения, предоставленные автором библиотеки, которую мы используем. Давайте использовать вместо этого наши собственные изображения. Для этого вы можете либо найти интересующее вас изображение и использовать URL-адрес для изображения в следующей команде, либо использовать URL-адрес, предоставленный для использования Sammy the Shark.

Мы снова воспользуемся магией IPython, чтобы загрузить изображение в наш рабочий каталог и поместить его в файл с именемsammy.png.

Блокнот

!wget -O - 'https://assets.digitalocean.com/blog/static/sammy-the-shark-gets-a-birthday-makeover-from-simon-oxley/sammy-jetpack.png' > $workingdir/sammy.png

Когда вы запустите эту команду в своей записной книжке, вы увидите следующий вывод:

Output--2017-08-15 20:03:27--  https://assets.digitalocean.com/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))

An image of Rocket Sammy

Следуя тому же рабочему процессу, что и тестовый прогон, давайте запустим нашу модель передачи художественного стиля, используя Rocket Sammy в качестве изображения контента и ту же картинку Starry Night, что и наше изображение стиля.

Мы будем использовать тот же код, который использовали ранее, но на этот раз мы укажем изображение содержимого как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, чтобы просмотреть результаты переноса художественного стиля из «Звездной ночи» Винсента ван Вога в содержание вашего изображения Ракеты Сэмми.

Блокнот

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

Вы увидите новую стилизованную Rocket Sammy:

An image of Starry night’s style transferred to Rocket Sammy

Давайте попробуем это снова, сопоставив изображение другого стиля с нашей картиной Ракеты Сэмми. На этот раз мы будем использовать 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))

An image of The Muse’s style transferred to Rocket Sammy

К настоящему времени у вас должна быть хорошая идея, как использовать эти преобразования. Попробуйте использовать некоторые из ваших собственных изображений, если вы еще этого не сделали.

Заключение

В этом руководстве вы использовали Python и реализацию PyTorch с открытым исходным кодом модели передачи нейронных стилей для применения стилистической передачи к изображениям. Область машинного обучения и искусственного интеллекта обширна, и это только одно из его применений. Вот некоторые дополнительные вещи, которые вы можете изучить:

Related