PyTorch Autoencoder
El autoencoder (Autoencoder, AE)es una red neuronal de aprendizaje no supervisado que comprime los datos de entrada a un espacio latente de baja dimensión y reconstruye los datos originales a partir de la representación comprimida.
Los autoencoders se utilizan ampliamente en escenarios como reducción de dimensionalidad de datos, extracción de características, detección de anomalías, denoising de imágenes y modelos generativos.
1. Principios básicos del autoencoder
La estructura básica de un autoencoder incluye tres partes:
- Codificador (Encoder): mapea los datos de entrada \(x\) a una representación latente de baja dimensión \(z\)
- Espacio latente (Latent Space): el vector de baja dimensión que genera el codificador, también conocido como capa de cuello de botella
- Decodificador (Decoder): reconstruye la representación latente \(z\) en la salida \(\hat{x}\)
1.1 Estructura de la red
El objetivo del autoencoder es que la salida \(\hat{x}\) sea lo más cercana posible a la entrada \(x\):
\[ \min_{\theta, \phi} \frac{1}{n} \sum_{i=1}^{n} \| x_i - D_\phi(E_\theta(x_i)) \|^2 \]
donde \(\theta\) son los parámetros del codificador y \(\phi\) son los parámetros del decodificador.
1.2 Efecto de reducción de dimensionalidad
El autoencoder aprende una representación comprimida de los datos al forzarlos a pasar por una capa de cuello de botella con menor dimensión que la entrada. Esta compresión conserva la información principal de los datos.
En comparación con el Análisis de Componentes Principales (PCA), el autoencoder puede aprender una reducción de dimensionalidad no lineal y capturar estructuras de datos más complejas.
2. Implementación básica del autoencoder
2.1 Autoencoder simple
Ejemplo
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
# ── Modelo de autoencoder ─────────────────────────────────
class Autoencoder(nn.Module):
"""
Autoencoder básico: estructura simétrica
"""
def __init__(self, input_dim, hidden_dim, latent_dim):
super().__init__()
# Codificador
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), # Capa de cuello de botella
)
# Decodificador
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):
"""Codificación: obtener la representación latente"""
return self.encoder(x)
def decode(self, z):
"""Decodificación: reconstruir desde la representación latente"""
return self.decoder(z)
# ── Ejemplo de uso ──────────────────────────────────────
INPUT_DIM = 784 # Por ejemplo, después de aplanar la imagen MNIST
HIDDEN_DIM = 256
LATENT_DIM = 32 # La dimensión del espacio latente, mucho menor que la dimensión de entrada
model = Autoencoder(INPUT_DIM, HIDDEN_DIM, LATENT_DIM)
print(f"Dimensión de entrada: {INPUT_DIM}")
print(f"Dimensión latente: {LATENT_DIM}")
print(f"Relación de compresión: {INPUT_DIM / LATENT_DIM:.1f}x")
# Ver cantidad de parámetros
total_params = sum(p.numel() for p in model.parameters())
print(f"Total de parámetros: {total_params:,}")
2.2 Autoencoder convolucional
Para datos de imagen, los autoencoders que usan capas convolucionales funcionan mejor:
Ejemplo
import torch.nn as nn
class ConvAutoencoder(nn.Module):
"""
Autoencoder convolucional: adecuado para imágenes
"""
def __init__(self, channels=3, latent_dim=128):
super().__init__()
# Codificador: reduce gradualmente el tamaño, aumenta el número de canales
# Entrada: (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(),
)
# Mapeo del espacio latente
self.to_latent = nn.AdaptiveAvgPool2d((1, 1))
# Decodificador: aumenta gradualmente el tamaño
# Entrada: (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() # Salida [0, 1]
)
def forward(self, x):
z = self.encode(x)
x_recon = self.decode(z)
return x_recon
def encode(self, x):
"""Codificar"""
features = self.encoder(x)
z = self.to_latent(features)
z = z.view(z.size(0), -1) # (batch, 256)
return z
def decode(self, z):
"""Decodificar"""
# Reestructurar el vector a un mapa de características
batch_size = z.size(0)
z = z.view(batch_size, 256, 1, 1)
z = z.expand(-1, -1, 2, 2) # Sobremuestrear a 2x2
x_recon = self.from_latent(z)
return x_recon
# Prueba
model = ConvAutoencoder(channels=3, latent_dim=128)
x = torch.randn(4, 3, 64, 64)
x_recon = model(x)
print(f"Forma de entrada: {x.shape}")
print(f"Forma de salida: {x_recon.shape}")
print(f"Forma del vector latente: {model.encode(x).shape}")
2.3 Entrenamiento y reconstrucción
Ejemplo
import torch.nn as nn
import torch.optim as optim
# ── Configuración de entrenamiento ────────────────────────────
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)
# ── Bucle de entrenamiento ────────────────────────────────────
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)
# Propagación hacia adelante
outputs = model(images)
loss = criterion(outputs, images)
# Propagación hacia atrás
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
# Suponiendo que ya existe un cargador de datos
# train_autoencoder(model, train_loader, criterion, optimizer, num_epochs=10)
print("¡Entrenamiento del autoencoder completado!")
3. Autoencoder de denoising (DAE)
El autoencoder de denoising (Denoising Autoencoder, DAE)añade ruido a la entrada durante el entrenamiento y luego aprende a eliminar el ruido para recuperar la entrada original. Esto permite que el modelo aprenda representaciones de características más robustas.
3.1 Implementación del autoencoder de denoising
Ejemplo
import torch.nn as nn
class DenoisingAutoencoder(nn.Module):
"""
Autoencoder de denoising
"""
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() # Salida [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):
"""
Añadir ruido gaussiano
"""
noise = torch.randn_like(x) * noise_factor
noisy_x = x + noise
return torch.clamp(noisy_x, 0.0, 1.0)
# Entrenar el autoencoder de denoising
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]
# Añadir ruido
noisy_images = add_noise(images, noise_factor)
noisy_images = noisy_images.to(next(model.parameters()).device)
images = images.to(next(model.parameters()).device)
# Propagación hacia adelante
outputs = model(noisy_images)
loss = criterion(outputs, images) # Comparar con la imagen original, no con la imagen con ruido
# Propagación hacia atrás
optimizer.zero_grad()
loss.backward()
optimizer.step()
return model
3.2 Otros tipos de ruido
Ejemplo
"""Ruido de sal y pimienta"""
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):
"""Ruido de enmascaramiento (puesta a cero aleatoria)"""
mask = torch.rand_like(x) > prob
return x * mask.float()
def dropout_noise(x, rate=0.2):
"""Ruido Dropout"""
mask = torch.rand_like(x) > rate
return x * mask.float() / (1 - rate)
4. Autoencoder variacional (VAE)
El autoencoder variacional (Variational Autoencoder, VAE)es un modelo generativo que codifica los datos como una distribución de probabilidad en el espacio latente, en lugar de un vector fijo. Esto nos permite muestrear del espacio latente para generar nuevos datos.
4.1 Principios fundamentales del VAE
La innovación clave del VAE es aprender la distribución de probabilidad de las variables latentes:
- El codificador genera la media \(\mu\) y la desviación estándar \(\sigma\)
- Se muestrea un vector latente \(z\) de la distribución normal \(\mathcal{N}(\mu, \sigma)\)
- El decodificador reconstruye los datos a partir de \(z\)
Para lograr un proceso de muestreo diferenciable, se utiliza elTruco de reparametrización (Reparameterization Trick):
\[ z = \mu + \sigma \cdot \epsilon, \quad \epsilon \sim \mathcal{N}(0, 1) \]
4.2 Implementación del VAE
Ejemplo
import torch.nn as nn
import torch.optim as optim
class VAE(nn.Module):
"""
Autoencoder variacional
"""
def __init__(self, input_dim, hidden_dim, latent_dim):
super().__init__()
# Codificador: genera media y varianza
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)
# Decodificador
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):
"""Truco de reparametrización"""
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):
"""
Función de pérdida del VAE
Pérdida de reconstrucción + divergencia KL
"""
# Pérdida de reconstrucción
recon_loss = nn.functional.mse_loss(x_recon, x, reduction='sum')
# Divergencia 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
# Ejemplo de uso
INPUT_DIM = 784
HIDDEN_DIM = 256
LATENT_DIM = 2 # Espacio latente bidimensional para facilitar la visualización
model = VAE(INPUT_DIM, HIDDEN_DIM, LATENT_DIM)
# Prueba
x = torch.randn(32, 784)
x_recon, mu, logvar = model(x)
print(f"Forma de entrada: {x.shape}")
print(f"Forma de reconstrucción: {x_recon.shape}")
print(f"Forma de la media: {mu.shape}") # (32, 2)
print(f"Forma de la varianza: {logvar.shape}") # (32, 2)
4.3 Generación y visualización con VAE
Ejemplo
def visualize_latent_space(model, dataloader, device):
"""Visualizar el espacio latente"""
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('Latent Dimension 1')
plt.ylabel('Latent Dimension 2')
plt.title('VAE Latent Space')
plt.show()
def generate_from_latent(model, z, device):
"""Generar imágenes desde vectores latentes"""
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):
"""Generación por interpolación en el espacio latente"""
model.eval()
# Interpolación lineal
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)
# Generar nuevas imágenes
def generate_new_images(model, num_images, latent_dim, device):
"""Generar nuevas imágenes desde vectores latentes aleatorios"""
model.eval()
with torch.no_grad():
# Muestrear de una distribución normal estándar
z = torch.randn(num_images, latent_dim).to(device)
generated = model.decode(z)
return generated
El espacio latente de un VAE es continuo, por lo que se puede interpolar en el espacio latente para generar imágenes con transiciones suaves. Sin embargo, las imágenes generadas por un VAE suelen ser borrosas, porque optimiza un límite inferior en lugar de la verosimilitud logarítmica exacta.
5. Autoencoder disperso
Autoencoder disperso (Sparse Autoencoder)Se añade una restricción de dispersión a la función de pérdida para limitar el número de activaciones en el vector latente. Esto permite al modelo aprender características más significativas.
5.1 Implementación del autoencoder disperso
import torch.nn as nn
import torch.nn.functional as F
class SparseAutoencoder(nn.Module):
"""
Autoencoder disperso
"""
def __init__(self, input_dim, hidden_dim, latent_dim):
super().__init__()
# Codificador
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
)
# Capa latente
self.bottleneck = nn.Linear(hidden_dim, latent_dim)
# Decodificador
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) # Activación dispersa
x_recon = self.decoder(z_activated)
return x_recon, z_activated
def sparse_loss(z, rho=0.05, beta=1.0):
"""
Pérdida de dispersión: divergencia KL
rho: dispersión objetivo (por ejemplo, 0.05 significa que solo el 5% de las neuronas deberían activarse)
beta: peso del término de dispersión
"""
# Calcular la activación media
rho_hat = torch.mean(z, dim=0)
# Divergencia 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):
"""Pérdida total = pérdida de reconstrucción + pérdida de dispersión"""
recon_loss = F.mse_loss(x_recon, x)
sparsity = sparse_loss(z, rho, beta)
return recon_loss + sparsity
6. Autoencoder secuencia a secuencia
Para datos secuenciales (como texto o series temporales), se utilizan RNN/LSTM como codificador y decodificador.
6.1 Implementación del autoencoder de secuencias
Ejemplo
import torch.nn as nn
class Seq2SeqAutoencoder(nn.Module):
"""
Autoencoder secuencia a secuencia: para datos secuenciales
"""
def __init__(self, input_size, hidden_size, latent_size, num_layers=2):
super().__init__()
# Codificador LSTM
self.encoder = nn.LSTM(
input_size=input_size,
hidden_size=hidden_size,
num_layers=num_layers,
batch_first=True,
bidirectional=True
)
# Mapeo al espacio latente
# La salida del LSTM bidireccional es hidden_size * 2
self.to_latent = nn.Linear(hidden_size * 2, latent_size)
self.from_latent = nn.Linear(latent_size, hidden_size * 2)
# Decodificador LSTM
self.decoder = nn.LSTM(
input_size=hidden_size,
hidden_size=hidden_size,
num_layers=num_layers,
batch_first=True,
bidirectional=True
)
# Mapeo de salida
self.output_proj = nn.Linear(hidden_size * 2, input_size)
def forward(self, x):
# Codificación
_, (h_n, _) = self.encoder(x)
# Combinar el último estado oculto bidireccional
# 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)
# Mapear al espacio latente
z = self.to_latent(h_combined)
# Mapear de vuelta desde el espacio latente
decoder_init = self.from_latent(z)
decoder_init = decoder_init.view(2, decoder_init.size(0), -1) # (2, batch, hidden_size*2)
# Decodificar (usando la longitud de entrada original)
decoder_output, _ = self.decoder(
x,
(decoder_init, torch.zeros_like(decoder_init))
)
# Mapeo de salida
output = self.output_proj(decoder_output)
return output, z
# Ejemplo de uso
model = Seq2SeqAutoencoder(
input_size=128, # Dimensión de características de entrada
hidden_size=256, # Dimensión oculta del LSTM
latent_size=64, # Dimensión del espacio latente
num_layers=2
)
# Prueba
x = torch.randn(8, 20, 128) # (batch, seq_len, input_size)
output, z = model(x)
print(f"Forma de entrada: {x.shape}") # (8, 20, 128)
print(f"Forma de salida: {output.shape}") # (8, 20, 128)
print(f"Forma del vector latente: {z.shape}") # (8, 64)
7. Escenarios de aplicación del autoencoder
7.1 Detección de anomalías
Un autoencoder puede utilizarse para detectar datos anómalos. El error de reconstrucción es pequeño para datos normales y grande para datos anómalos:
Ejemplo
import torch.nn as nn
def detect_anomalies(model, data_loader, threshold=None, device='cpu'):
"""
Detección de anomalías usando un autoencoder
"""
model.eval()
reconstruction_errors = []
with torch.no_grad():
for batch in data_loader:
images = batch[0].to(device)
outputs = model(images)
# Calcular el error de reconstrucción (error cuadrático medio)
errors = torch.mean((outputs - images) ** 2, dim=(1, 2, 3))
reconstruction_errors.extend(errors.cpu().numpy())
reconstruction_errors = torch.tensor(reconstruction_errors)
# Si no se da un umbral, usar un método estadístico
if threshold is None:
# Usar el percentil 95
threshold = torch.quantile(reconstruction_errors, 0.95).item()
# Marcar anomalías
anomalies = reconstruction_errors > threshold
return anomalies, reconstruction_errors, threshold
# Entrenar modelo de detección de anomalías
def train_anomaly_detector(normal_data_loader):
"""Entrenar el autoencoder solo con datos 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 Coloreado de imágenes y transferencia de estilo
Ejemplo
"""
Autoencoder para colorización de imágenes
Entrada: imagen en escala de grises (batch, 1, H, W)
Salida: imagen en color (batch, 2, H, W) (espacio de color ab)
"""
def __init__(self):
super().__init__()
# Codificador: extraer características gradualmente
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(),
)
# Decodificador: aumentar la resolución para generar color
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), # Salida de canales ab
nn.Sigmoid() # Rango de canales ab [0, 1]
)
def forward(self, x):
z = self.encoder(x)
color = self.decoder(z)
return color
7.3 Visualización de reducción de dimensionalidad de datos
Ejemplo
def visualize_latent_2d(model, dataloader, device, num_samples=1000):
"""
Usar un autoencoder para reducir los datos a 2 dimensiones y visualizarlos
"""
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)
# Si es un AE 2D, usar directamente
# Si la dimensión es mayor, primero proyectar a 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('Latent Dimension 1')
plt.ylabel('Latent Dimension 2')
plt.title('Autoencoder 2D Latent Space Visualization')
plt.show()
8. Referencia rápida de API
8.1 Tipos comunes de autoencoders
| Tipo | Características | Escenarios de aplicación |
|---|---|---|
| Autoencoder básico | Estructura simétrica simple | Reducción de dimensionalidad, extracción de características |
| Autoencoder convolucional | Usa capas convolucionales para preservar la estructura espacial | Procesamiento de imágenes |
| Autoencoder de denoising | Aprende a eliminar el ruido | Eliminación de ruido en imágenes, características robustas |
| Autoencoder variacional | Aprende una distribución de probabilidad, puede generar nuevos datos | Modelo generativo, generación de datos |
| Autoencoder disperso | Restricción de dispersión, aprende características interpretables | Desacoplamiento de características, interpretabilidad |
| Autoencoder secuencial | Usa RNN/LSTM para procesar secuencias | Texto, series temporales |
8.2 Selección de la función de pérdida
| Tarea | Función de pérdida recomendada |
|---|---|
| Reconstrucción de imágenes | MSELoss、SSIMLoss |
| Imágenes binarias | BCELoss、BCEWithLogitsLoss |
| Reconstrucción de texto | CrossEntropyLoss |
| VAE | MSE + KL Divergence |
| Detección de anomalías | MSE、MAE |
8.3 Selección de la dimensión latente
数据维度低(<100维)
-> 潜在维度设为 2~10
数据维度中等(100~1000维)
-> 潜在维度设为 10~50
数据维度高(>1000维)
-> 潜在维度设为 50~200
生成任务(VAE)
-> 潜在维度 2~32(便于采样和可视化)
异常检测
-> 潜在维度 16~64(保留足够信息检测异常)
Otras extensiones