Comment effectuer un transfert de style neuronal avec Python 3 et PyTorch

introduction

L'apprentissage automatique, ou ML, est un sous-domaine de l'IA axé sur des algorithmes permettant l'apprentissage de modèles à partir de données.

Examinons une application pratique de l'apprentissage automatique dans le domaine de la vision par ordinateur appeléeneural style transfer. En 2015, les chercheurs ont utilisé des techniques d'apprentissage en profondeur pour créer un algorithme associant le contenu d'une image au style artistique d'une autre. Ce nouvel algorithme génère des images uniques, mais offre également une perspective unique sur la manière dont notre système visuel peut inférer de nouveaux concepts artistiques.

Comme son nom l'indique, le transfert de style neuronal s'appuie sur des réseaux de neurones pour effectuer cette tâche. Les détails exacts de cette implémentation sortent du cadre de ce didacticiel, mais vous pouvez en apprendre plus sur lesin this blog post on artistic style transfer ou sur lesoriginal research manuscript.

Dans ce tutoriel, vous allez appliquer le transfert de style neuronal à l'aide de Jupyter Notebook et de la ligne de commande Linux pour prendre une image comme celle-ci:

An image of Rocket Sammy

et le transformer en appliquant le style artistique de «Starry Night» de Vincent van Gogh pour créer cette image:

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

Conditions préalables

Pour compléter ce tutoriel, vous aurez besoin de:

Travailler avec des modèles d'apprentissage machine peut nécessiter beaucoup de mémoire. Votre ordinateur doit donc disposer d'au moins 8 Go de mémoire pour effectuer certains calculs de ce didacticiel.

[[step-1 -—- installation-dependencies-and-cloning-the-pytorch-style-transfer-github-repository]] == Étape 1 - Installation des dépendances et clonage du référentiel PyTorch-Style-Transfer GitHub

Dans ce tutoriel, nous utiliserons une implémentation open-source du transfert de style neuronal fourni parHang Zhang appeléePyTorch-Style-Transfer. Cette implémentation particulière utilise la bibliothèquePyTorch.

Activez votre environnement de programmation et installez PyTorch et le packagetorchvision avec la commande suivante:

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

Notez que pour ce tutoriel, nous avons besoin detorch-0.1.12_2.

Pour éviter d'encombrer votre répertoire personnel avec des fichiers, créez un nouveau répertoire appeléstyle_transfer et utilisez-le comme répertoire de travail:

mkdir style_transfer
cd style_transfer

Ensuite, clonez le référentielPyTorch-Style-Transfer dans votre répertoire de travail à l'aide de la commandegit clone. Vous pouvez en savoir plus sur Git dansthis Git tutorial series.

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

L'auteur de ce référentiel a placé le code que nous utiliserons dans le dossierexperiments du référentielPyTorch-Style-Transfer, donc basculez vers ce répertoire une fois que tous les fichiers ont été clonés:

cd PyTorch-Style-Transfer/experiments

Jetez un œil au contenu du répertoireexperiments:

ls

Vous verrez les répertoires suivants:

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

Dans ce didacticiel, vous utiliserez le répertoireimages/, qui contient des images d'archives, et le scriptmain.py, qui est utilisé pour appliquer le transfert de style neuronal à vos images.

Avant de passer à la section suivante, vous devez également télécharger le modèle d’apprentissage approfondi préalablement formé requis pour exécuter le transfert de style neuronal. Ces modèles peuvent être volumineux et ne peuvent donc pas être stockés sur GitHub. L'auteur fournit donc un petit script pour télécharger le fichier. Vous trouverez le script àmodels/download_model.sh.

Tout d’abord, rendez le script exécutable:

chmod +x ./models/download_model.sh

Ensuite, exécutez le script pour télécharger le modèle:

./models/download_model.sh

Maintenant que tout est téléchargé, utilisons ces outils pour transformer certaines images.

[[step-2 -—- running-your-first-style-transfer-experiment]] == Étape 2 - Exécution de votre première expérience de transfert de style

Pour illustrer le fonctionnement du transfert de style neuronal, commençons par utiliser l'exemple fourni par l'auteur du référentielPyTorch-Style-Transfer. Comme nous aurons besoin d'afficher et de visualiser les images, il sera plus pratique d'utiliser un ordinateur portable Jupyter.

Lancez Jupyter depuis votre terminal:

jupyter notebook

Accédez ensuite à Jupyter en suivant les instructions présentées.

Une fois Jupyter affiché, créez un nouveau notebook en sélectionnantNew > Python 3 dans le menu déroulant en haut à droite:

Jupyter Notebook

Cela ouvre un nouveau bloc-notes où vous pouvez entrer votre code.

En haut du bloc-notes, ajoutez le code suivant pour charger les bibliothèques requises.

Carnet

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

En plus detorch, nous importons également les bibliothèques standardos etsubprocess, que nous utiliserons pour exécuter des scripts Python directement à partir du notebook Jupyter. Nous incluons également la bibliothèqueIPython.display, qui nous permet d'afficher des images dans le notebook Jupyter.

[.note] #Note: saisissezALT+ENTER (ouSHIFT+ENTER sous macOS) pour exécuter le code et passer à un nouveau bloc de code dans votre bloc-notes. Faites-le après chaque bloc de code de ce didacticiel pour voir vos résultats.
#

