Les hommes ne savent pas tous peindre, mais les Machines Learning oui.
Nul besoin d’être un amateur d’art pour affirmer que la peinture ci-à côté est fascinante. Nul besoin d’être peintre non plus pour créer, à la fin de cet article, une image du même standing que celle ci. Pour ce faire, cet article couvrira les points suivants :
- Description du transfert de style neuronal
- Fonctionnement du transfert de style neuronal
- Implémentation de code de transfert de style neuronal
Qu’est-ce que le transfert de style neuronal ?
Le transfert de style neuronal (TSN) est une technique qui implique l’utilisation d’un réseau neuronal convolutif profond et d’algorithmes pour extraire les informations de contenu d’une image et les informations de style d’une autre image de référence. Après l’extraction du style et du contenu, une image combinée est générée où le contenu et le style de l’image résultante proviennent des différentes images.
Le TSN est une méthode de stylisation d’image, qui est un processus qui implique l’utilisation d’une image de référence d’entrée pour fournir une image de sortie avec une variation de style dérivée de l’image d’entrée.
Comment le transfert de style neuronal fonctionne ?
Le réseau neuronal profond (RND), et plus spécifiquement le réseau neuronal convolutif (RNC), ont une caractéristique cruciale : celle de mémoriser la représentation spatiale du contenu et du style dans les images. Cette caractéristique permet de réaliser le TSN.
La représentation spatiale de l’image d’entrée générée par le RNC capture les informations statistiques de l’image sur le style et le contenu. Le TSN combine le style et le contenu extraits dans une image de sortie générée.
La fonction d’activation dans les couches intermédiaires au sein d’une structure de couche RNC permet de capturer le contenu et le style des informations statistiques de l’image d’entrée.
Les couches RNC produisent une map des caractéristiques après l’opération de convolution qui implique d’avoir une diapositive de filtre sur l’image d’entrée. Le contenu d’une image se trouve en fait dans la carte d’entités générée par chaque couche.
L’extraction du contenu des maps de caractéristiques des couches intermédiaires fournira des informations structurelles et géométriques de haut niveau sur l’image d’entrée.
Les maps d’entités obtiennent le style de l’image d’entrée. Pour dériver le style d’une image, il est nécessaire d’évaluer la moyenne et la corrélation des maps d’entités dans les couches intermédiaires. Les informations fournies par ce processus fournissent des informations sur le motif de texture de l’image d’entrée.
Le code : toutes les étapes
Afin de mettre en œuvre avec succès le processus de transfert de style neuronal à l’aide de deux images de référence, nous ferons appel ici à des modules TensorFlow Hub.
TensorFlow Hub fournit une suite de composants Machine Learning réutilisables tels que des ensembles de données, des modèles, etc.
Nous utiliserons un ensemble d’outils et de bibliothèques pour charger des images et effectuer une transformation de données :
- TensorFlow : une plate-forme open source pour l’implémentation, la formation et le déploiement de modèles Machine Learning.
- Matplotlib : outil utilisé pour créer des graphiques en Python
- Numpy : permet plusieurs calculs et opérations mathématiques sur les structures de données de tableaux.
- TensorFlow Hub : une bibliothèque de composants d’apprentissage automatique réutilisables tels que des modèles, des jeux de données, etc.
Nous utiliserons Jupyter Notebook pour l’implémentation du code. À la fin de cet article, vous trouverez également un lien vers le référentiel Github pour le bloc-notes.
Tout d’abord, nous importons les outils et bibliothèques nécessaires.
import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import PIL.Image
import tensorflow_hub as hub
Ensuite, nous déclarons deux variables qui contiennent le chemin du répertoire vers les images pour le contenu et le style de notre résultat de sortie. Nous afficherons également les images.
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)
Il est nécessaire que les images soient converties en une représentation tensorielle. Pour cette prochaine étape, nous utiliserons les méthodes de traitement d’image de TensorFlow.
Nous allons créer une fonction qui prend le chemin de l’image, puis convertir les images en un tenseur en utilisant la méthode «tf.io.read_file». Nous continuons à changer les types de données des valeurs dans le tenseur pour qu’ils flottent entre 0 et 1 en utilisant la méthode «tf.image.decode_image».
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
Une implémentation de l’opposé de ce qui précède est requise pour visualiser le résultat du module TensorFlow Hub. Nous devons convertir le tenseur retourné en une image que nous pouvons visualiser.
Nous dénormalisons simplement le tenseur qui contient des valeurs comprises entre 0 et 1 en valeurs réelles de pixels en multipliant chaque élément par 255. L’étape suivante consiste à créer un tableau à l’aide de Numpy qui inclut le type de données approprié dont nous avons besoin.
On renvoie ainsi un objet image depuis le tenseur.
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)
Jusqu’à présent, nous avons :
- affiché le contenu et la référence d’image de style
- créé une fonction pour convertir des images en tenseurs et des tenseurs en images
Nous allons maintenant convertir les images en tenseur et les transmettre à un module via la méthode «.load ()» du package TensorFlow Hub.
Nous attendons un résultat combiné du style et du contenu de notre image de référence. Par conséquent, nous allons créer une variable pour contenir le résultat de l’opération à partir du module.
Pour visualiser le résultat, nous utilisons simplement la fonction «tensor_to_image» que nous avons créée plus tôt
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)
Observons maintenant le résultat obtenu :
Nous avons alors réussi à combiner le style et le contenu de deux images de référence et généré une image maillée.
Vous pouvez également retrouver le code utilisé dans cet article sur le repo GitHub suivant.
Pour aller plus loin
Cet article vous a plu et vous souhaitez vous initier au transfert de style neuronal, et plus généralement à l’apprentissage automatique, nous vous invitons à participer à notre atelier de découverte sur le deep learning avec notre formation TensorFlow ainsi qu’à notre formation introduction sur le deep learning pour l’interprétation et le traitement d’images.