Variational Autoencoder : Guide complet — Autoencodeur Variationnel
Résumé — Le VAE (Variational Autoencoder) est un modèle génératif introduit par Kingma et Welling en 2013. Contrairement à l’autoencodeur classique qui apprend une représentation déterministe, le VAE apprend une distribution de probabilité dans l’espace latent. Cette approche probabiliste permet non seulement de compresser les données, mais aussi d’en générer de nouvelles en échantillonnant dans l’espace latent. Le VAE est l’un des piliers de l’apprentissage génératif profond, aux côtés des GANs et des modèles de diffusion.
Principe mathématique
1. De l’autoencodeur déterministe au VAE probabiliste
Un autoencodeur classique apprend deux fonctions :
– Encodeur : h = f_θ(x) → un point fixe dans l’espace latent
– Décodeur : r = g_φ(h) → reconstruction
Le problème : cet espace latent est discontinu et non structuré. Deux points proches dans l’espace latent peuvent décoder en images totalement différentes. On ne peut pas générer de nouvelles données de manière fiable.
Le VAE résout ce problème en faisant de l’encodeur un générateur de distributions : au lieu de produire un seul vecteur h, il produit une distribution gaussienne.
2. L’encodeur variationnel
L’encodeur du VAE produit pour chaque entrée x deux vecteurs :
– μ(x) : moyenne de la distribution latente
– σ(x) : écart-type de la distribution latente
La représentation latente est alors un échantillon aléatoire :
$$z \sim \mathcal{N}(\mu(x), \sigma^2(x) \cdot I)$$
Ce qui signifie que z n’est plus un point fixe, mais un point tiré aléatoirement selon une gaussienne centrée sur μ(x) avec un rayon σ(x).
3. Reparameterization trick
Le problème est que l’opération d’échantillonnage z ~ N(μ, σ²) n’est pas différentiable, ce qui empêche la rétropropagation du gradient.
La solution est le reparameterization trick :
$$z = \mu(x) + \sigma(x) \cdot \varepsilon \quad \text{où} \quad \varepsilon \sim \mathcal{N}(0, 1)$$
Maintenant, l’aléa est isolé dans ε (qui ne dépend pas des paramètres du modèle), et la transformation z = μ + σ·ε est différentiable par rapport à μ et σ. Le gradient peut donc circuler.
4. Fonction de coût : ELBO
Le VAE maximise la borne inférieure de l’évidence (ELBO – Evidence Lower BOund) :
$$\mathcal{L}(\theta, \phi; x) = \mathbb{E}{q\phi(z|x)}[\log p_\theta(x|z)] – \text{KL}(q_\phi(z|x) || p(z))$$
Cette formule se décompose en deux termes :
Terme de reconstruction : E[log p_θ(x|z)]
C’est la fidélité de la reconstruction. Plus le décodeur arrive à reconstruire x à partir de z, meilleur est ce terme. En pratique, on utilise la MSE ou la binary cross-entropy.
Terme de KL divergence : KL(q_φ(z|x) || p(z))
C’est une régularisation qui force la distribution latente q(z|x) à être proche d’une distribution a priori p(z) = N(0, I).
Pour des gaussiennes, la KL divergence a une forme close :
$$\text{KL} = \frac{1}{2} \sum_{j=1}^{d} (\sigma_j^2 + \mu_j^2 – \log(\sigma_j^2) – 1)$$
La fonction de coût totale à minimiser est donc :
$$\text{Loss} = \text{Reconstruction} + \beta \cdot \text{KL}$$
où β est un hyperparamètre (souvent β = 1 pour le VAE standard).
5. Génération de nouvelles données
Une fois entraîné, on peut générer de nouvelles données en échantillonnant directement dans la distribution a priori :
$$z_{new} \sim \mathcal{N}(0, I) \quad \rightarrow \quad x_{new} = g_\phi(z_{new})$$
Comme l’encodeur a appris à régulariser les distributions latentes vers N(0, I), le décodeur sait interpréter n’importe quel point de cet espace.
Intuition
Imaginez un cartographe qui doit dessiner une carte d’un continent.
L’autoencodeur classique place chaque ville en un point précis sur la carte. Si vous demandez « qu’y a-t-il à 0.1 km au nord-est de Lyon ? », il n’a pas de réponse — il n’a appris que des points discrets. La carte a des trous entre les villes connues.
Le VAE, lui, ne place pas un point mais dessine un cercle d’incertitude autour de chaque ville. Les cercles se chevauchent, créant une carte continue où chaque point de la carte correspond à quelque chose de plausible. Si vous pointez un endroit entre Lyon et Saint-Étienne, le VAE sait vous décrire une ville plausible qui pourrait s’y trouver.
C’est la différence entre un annuaire téléphonique (autoencodeur : une entrée fixe par personne) et une carte routière (VAE : un espace continu où chaque point a du sens).
Implémentation Python
Exemple 1 : VAE basique avec Keras
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, models
# Paramètres
latent_dim = 2
input_shape = (28, 28, 1) # MNIST
# Encodeur
inputs = keras.Input(shape=input_shape)
x = layers.Flatten()(inputs)
x = layers.Dense(256, activation='relu')(x)
x = layers.Dense(128, activation='relu')(x)
z_mean = layers.Dense(latent_dim, name='z_mean')(x)
z_log_var = layers.Dense(latent_dim, name='z_log_var')(x)
# Reparameterization trick
class Sampling(layers.Layer):
def call(self, inputs):
z_mean, z_log_var = inputs
batch = tf.shape(z_mean)[0]
dim = tf.shape(z_mean)[1]
epsilon = tf.keras.backend.random_normal(shape=(batch, dim))
return z_mean + tf.exp(0.5 * z_log_var) * epsilon
z = Sampling()([z_mean, z_log_var])
encoder = models.Model(inputs, [z_mean, z_log_var, z], name='encoder')
# Décodeur
latent_inputs = keras.Input(shape=(latent_dim,))
x = layers.Dense(128, activation='relu')(latent_inputs)
x = layers.Dense(256, activation='relu')(x)
outputs = layers.Dense(784, activation='sigmoid')(x)
outputs = layers.Reshape((28, 28, 1))(outputs)
decoder = models.Model(latent_inputs, outputs, name='decoder')
# VAE modèle complet
outputs_comb = decoder(z)
vae = models.Model(inputs, outputs_comb, name='vae')
# Loss custom
reconstruction_loss = tf.reduce_mean(
keras.losses.binary_crossentropy(
tf.reshape(inputs, [-1, 784]),
tf.reshape(outputs_comb, [-1, 784])
)
) * 784
kl_loss = -0.5 * tf.reduce_mean(
tf.reduce_sum(
1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var),
axis=1
)
)
total_loss = reconstruction_loss + kl_loss
vae.add_loss(total_loss)
# Compilation
vae.compile(optimizer=keras.optimizers.Adam(learning_rate=1e-3))
vae.summary()
Exemple 2 : Entraînement sur MNIST
# Chargement des données
(x_train, _), (x_test, _) = keras.datasets.mnist.load_data()
x_train = np.expand_dims(x_train, -1).astype('float32') / 255.0
x_test = np.expand_dims(x_test, -1).astype('float32') / 255.0
# Entrainement
history = vae.fit(
x_train,
epochs=20,
batch_size=128,
validation_data=(x_test, None)
)
# Génération d'images
# Échantillonner dans l'espace latent
n_samples = 10
z_samples = np.random.normal(size=(n_samples, latent_dim))
generated_imgs = decoder.predict(z_samples)
# Afficher les images générées
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, n_samples, figsize=(15, 3))
for i, ax in enumerate(axes):
ax.imshow(generated_imgs[i].squeeze(), cmap='gray')
ax.axis('off')
plt.suptitle('Images générées par le VAE')
plt.tight_layout()
plt.savefig('vae_generated.png', dpi=150)
Exemple 3 : Visualisation du latent space 2D
# Encoder tout l'espace test
encoded = encoder.predict(x_test)
z_means = encoded[0] # (10000, 2)
fig, ax = plt.subplots(figsize=(10, 10))
# Charger les labels pour la coloration
(_, y_test), _ = keras.datasets.mnist.load_data()
scatter = ax.scatter(z_means[:, 0], z_means[:, 1], c=y_test,
cmap='tab10', alpha=0.6, s=5)
plt.colorbar(scatter, ticks=range(10), label='Chiffre')
ax.set_title('Espace latent VAE - MNIST (2D)')
ax.set_xlabel('z1')
ax.set_ylabel('z2')
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('vae_latent_space.png', dpi=150)
Exemple 4 : Interpolation dans l’espace latent
# Prendre deux images encodées et interpoler entre elles
z1 = z_means[0:1] # Premier point latent
z2 = z_means[1:2] # Deuxième point latent
n_steps = 20
interp_z = np.linspace(z1, z2, n_steps)
interp_imgs = decoder.predict(interp_z)
# Afficher l'interpolation
fig, axes = plt.subplots(2, 10, figsize=(15, 4))
for i, ax in enumerate(axes.flatten()):
ax.imshow(interp_imgs[i].squeeze(), cmap='gray')
ax.axis('off')
plt.suptitle('Interpolation dans l\'espace latent du VAE')
plt.tight_layout()
plt.savefig('vae_interpolation.png', dpi=150)
Hyperparamètres
| Hyperparamètre | Valeur typique | Description |
|---|---|---|
latent_dim |
2-512 | Dimension de l’espace latent. 2 pour visualisation, 32-128 pour génération |
beta (β) |
0.1-4 | Poids de la KL divergence. Plus grand = espace latent plus régularisé mais reconstruction moins précise |
architecture |
Dense ou Conv | Dense pour données plates, Conv2D pour images |
optimizer |
Adam | Adam est le choix standard. lr = 1e-3 |
epochs |
50-200 | Plus d’epochs = meilleure reconstruction, mais risque de surapprentissage |
batch_size |
64-256 | Standard pour la convergence stable |
Avantages du VAE
- Génération de nouvelles données : Le VAE peut créer des échantillons réalistes en échantillonnant dans l’espace latent. C’est un modèle génératif, pas seulement un compresseur.
- Espace latent continu et structuré : Contrairement à l’autoencodeur classique, l’espace latent du VAE est continu : on peut naviguer, interpoler et explorer de manière significative.
- Fonction de coût analytique : La KL divergence entre gaussiennes a une forme close, ce qui rend le training stable et rapide, sans termes adversaires instables comme les GANs.
- Interprétabilité du latent space : Avec un latent_dim = 2, on peut visualiser directement l’espace latent. Pour des dimensions plus grandes, des analyses de corrélation révèlent les dimensions qui encodent des caractéristiques spécifiques.
- Applications variées : Au-delà de la génération d’images, les VAEs sont utilisés pour la détection d’anomalies, la découverte de médicaments, et la compression d’images.
Limites du VAE
- Images générées floues : La minimisation de la MSE produit des images moyennes plutôt que des images nettes. Les générations VAE sont souvent plus floues que celles des GANs.
- Posterior collapse : Parfois, le décodeur apprend à ignorer l’encodeur et la KL tombe à zéro. Le VAE se réduit alors à un décodeur qui génère des images sans utiliser l’espace latent.
- Sélection de la distribution a priori : Le choix de N(0, I) comme distribution a priori est pratique mais peut être trop restrictif pour des données complexes avec des structures multimodales.
- Difficile à évaluer : Contrairement à un classifieur où la précision est claire, évaluer la qualité des générations d’un VAE nécessite des métriques complexes comme l’Inception Score ou le FID.
- Moins performant que les GANs en qualité visuelle : Les GANs produisent des images plus nettes et plus réalistes, au prix d’un entraînement plus instable.
4 cas d’usage concrets
1. Génération de visages humains
Les VAEs entraînés sur des datasets de visages (CelebA, FFHQ) apprent un espace latent structuré où chaque dimension encode une caractéristique : sourire, orientation, âge, éclairage. En manipulant ces dimensions, on peut générer des visages réalistes avec des attributs contrôlables.
2. Détection d’anomalies par reconstruction
Un VAE entraîné uniquement sur des données normales apprend à bien reconstruire les patterns normaux. Quand une anomalie (un état de machine défaillante, une fraude, une image médicale anormale) est présentée, l’erreur de reconstruction est élevée — signalant l’anomalie.
3. Drug Discovery (conception de molécules)
En chimie informatique, les VAEs encodent des représentations de molécules (SMILES strings) dans un espace latent continu. On peut ensuite naviguer dans cet espace pour trouver de nouvelles molécules avec des propriétés souhaitées (solubilité, efficacité, toxicité réduite).
4. Compression d’images avec génération
Bien que moins efficace que JPEG pour la compression pure, le VAE offre une compression « intelligente » : au lieu de stocker les pixels, on stocke les paramètres latents (μ, σ). La décompression génère une approximation plausible de l’image originale, parfois plus naturelle qu’une décompression JPEG compressée.
Conclusion
Le VAE est une contribution majeure à l’apprentissage génératif : pour la première fois, un modèle de deep learning apprend un espace latent continu, structuré et génératif. Le reparameterization trick est une innovation simple mais profonde qui a ouvert la voie à toute une famille de modèles variationnels.
Même si les GANs surpassent les VAEs en qualité visuelle pure, les VAEs restent incomparables pour l’interprétabilité de l’espace latent et la stabilité de l’entraînement. Et dans les années 2020, les VAEs ont connu un renouveau avec les « VQ-VAE » de DeepMind qui combinent discrétisation et génération pour produire des images de qualité GAN.
Voir aussi
- Maîtriser les Numbers Steps en Python : Guide Complet pour Optimiser Vos Algorithmes
- Emballage de Cercles II en Python : Techniques Avancées et Solutions Optimisées