L'exemple fourni dans le fichierREADME du référentielPyTorch-Style-Transfer utilise des images de stock situées dans le répertoireimages/ et le scriptmain.py. Vous devrez fournir au moins cinq arguments pour exécuter le scriptmain.py:

  • Le chemin d'accès à l'image de contenu (situé dans/images/content).

  • Chemin d'accès à l'image de style (situé dans/images/21styles).

  • Le chemin vers le modèle GAN (Generative Adversarial Network) pré-entraîné utilisé pour effectuer le transfert de style (situé dans/models).

  • Le chemin et le nom de l'image de sortie.

  • Les modèles d'apprentissage en profondeur s'exécutent beaucoup plus rapidement sur les GPU. Si vous en avez un disponible, spécifiez le paramètre--cuda=1, sinon utilisez--cuda=0.

Pour exécuter le code de transfert de style neuronal, nous allons spécifier les arguments requis et utiliser la bibliothèquesubprocess pour exécuter la commande dans le shell.

Commençons par définir le chemin de notre répertoire de travail. Nous allons stocker dans une variable appeléeworkingdir:

Carnet

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

Nous utiliserons cette variable dans tout notre code lorsque nous pointez sur des images et d’autres fichiers.

Définissons maintenant le chemin du scriptmain.py, ainsi que la liste des arguments que nous utiliserons comme entrée pour ce test. Nous allons spécifier que l'image de contenu estvenice-boat.jpg, l'image de style est`starry_night.jpg, and we’ll save the output of our neural style transfer to a file called `test.jpg:

Carnet

# 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']

Avant d'exécuter l'exemple de test, vous pouvez examiner rapidement les images de contenu et de style que vous avez choisies pour cet exemple en exécutant ce code dans votre bloc-notes:

Carnet

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)

Vous verrez ces images affichées dans la sortie:

The content image for your first example of neural style transfer

The style image for your first example of neural style transfer

Enfin, concaténez l'appel àmain.py et sa liste d'arguments et exécutez-le dans le shell en utilisant la fonctionsubprocess.check_output:

Carnet

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

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

Selon la quantité de mémoire disponible sur votre ordinateur, l’exécution de cette opération peut prendre une minute ou deux. Une fois terminé, vous devriez voir un fichiertest.jpg dans votre répertoire de travail. À partir d'un notebook Jupyter, vous pouvez utiliserIpython magic commands pour afficher le contenu de votre répertoire de travail dans le notebook Jupyter:

Carnet

!ls $workingdir

Vous pouvez également utiliser la commandels dans votre terminal. De toute façon, vous verrez la sortie suivante:

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

Vous verrez un nouveau fichier appelétest.jpg, qui contient les résultats du transfert de style neuronal en utilisant votre contenu d'entrée et vos images de style.

Utilisez la fonctionImage pour afficher le contenu detest.jpg:

Carnet

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

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

Le style artistique de la toile Starry Night de Vincent van Gogh a été mis en correspondance avec le contenu des images de nos bateaux vénitiens. Vous avez appliqué avec succès le transfert de style neuronal avec un exemple de manuel. Essayons donc de répéter cet exercice avec des images différentes.

[[step-3 -—- transformer-your-own-images]] == Étape 3 - Transformer vos propres images

Jusqu'à présent, vous avez utilisé les images fournies par l'auteur de la bibliothèque que nous utilisons. Utilisons plutôt nos propres images. Pour ce faire, vous pouvez rechercher une image qui vous intéresse et utiliser l'URL de l'image dans la commande suivante ou utiliser l'URL fournie pour utiliser Sammy the Shark.

Nous utiliserons à nouveau un peu de magie IPython pour télécharger l'image dans notre répertoire de travail et la placer dans un fichier appelésammy.png.

Carnet

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

Lorsque vous exécutez cette commande dans votre bloc-notes, la sortie suivante s’affiche:

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]

Utilisez la commandeImage pour afficher la nouvelle image dans le notebook:

Carnet

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

An image of Rocket Sammy

En suivant le même flux de travail que celui du test, exécutons notre modèle de transfert de style artistique utilisant Rocket Sammy comme image de contenu et la même image Starry Night que notre image de style.

Nous utiliserons le même code que nous avons utilisé précédemment, mais cette fois, nous spécifierons l'image de contenu comme étantsammy.png, l'image de style comme étantstarry_night.jpg, et nous écrivons la sortie dans un fichier appeléstarry_sammy.jpg. Ensuite, nous exécutons la commande:

Carnet

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

Utilisez ensuite la fonctionImage pour afficher les résultats du transfert du style artistique de la Nuit étoilée de Vincent van Vogh vers le contenu de votre image Rocket Sammy.

Carnet

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

Vous verrez le nouveau Rocket Sammy stylisé:

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

Réessayons en mappant une image de style différent de celle de Rocket Sammy. Nous utiliserons The Muse de Picasso cette fois-ci. Encore une fois, nous utilisonssammy.png comme image de contenu, mais nous changerons l'image de style enla_muse.jpg. Nous enregistrerons la sortie dansmusing_sammy.jpg:

Carnet

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

Une fois le code exécuté, affichez la sortie de votre travail en utilisant le nom de fichier de sortie que vous avez spécifié et la fonctionImage:

Carnet

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

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

À présent, vous devriez avoir une bonne idée de la façon d'utiliser ces transformations. Essayez d’utiliser certaines de vos propres images si vous ne l’avez pas déjà fait.

Conclusion

Dans ce didacticiel, vous avez utilisé Python et une implémentation open source PyTorch d’un modèle de transfert de style neuronal pour appliquer un transfert stylistique à des images. Le domaine de l'apprentissage automatique et de l'intelligence artificielle est vaste et il ne s'agit que de l'une de ses applications. Voici quelques choses supplémentaires que vous pouvez explorer:

Related