PyTorch: автоэнкодер
Автоэнкодер (Autoencoder, AE)— это нейронная сеть для обучения без учителя, которая сжимает входные данные в низкоразмерное латентное пространство посредством обучения, а затем восстанавливает исходные данные из сжатого представления.
Автоэнкодеры широко используются в таких сценариях, как снижение размерности данных, извлечение признаков, обнаружение аномалий, шумоподавление изображений и генеративные модели.
1. Основные принципы автоэнкодера
Базовая структура автоэнкодера состоит из трёх частей:
- Энкодер: отображает входные данные \(x\) в низкоразмерное латентное представление \(z\)
- Латентное пространство: низкоразмерный вектор, выдаваемый энкодером, также называемый слоем узкого места
- Декодер: восстанавливает латентное представление \(z\) в выход \(\hat{x}\)
1.1 Структура сети
Цель автоэнкодера — сделать выход \(\hat{x}\) как можно более близким к входу \(x\):
\[ \min_{\theta, \phi} \frac{1}{n} \sum_{i=1}^{n} \| x_i - D_\phi(E_\theta(x_i)) \|^2 \]
где \(\theta\) — параметры энкодера, а \(\phi\) — параметры декодера.
1.2 Эффект снижения размерности
Автоэнкодеры обучаются сжатому представлению данных, пропуская данные через слой узкого места, размер которого меньше размерности входа. Это сжатие сохраняет основную информацию о данных.
По сравнению с методом главных компонент (PCA) автоэнкодеры могут изучать нелинейное снижение размерности и улавливать более сложные структуры данных.
2. Базовая реализация автоэнкодера
2.1 Простой автоэнкодер
Пример
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
# ── Модель автоэнкодера ─────────────────────────────────
class Autoencoder(nn.Module):
"""
Базовый автоэнкодер: симметричная структура
"""
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),
)
def forward(self, x):
z = self.encoder(x)
x_recon = self.decoder(z)
return x_recon
def encode(self, x):
"""Кодирование: получение латентного представления"""
return self.encoder(x)
def decode(self, z):
"""Декодирование: восстановление из латентного представления"""
return self.decoder(z)
# ── Пример использования ──────────────────────────────────────
INPUT_DIM = 784 # Например, после уплощения изображения MNIST
HIDDEN_DIM = 256
LATENT_DIM = 32 # Размерность латентного пространства, намного меньше размерности входа
model = Autoencoder(INPUT_DIM, HIDDEN_DIM, LATENT_DIM)
print(f"Размерность входа: {INPUT_DIM}")
print(f"Размерность латентного пространства: {LATENT_DIM}")
print(f"Коэффициент сжатия: {INPUT_DIM / LATENT_DIM:.1f}x")
# Просмотр количества параметров
total_params = sum(p.numel() for p in model.parameters())
print(f"Всего параметров: {total_params:,}")
2.2 Свёрточный автоэнкодер
Для изображений автокодировщики, использующие свёрточные слои, работают лучше:
Пример
import torch.nn as nn
class ConvAutoencoder(nn.Module):
"""
Свёрточный автокодировщик: подходит для изображений
"""
def __init__(self, channels=3, latent_dim=128):
super().__init__()
# Кодировщик: постепенно уменьшать размер, увеличивать число каналов
# Вход: (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(),
)
# Отображение в латентное пространство
self.to_latent = nn.AdaptiveAvgPool2d((1, 1))
# Декодер: постепенно увеличивать размер
# Вход: (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() # Выход [0, 1]
)
def forward(self, x):
z = self.encode(x)
x_recon = self.decode(z)
return x_recon
def encode(self, x):
"""Кодирование"""
features = self.encoder(x)
z = self.to_latent(features)
z = z.view(z.size(0), -1) # (batch, 256)
return z
def decode(self, z):
"""Декодирование"""
# Преобразовать вектор в карту признаков
batch_size = z.size(0)
z = z.view(batch_size, 256, 1, 1)
z = z.expand(-1, -1, 2, 2) # Апсемплинг до 2x2
x_recon = self.from_latent(z)
return x_recon
#
model = ConvAutoencoder(channels=3, latent_dim=128)
x = torch.randn(4, 3, 64, 64)
x_recon = model(x)
print(f"Форма входа: {x.shape}")
print(f"Форма выхода: {x_recon.shape}")
print(f"Форма латентного вектора: {model.encode(x).shape}")
2.3 Обучение и реконструкция
Пример
import torch.nn as nn
import torch.optim as optim
# ── Конфигурация обучения ─────────────────────────────────────
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)
# ── Цикл обучения ─────────────────────────────────────
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)
# Прямое распространение
outputs = model(images)
loss = criterion(outputs, images)
# Обратное распространение
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
avg_loss = total_loss / len(dataloader)
print(f"Эпоха [{epoch+1}/{num_epochs}], Потеря: {avg_loss:.6f}")
return model
# Предполагается, что загрузчик данных уже существует
# train_autoencoder(model, train_loader, criterion, optimizer, num_epochs=10)
print("Обучение автоэнкодера завершено!")
3. Шумоподавляющий автоэнкодер (DAE)
Шумоподавляющий автоэнкодер (DAE)добавляет шум к входным данным во время обучения, а затем учится удалять шум и восстанавливать исходный вход. Это позволяет модели изучать более устойчивые представления признаков.
3.1 Реализация шумоподавляющего автоэнкодера
Пример
import torch.nn as nn
class DenoisingAutoencoder(nn.Module):
"""
Шумоподавляющий автоэнкодер
"""
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() # Выход [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):
"""
Добавить гауссов шум
"""
noise = torch.randn_like(x) * noise_factor
noisy_x = x + noise
return torch.clamp(noisy_x, 0.0, 1.0)
# Обучение шумоподавляющего автоэнкодера
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]
# Добавить шум
noisy_images = add_noise(images, noise_factor)
noisy_images = noisy_images.to(next(model.parameters()).device)
images = images.to(next(model.parameters()).device)
# Прямое распространение
outputs = model(noisy_images)
loss = criterion(outputs, images) # Сравнить с исходным изображением, а не с зашумлённым
# Обратное распространение
optimizer.zero_grad()
loss.backward()
optimizer.step()
return model
3.2 Другие типы шума
Пример
"""Шум «соль и перец»"""
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):
"""Шум маскирования (случайное обнуление)"""
mask = torch.rand_like(x) > prob
return x * mask.float()
def dropout_noise(x, rate=0.2):
"""Шум dropout"""
mask = torch.rand_like(x) > rate
return x * mask.float() / (1 - rate)
4. Вариационный автоэнкодер (VAE)
Вариационный автоэнкодер (VAE)— это генеративная модель, которая кодирует данные в распределение вероятностей в латентном пространстве, а не в фиксированный вектор. Это позволяет нам производить выборку из латентного пространства для генерации новых данных.
4.1 Основные принципы VAE
Ключевое нововведение VAE заключается в изучении распределения вероятностей латентных переменных:
- Энкодер выводит среднее \(\mu\) и стандартное отклонение \(\sigma\)
- Выполните выборку латентного вектора \(z\) из нормального распределения \(\mathcal{N}(\mu, \sigma)\)
- Декодер восстанавливает данные из \(z\)
Чтобы получить дифференцируемый процесс выборки, используетсятрюк репараметризации.:
\[ z = \mu + \sigma \cdot \epsilon, \quad \epsilon \sim \mathcal{N}(0, 1) \]
4.2 Реализация VAE
Пример
import torch.nn as nn
import torch.optim as optim
class VAE(nn.Module):
"""
Вариационный автоэнкодер
"""
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(),
)
self.fc_mu = nn.Linear(hidden_dim, latent_dim)
self.fc_logvar = 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()
)
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):
"""Трюк репараметризации"""
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):
"""
Функция потерь VAE
Потеря восстановления + KL-дивергенция
"""
# Потеря восстановления
recon_loss = nn.functional.mse_loss(x_recon, x, reduction='sum')
# 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
# Пример использования
INPUT_DIM = 784
HIDDEN_DIM = 256
LATENT_DIM = 2 # Двумерное латентное пространство для удобной визуализации
model = VAE(INPUT_DIM, HIDDEN_DIM, LATENT_DIM)
#
x = torch.randn(32, 784)
x_recon, mu, logvar = model(x)
print(f"Форма входа: {x.shape}")
print(f"Форма восстановления: {x_recon.shape}")
print(f"Форма среднего: {mu.shape}") # (32, 2)
print(f"Форма дисперсии: {logvar.shape}") # (32, 2)
4.3 Генерация и визуализация VAE
Пример
def visualize_latent_space(model, dataloader, device):
"""Визуализация латентного пространства"""
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('Латентное измерение 1')
plt.ylabel('Латентное измерение 2')
plt.title('Латентное пространство VAE')
plt.show()
def generate_from_latent(model, z, device):
"""Генерация изображений из латентных векторов"""
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):
"""Генерация интерполяции латентного пространства"""
model.eval()
# Линейная интерполяция
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)
# Генерация новых изображений
def generate_new_images(model, num_images, latent_dim, device):
"""Генерация новых изображений из случайных латентных векторов"""
model.eval()
with torch.no_grad():
# Выборка из стандартного нормального распределения
z = torch.randn(num_images, latent_dim).to(device)
generated = model.decode(z)
return generated
Латентное пространство VAE непрерывно, что позволяет выполнять интерполяцию в латентном пространстве для генерации плавно изменяющихся изображений. Однако изображения, генерируемые VAE, часто получаются размытыми, потому что VAE оптимизирует нижнюю границу, а не точное логарифмическое правдоподобие.
5. Разреженный автоэнкодер
Разреженный автоэнкодерДобавьте ограничение разреженности в функцию потерь, ограничивая количество активаций в латентном векторе. Это позволяет модели изучать более осмысленные признаки.
5.1 Реализация разреженного автоэнкодера
import torch.nn as nn
import torch.nn.functional as F
class SparseAutoencoder(nn.Module):
"""
Разреженный автоэнкодер
"""
def __init__(self, input_dim, hidden_dim, latent_dim):
super().__init__()
# Энкодер
self.encoder = nn.Sequential(
nn.Linear(input_dim, hidden_dim),
nn.ReLU(),
)
# Латентный слой
self.bottleneck = nn.Linear(hidden_dim, latent_dim)
# Декодер
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) # Разреженная активация
x_recon = self.decoder(z_activated)
return x_recon, z_activated
def sparse_loss(z, rho=0.05, beta=1.0):
"""
Разреженная потеря: KL-дивергенция
rho: целевая разреженность (например, 0.05 означает, что только 5% нейронов должны быть активны)
beta: вес члена разреженности
"""
# Вычислить среднюю активацию
rho_hat = torch.mean(z, dim=0)
# 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):
"""Общая потеря = потеря реконструкции + потеря разреженности"""
recon_loss = F.mse_loss(x_recon, x)
sparsity = sparse_loss(z, rho, beta)
return recon_loss + sparsity
6. Автоэнкодер последовательность-в-последовательность
Для последовательных данных (таких как текст, временные ряды) используйте RNN/LSTM в качестве энкодера и декодера.
6.1 Реализация автоэнкодера последовательностей
Пример
import torch.nn as nn
class Seq2SeqAutoencoder(nn.Module):
"""
Автоэнкодер «последовательность-в-последовательность»: используется для последовательных данных
"""
def __init__(self, input_size, hidden_size, latent_size, num_layers=2):
super().__init__()
# LSTM-энкодер
self.encoder = nn.LSTM(
input_size=input_size,
hidden_size=hidden_size,
num_layers=num_layers,
batch_first=True,
bidirectional=True
)
# Отображение в латентное пространство
# Выход двунаправленного LSTM равен hidden_size * 2
self.to_latent = nn.Linear(hidden_size * 2, latent_size)
self.from_latent = nn.Linear(latent_size, hidden_size * 2)
# LSTM декодера
self.decoder = nn.LSTM(
input_size=hidden_size,
hidden_size=hidden_size,
num_layers=num_layers,
batch_first=True,
bidirectional=True
)
# Отображение выхода
self.output_proj = nn.Linear(hidden_size * 2, input_size)
def forward(self, x):
# Кодирование
_, (h_n, _) = self.encoder(x)
# Объединить финальные скрытые состояния двунаправленной сети
# 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)
# Преобразовать в латентное пространство
z = self.to_latent(h_combined)
# Преобразовать обратно из латентного пространства
decoder_init = self.from_latent(z)
decoder_init = decoder_init.view(2, decoder_init.size(0), -1) # (2, batch, hidden_size*2)
# Декодировать (используя исходную длину входных данных)
decoder_output, _ = self.decoder(
x,
(decoder_init, torch.zeros_like(decoder_init))
)
# Отображение выхода
output = self.output_proj(decoder_output)
return output, z
# Пример использования
model = Seq2SeqAutoencoder(
input_size=128, # Размерность входных признаков
hidden_size=256, # Размерность скрытого состояния LSTM
latent_size=64, # Размерность латентного пространства
num_layers=2
)
#
x = torch.randn(8, 20, 128) # (batch, seq_len, input_size)
output, z = model(x)
print(f"Форма входа: {x.shape}") # (8, 20, 128)
print(f"Форма вывода: {output.shape}") # (8, 20, 128)
print(f"Форма латентного вектора: {z.shape}") # (8, 64)
7. Сценарии применения автоэнкодеров
7.1 Обнаружение аномалий
Автоэнкодеры можно использовать для обнаружения аномальных данных. У нормальных данных небольшая ошибка реконструкции, а у аномальных данных большая ошибка реконструкции:
Пример
import torch.nn as nn
def detect_anomalies(model, data_loader, threshold=None, device='cpu'):
"""
Обнаружение аномалий с помощью автоэнкодеров
"""
model.eval()
reconstruction_errors = []
with torch.no_grad():
for batch in data_loader:
images = batch[0].to(device)
outputs = model(images)
# Вычислить ошибку реконструкции (среднеквадратичная ошибка)
errors = torch.mean((outputs - images) ** 2, dim=(1, 2, 3))
reconstruction_errors.extend(errors.cpu().numpy())
reconstruction_errors = torch.tensor(reconstruction_errors)
# Если порог не задан, используйте статистический метод
if threshold is None:
# Использовать 95% процентиль
threshold = torch.quantile(reconstruction_errors, 0.95).item()
# Пометить аномалии
anomalies = reconstruction_errors > threshold
return anomalies, reconstruction_errors, threshold
# Обучение модели обнаружения аномалий
def train_anomaly_detector(normal_data_loader):
"""Обучение автоэнкодера только на нормальных данных"""
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 Колоризация изображений и перенос стиля
Пример
"""
Автоэнкодер для колоризации изображений
Вход: изображение в оттенках серого (batch, 1, H, W)
Выход: цветное изображение (batch, 2, H, W) (цветовое пространство ab)
"""
def __init__(self):
super().__init__()
# Энкодер: постепенно извлекает признаки
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(),
)
# Декодер: повышающая дискретизация для генерации цветов
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), # Выходные ab-каналы
nn.Sigmoid() # диапазон ab-каналов [0, 1]
)
def forward(self, x):
z = self.encoder(x)
color = self.decoder(z)
return color
7.3 Визуализация снижения размерности данных
Пример
def visualize_latent_2d(model, dataloader, device, num_samples=1000):
"""
Использование автоэнкодера для снижения размерности данных до 2 измерений для визуализации
"""
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)
# Если это 2D AE, используйте напрямую
# Если размерность выше, сначала спроецируйте в 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('Латентное измерение 1')
plt.ylabel('Латентное измерение 2')
plt.title('Визуализация 2D латентного пространства автоэнкодера')
plt.show()
8. Краткий справочник по API
8.1 Распространённые типы автоэнкодеров
| Type | Характеристики | Применимые сценарии |
|---|---|---|
| Базовый автоэнкодер | Простая симметричная структура | Снижение размерности, извлечение признаков |
| Свёрточный автоэнкодер | Использует свёрточные слои для сохранения пространственной структуры | Обработка изображений |
| Шумоподавляющий автоэнкодер | Учится удалять шум | Шумоподавление изображений, устойчивые признаки |
| Вариационный автоэнкодер | Изучает вероятностные распределения, может генерировать новые данные | Генеративные модели, генерация данных |
| Разреженный автоэнкодер | Ограничение разреженности, изучает интерпретируемые признаки | Разделение признаков, интерпретируемость |
| Автоэнкодер последовательностей | Использует RNN/LSTM для обработки последовательностей | Текст, временные ряды |
8.2 Выбор функции потерь
| Задача | Рекомендуемая функция потерь |
|---|---|
| Реконструкция изображений | MSELoss、SSIMLoss |
| Бинарные изображения | BCELoss、BCEWithLogitsLoss |
| Реконструкция текста | CrossEntropyLoss |
| VAE | MSE + KL-дивергенция |
| Обнаружение аномалий | MSE、MAE |
8.3 Выбор латентной размерности
数据维度低(<100维)
-> 潜在维度设为 2~10
数据维度中等(100~1000维)
-> 潜在维度设为 10~50
数据维度高(>1000维)
-> 潜在维度设为 50~200
生成任务(VAE)
-> 潜在维度 2~32(便于采样和可视化)
异常检测
-> 潜在维度 16~64(保留足够信息检测异常)
Другие расширения