Autoencodeur PyTorch
Un autoencodeur (Autoencoder, AE)est un réseau de neurones pour l'apprentissage non supervisé qui compresse les données d'entrée dans un espace latent de faible dimension par apprentissage, puis reconstruit les données d'origine à partir de la représentation compressée.
Les autoencodeurs sont largement utilisés dans des scénarios tels que la réduction de dimensionnalité des données, l'extraction de caractéristiques, la détection d'anomalies, le débruitage d'images et les modèles génératifs.
1. Principes de base de l'autoencodeur
La structure de base d'un autoencodeur se compose de trois parties :
- Encodeur: projette les données d'entrée \(x\) vers une représentation latente de faible dimension \(z\)
- Espace latent: le vecteur de faible dimension produit par l'encodeur, également appelé couche de goulot d'étranglement
- Décodeur: reconstruit la représentation latente \(z\) vers la sortie \(\hat{x}\)
1.1 Structure du réseau
L'objectif d'un autoencodeur est de rendre la sortie \(\hat{x}\) aussi proche que possible de l'entrée \(x\) :
\[ \min_{\theta, \phi} \frac{1}{n} \sum_{i=1}^{n} \| x_i - D_\phi(E_\theta(x_i)) \|^2 \]
où \(\theta\) sont les paramètres de l'encodeur et \(\phi\) sont les paramètres du décodeur.
1.2 Effet de réduction de dimensionnalité
Les autoencodeurs apprennent une représentation compressée des données en forçant les données à passer par une couche de goulot d'étranglement plus petite que la dimension d'entrée. Cette compression préserve les informations principales des données.
Comparés à l'analyse en composantes principales (ACP), les autoencodeurs peuvent apprendre une réduction de dimension non linéaire et capturer des structures de données plus complexes.
2. Implémentation de base d'un autoencodeur
2.1 Autoencodeur simple
Exemple
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
# ── Modèle d'autoencodeur ─────────────────────────────────
class Autoencoder(nn.Module):
"""
Autoencodeur de base : structure symétrique
"""
def __init__(self, input_dim, hidden_dim, latent_dim):
super().__init__()
# Encodeur
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, latent_dim), # Couche de goulot d'étranglement
)
# Décodeur
self.decoder = nn.Sequential(
nn.Linear(latent_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, input_dim),
)
def forward(self, x):
z = self.encoder(x)
x_recon = self.decoder(z)
return x_recon
def encode(self, x):
"""Encodage : obtenir la représentation latente"""
return self.encoder(x)
def decode(self, z):
"""Décodage : reconstruire à partir de la représentation latente"""
return self.decoder(z)
# ── Exemple d'utilisation ──────────────────────────────────────
INPUT_DIM = 784 # Par exemple, après avoir aplati une image MNIST
HIDDEN_DIM = 256
LATENT_DIM = 32 # Dimension de l'espace latent, bien plus petite que la dimension d'entrée
model = Autoencoder(INPUT_DIM, HIDDEN_DIM, LATENT_DIM)
print(f"Dimension d'entrée : {INPUT_DIM}")
print(f"Dimension latente : {LATENT_DIM}")
print(f"Taux de compression : {INPUT_DIM / LATENT_DIM:.1f}x")
# Afficher le nombre de paramètres
total_params = sum(p.numel() for p in model.parameters())
print(f"Nombre total de paramètres : {total_params:,}")
2.2 Autoencodeur convolutif
Pour les données d'image, les autoencodeurs utilisant des couches convolutives sont plus performants :
Exemple
import torch.nn as nn
class ConvAutoencoder(nn.Module):
"""
Autoencodeur convolutif : adapté aux images
"""
def __init__(self, channels=3, latent_dim=128):
super().__init__()
# Encodeur : réduire progressivement la taille, augmenter le nombre de canaux
# Entrée : (batch, channels, 64, 64)
self.encoder = nn.Sequential(
# 32 -> 16
nn.Conv2d(channels, 32, kernel_size=3, stride=2, padding=1),
nn.ReLU(),
# 16 -> 8
nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=1),
nn.ReLU(),
# 8 -> 4
nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1),
nn.ReLU(),
# 4 -> 2
nn.Conv2d(128, 256, kernel_size=3, stride=2, padding=1),
nn.ReLU(),
)
# Mappage de l'espace latent
self.to_latent = nn.AdaptiveAvgPool2d((1, 1))
# Décodeur : augmenter progressivement la taille
# Entrée : (batch, 256, 2, 2)
self.from_latent = nn.Sequential(
nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True),
nn.Conv2d(256, 128, kernel_size=3, padding=1),
nn.ReLU(),
nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True),
nn.Conv2d(128, 64, kernel_size=3, padding=1),
nn.ReLU(),
nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True),
nn.Conv2d(64, 32, kernel_size=3, padding=1),
nn.ReLU(),
nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True),
nn.Conv2d(32, channels, kernel_size=3, padding=1),
nn.Sigmoid() # Sortie [0, 1]
)
def forward(self, x):
z = self.encode(x)
x_recon = self.decode(z)
return x_recon
def encode(self, x):
"""Encoder"""
features = self.encoder(x)
z = self.to_latent(features)
z = z.view(z.size(0), -1) # (batch, 256)
return z
def decode(self, z):
"""Décoder"""
# Redimensionner le vecteur en carte de caractéristiques
batch_size = z.size(0)
z = z.view(batch_size, 256, 1, 1)
z = z.expand(-1, -1, 2, 2) # Suréchantillonner à 2x2
x_recon = self.from_latent(z)
return x_recon
# Test
model = ConvAutoencoder(channels=3, latent_dim=128)
x = torch.randn(4, 3, 64, 64)
x_recon = model(x)
print(f"Forme de l'entrée : {x.shape}")
print(f"Forme de sortie : {x_recon.shape}")
print(f"Forme du vecteur latent : {model.encode(x).shape}")
2.3 Entraînement et reconstruction
Exemple
import torch.nn as nn
import torch.optim as optim
# ── Configuration d'entraînement ─────────────────────────────────────
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = ConvAutoencoder(channels=3, latent_dim=128).to(device)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=1e-3)
# ── Boucle d'entraînement ─────────────────────────────────────
def train_autoencoder(model, dataloader, criterion, optimizer, num_epochs=10):
model.train()
for epoch in range(num_epochs):
total_loss = 0
for batch in dataloader:
images = batch[0].to(device)
# Propagation avant
outputs = model(images)
loss = criterion(outputs, images)
# Rétropropagation
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
avg_loss = total_loss / len(dataloader)
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {avg_loss:.6f}")
return model
# On suppose qu'un chargeur de données existe déjà
# train_autoencoder(model, train_loader, criterion, optimizer, num_epochs=10)
print("Entraînement de l'autoencodeur terminé !")
3. Autoencodeur débruiteur (DAE)
L'autoencodeur débruiteur (DAE)ajoute du bruit à l'entrée pendant l'entraînement, puis apprend à supprimer le bruit et à récupérer l'entrée d'origine. Cela permet au modèle d'apprendre des représentations de caractéristiques plus robustes.
3.1 Implémentation de l'autoencodeur débruiteur
Exemple
import torch.nn as nn
class DenoisingAutoencoder(nn.Module):
"""
Autoencodeur débruiteur
"""
def __init__(self, input_dim, hidden_dim, latent_dim):
super().__init__()
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, latent_dim),
)
self.decoder = nn.Sequential(
nn.Linear(latent_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, input_dim),
nn.Sigmoid() # Sortie [0, 1]
)
def forward(self, x):
z = self.encode(x)
return self.decode(z)
def encode(self, x):
return self.encoder(x)
def decode(self, z):
return self.decoder(z)
def add_noise(x, noise_factor=0.3):
"""
Ajouter un bruit gaussien
"""
noise = torch.randn_like(x) * noise_factor
noisy_x = x + noise
return torch.clamp(noisy_x, 0.0, 1.0)
# Entraîner l'autoencodeur de débruitage
def train_dae(model, dataloader, noise_factor=0.3, lr=1e-3):
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=lr)
model.train()
for epoch in range(10):
for batch in dataloader:
images = batch[0]
# Ajouter du bruit
noisy_images = add_noise(images, noise_factor)
noisy_images = noisy_images.to(next(model.parameters()).device)
images = images.to(next(model.parameters()).device)
# Propagation avant
outputs = model(noisy_images)
loss = criterion(outputs, images) # Comparer à l'image originale, pas à l'image bruitée
# Rétropropagation
optimizer.zero_grad()
loss.backward()
optimizer.step()
return model
3.2 Autres types de bruit
Exemple
"""Bruit poivre et sel"""
random_mask = torch.rand_like(x)
noisy = x.clone()
noisy[random_mask < prob / 2] = 0.0
noisy[random_mask > 1 - prob / 2] = 1.0
return noisy
def mask_noise(x, prob=0.1):
"""Bruit de masquage (mis aléatoirement à zéro)"""
mask = torch.rand_like(x) > prob
return x * mask.float()
def dropout_noise(x, rate=0.2):
"""Bruit de dropout"""
mask = torch.rand_like(x) > rate
return x * mask.float() / (1 - rate)
4. Auto-encodeur variationnel (VAE)
Auto-encodeur variationnel (VAE)est un modèle génératif qui encode les données en une distribution de probabilité dans l'espace latent plutôt qu'en un vecteur fixe. Cela nous permet d'échantillonner à partir de l'espace latent pour générer de nouvelles données.
4.1 Principes fondamentaux du VAE
L'innovation clé du VAE est d'apprendre la distribution de probabilité des variables latentes :
- L'encodeur produit la moyenne \(\mu\) et l'écart-type \(\sigma\)
- Échantillonner le vecteur latent \(z\) à partir de la distribution normale \(\mathcal{N}(\mu, \sigma)\)
- Le décodeur reconstruit les données à partir de \(z\)
Pour obtenir un processus d'échantillonnage différentiable, l'astuce de reparamétrisation est utilisée.:
\[ z = \mu + \sigma \cdot \epsilon, \quad \epsilon \sim \mathcal{N}(0, 1) \]
4.2 Implémentation du VAE
Exemple
import torch.nn as nn
import torch.optim as optim
class VAE(nn.Module):
"""
Autoencodeur variationnel
"""
def __init__(self, input_dim, hidden_dim, latent_dim):
super().__init__()
# Encodeur : moyenne et variance en sortie
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
)
self.fc_mu = nn.Linear(hidden_dim, latent_dim)
self.fc_logvar = nn.Linear(hidden_dim, latent_dim)
# Décodeur
self.decoder = nn.Sequential(
nn.Linear(latent_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, input_dim),
nn.Sigmoid()
)
def encode(self, x):
h = self.encoder(x)
mu = self.fc_mu(h)
logvar = self.fc_logvar(h)
return mu, logvar
def reparameterize(self, mu, logvar):
"""Astuce de reparamétrisation"""
std = torch.exp(0.5 * logvar)
eps = torch.randn_like(std)
return mu + eps * std
def decode(self, z):
return self.decoder(z)
def forward(self, x):
mu, logvar = self.encode(x)
z = self.reparameterize(mu, logvar)
x_recon = self.decode(z)
return x_recon, mu, logvar
def vae_loss(x_recon, x, mu, logvar, beta=1.0):
"""
Fonction de perte VAE
Perte de reconstruction + divergence KL
"""
# Perte de reconstruction
recon_loss = nn.functional.mse_loss(x_recon, x, reduction='sum')
# Divergence KL : -0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
kl_loss = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())
return recon_loss + beta * kl_loss, recon_loss, kl_loss
# Exemple d'utilisation
INPUT_DIM = 784
HIDDEN_DIM = 256
LATENT_DIM = 2 # Espace latent bidimensionnel pour une visualisation facile
model = VAE(INPUT_DIM, HIDDEN_DIM, LATENT_DIM)
# Test
x = torch.randn(32, 784)
x_recon, mu, logvar = model(x)
print(f"Forme de l'entrée : {x.shape}")
print(f"Forme reconstruite : {x_recon.shape}")
print(f"Forme de la moyenne : {mu.shape}") # (32, 2)
print(f"Forme de la variance : {logvar.shape}") # (32, 2)
4.3 Génération et visualisation VAE
Exemple
def visualize_latent_space(model, dataloader, device):
"""Visualisation de l'espace latent"""
model.eval()
all_mu = []
all_labels = []
with torch.no_grad():
for batch in dataloader:
images, labels = batch[0].to(device), batch[1]
mu, _ = model.encode(images)
all_mu.append(mu.cpu())
all_labels.append(labels)
all_mu = torch.cat(all_mu, dim=0).numpy()
all_labels = torch.cat(all_labels, dim=0).numpy()
plt.figure(figsize=(10, 8))
scatter = plt.scatter(all_mu[:, 0], all_mu[:, 1], c=all_labels,
cmap='tab10', alpha=0.5, s=10)
plt.colorbar(scatter)
plt.xlabel('Dimension latente 1')
plt.ylabel('Dimension latente 2')
plt.title('Espace latent du VAE')
plt.show()
def generate_from_latent(model, z, device):
"""Génération d'images à partir de vecteurs latents"""
model.eval()
with torch.no_grad():
z = z.to(device)
generated = model.decode(z)
return generated
def interpolate_latent(model, z1, z2, steps=10, device):
"""Génération par interpolation dans l'espace latent"""
model.eval()
# Interpolation linéaire
alphas = torch.linspace(0, 1, steps)
interpolated = []
with torch.no_grad():
for alpha in alphas:
z = z1 * (1 - alpha) + z2 * alpha
generated = model.decode(z)
interpolated.append(generated)
return torch.cat(interpolated, dim=0)
# Générer de nouvelles images
def generate_new_images(model, num_images, latent_dim, device):
"""Générer de nouvelles images à partir de vecteurs latents aléatoires"""
model.eval()
with torch.no_grad():
# Échantillonner depuis une distribution normale standard
z = torch.randn(num_images, latent_dim).to(device)
generated = model.decode(z)
return generated
L'espace latent d'un VAE est continu, permettant une interpolation dans l'espace latent pour générer des images avec des transitions fluides. Cependant, les images générées par un VAE sont souvent floues car il optimise une borne inférieure plutôt que la log-vraisemblance exacte.
5. Autoencodeur parcimonieux
Autoencodeur parcimonieuxAjoutez une contrainte de parcimonie à la fonction de perte, limitant le nombre d'activations dans le vecteur latent. Cela permet au modèle d'apprendre des caractéristiques plus significatives.
5.1 Implémentation de l'autoencodeur parcimonieux
import torch.nn as nn
import torch.nn.functional as F
class SparseAutoencoder(nn.Module):
"""
Autoencodeur parcimonieux
"""
def __init__(self, input_dim, hidden_dim, latent_dim):
super().__init__()
# Encodeur
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
)
# Couche latente
self.bottleneck = nn.Linear(hidden_dim, latent_dim)
# Décodeur
self.decoder = nn.Sequential(
nn.Linear(latent_dim, hidden_dim),
nn.ReLU(),
nn.Linear(hidden_dim, input_dim),
nn.Sigmoid()
)
def forward(self, x):
h = self.encoder(x)
z = self.bottleneck(h)
z_activated = F.relu(z) # Activation parcimonieuse
x_recon = self.decoder(z_activated)
return x_recon, z_activated
def sparse_loss(z, rho=0.05, beta=1.0):
"""
Perte de parcimonie : divergence KL
rho : parcimonie cible (par ex., 0.05 signifie que seulement 5% des neurones devraient être actifs)
beta : poids du terme de parcimonie
"""
# Calculer l'activation moyenne
rho_hat = torch.mean(z, dim=0)
# Divergence KL
kl = rho * torch.log(rho / (rho_hat + 1e-8)) + \
(1 - rho) * torch.log((1 - rho) / (1 - rho_hat + 1e-8))
return beta * torch.sum(kl)
def total_sparse_loss(x_recon, x, z, rho=0.05, beta=1.0):
"""Perte totale = perte de reconstruction + perte de parcimonie"""
recon_loss = F.mse_loss(x_recon, x)
sparsity = sparse_loss(z, rho, beta)
return recon_loss + sparsity
6. Autoencodeur séquence à séquence
Pour les données séquentielles (comme le texte, les séries temporelles), utilisez RNN/LSTM comme encodeur et décodeur.
6.1 Implémentation de l'auto-encodeur de séquence
Exemple
import torch.nn as nn
class Seq2SeqAutoencoder(nn.Module):
"""
Auto-encodeur séquence à séquence : utilisé pour les données séquentielles
"""
def __init__(self, input_size, hidden_size, latent_size, num_layers=2):
super().__init__()
# Encodeur LSTM
self.encoder = nn.LSTM(
input_size=input_size,
hidden_size=hidden_size,
num_layers=num_layers,
batch_first=True,
bidirectional=True
)
# Mappage de l'espace latent
# La sortie du LSTM bidirectionnel est hidden_size * 2
self.to_latent = nn.Linear(hidden_size * 2, latent_size)
self.from_latent = nn.Linear(latent_size, hidden_size * 2)
# LSTM décodeur
self.decoder = nn.LSTM(
input_size=hidden_size,
hidden_size=hidden_size,
num_layers=num_layers,
batch_first=True,
bidirectional=True
)
# Projection de sortie
self.output_proj = nn.Linear(hidden_size * 2, input_size)
def forward(self, x):
# Encodage
_, (h_n, _) = self.encoder(x)
# Concaténer les états cachés finaux bidirectionnels
# h_n: (num_layers * 2, batch, hidden_size)
h_forward = h_n[-2]
h_backward = h_n[-1]
h_combined = torch.cat([h_forward, h_backward], dim=-1)
# Mapper vers l'espace latent
z = self.to_latent(h_combined)
# Remapper depuis l'espace latent
decoder_init = self.from_latent(z)
decoder_init = decoder_init.view(2, decoder_init.size(0), -1) # (2, batch, hidden_size*2)
# Décoder (en utilisant la longueur d'entrée d'origine)
decoder_output, _ = self.decoder(
x,
(decoder_init, torch.zeros_like(decoder_init))
)
# Projection de sortie
output = self.output_proj(decoder_output)
return output, z
# Exemple d'utilisation
model = Seq2SeqAutoencoder(
input_size=128, # Dimension des caractéristiques d'entrée
hidden_size=256, # Dimension cachée du LSTM
latent_size=64, # Dimension de l'espace latent
num_layers=2
)
# Test
x = torch.randn(8, 20, 128) # (batch, seq_len, input_size)
output, z = model(x)
print(f"Forme de l'entrée : {x.shape}") # (8, 20, 128)
print(f"Forme de sortie : {output.shape}") # (8, 20, 128)
print(f"Forme du vecteur latent : {z.shape}") # (8, 64)
7. Scénarios d'application des autoencodeurs
7.1 Détection d'anomalies
Les autoencodeurs peuvent être utilisés pour détecter des données anormales. Les données normales ont une faible erreur de reconstruction, tandis que les données anormales ont une erreur de reconstruction élevée :
Exemple
import torch.nn as nn
def detect_anomalies(model, data_loader, threshold=None, device='cpu'):
"""
Détection d'anomalies à l'aide d'autoencodeurs
"""
model.eval()
reconstruction_errors = []
with torch.no_grad():
for batch in data_loader:
images = batch[0].to(device)
outputs = model(images)
# Calculer l'erreur de reconstruction (erreur quadratique moyenne)
errors = torch.mean((outputs - images) ** 2, dim=(1, 2, 3))
reconstruction_errors.extend(errors.cpu().numpy())
reconstruction_errors = torch.tensor(reconstruction_errors)
# Si aucun seuil n'est fourni, utiliser une méthode statistique
if threshold is None:
# Utiliser le percentile 95%
threshold = torch.quantile(reconstruction_errors, 0.95).item()
# Marquer les anomalies
anomalies = reconstruction_errors > threshold
return anomalies, reconstruction_errors, threshold
# Entraîner le modèle de détection d'anomalies
def train_anomaly_detector(normal_data_loader):
"""Entraîner l'auto-encodeur en utilisant uniquement des données normales"""
model = ConvAutoencoder(channels=1, latent_dim=32)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)
model.train()
for epoch in range(10):
for batch in normal_data_loader:
images = batch[0]
outputs = model(images)
loss = criterion(outputs, images)
optimizer.zero_grad()
loss.backward()
optimizer.step()
return model
7.2 Colorisation d'images et transfert de style
Exemple
"""
Auto-encodeur de colorisation d'images
Entrée : image en niveaux de gris (batch, 1, H, W)
Sortie : image couleur (batch, 2, H, W) (espace colorimétrique ab)
"""
def __init__(self):
super().__init__()
# Encodeur : extraire progressivement les caractéristiques
self.encoder = nn.Sequential(
nn.Conv2d(1, 64, kernel_size=4, stride=2, padding=1), # H/2
nn.ReLU(),
nn.Conv2d(64, 128, kernel_size=4, stride=2, padding=1), # H/4
nn.BatchNorm2d(128),
nn.ReLU(),
nn.Conv2d(128, 256, kernel_size=4, stride=2, padding=1), # H/8
nn.BatchNorm2d(256),
nn.ReLU(),
)
# Décodeur : suréchantillonner pour générer des couleurs
self.decoder = nn.Sequential(
nn.ConvTranspose2d(256, 128, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(),
nn.ConvTranspose2d(128, 64, kernel_size=4, stride=2, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(),
nn.ConvTranspose2d(64, 32, kernel_size=4, stride=2, padding=1),
nn.ReLU(),
nn.Conv2d(32, 2, kernel_size=3, padding=1), # Canaux ab en sortie
nn.Sigmoid() # plage des canaux ab [0, 1]
)
def forward(self, x):
z = self.encoder(x)
color = self.decoder(z)
return color
7.3 Visualisation de la réduction de dimensionnalité des données
Exemple
def visualize_latent_2d(model, dataloader, device, num_samples=1000):
"""
Utiliser un autoencodeur pour réduire les données à 2 dimensions pour la visualisation
"""
model.eval()
all_latents = []
all_labels = []
with torch.no_grad():
count = 0
for batch in dataloader:
if count >= num_samples:
break
images, labels = batch[0], batch[1]
images = images.to(device)
# S’il s’agit d’un AE 2D, utilisez-le directement
# Si la dimensionnalité est supérieure, projetez d’abord en 2D
z = model.encode(images)
all_latents.append(z.cpu())
all_labels.append(labels)
count += images.size(0)
latents = torch.cat(all_latents, dim=0)[:num_samples].numpy()
labels = torch.cat(all_labels, dim=0)[:num_samples].numpy()
plt.figure(figsize=(10, 8))
scatter = plt.scatter(latents[:, 0], latents[:, 1], c=labels,
cmap='tab10', alpha=0.6, s=20)
plt.colorbar(scatter)
plt.xlabel('Dimension latente 1')
plt.ylabel('Dimension latente 2')
plt.title('Visualisation de l’espace latent 2D de l’autoencodeur')
plt.show()
8. Référence rapide de l’API
8.1 Types courants d’autoencodeurs
| Type | Caractéristiques | Scénarios applicables |
|---|---|---|
| Autoencodeur de base | Structure symétrique simple | Réduction de dimensionnalité, extraction de caractéristiques |
| Autoencodeur convolutif | Utilise des couches convolutives pour préserver la structure spatiale | Traitement d'images |
| Autoencodeur de débruitage | Apprend à supprimer le bruit | Débruitage d'images, caractéristiques robustes |
| Autoencodeur variationnel | Apprend les distributions de probabilité, peut générer de nouvelles données | Modèles génératifs, génération de données |
| Autoencodeur parcimonieux | Contrainte de parcimonie, apprend des caractéristiques interprétables | Désenchevêtrement des caractéristiques, interprétabilité |
| Autoencodeur de séquence | Utilise RNN/LSTM pour traiter des séquences | Texte, séries temporelles |
8.2 Sélection de la fonction de perte
| Tâche | Fonction de perte recommandée |
|---|---|
| Reconstruction d'image | MSELoss、SSIMLoss |
| Images binaires | BCELoss、BCEWithLogitsLoss |
| Reconstruction de texte | CrossEntropyLoss |
| VAE | MSE + divergence KL |
| Détection d'anomalies | MSE、MAE |
8.3 Sélection de la dimension latente
数据维度低(<100维)
-> 潜在维度设为 2~10
数据维度中等(100~1000维)
-> 潜在维度设为 10~50
数据维度高(>1000维)
-> 潜在维度设为 50~200
生成任务(VAE)
-> 潜在维度 2~32(便于采样和可视化)
异常检测
-> 潜在维度 16~64(保留足够信息检测异常)
Autres extensions