PyTorch オートエンコーダー (Autoencoder)
オートエンコーダー(Autoencoder,AE)は、入力データを低次元の潜在空間に圧縮し、その圧縮表現から元のデータを再構成することを学習する、教師なし学習のニューラルネットワークです。
オートエンコーダーは、データの次元削減、特徴抽出、異常検知、画像ノイズ除去、生成モデルなどのシーンで広く利用されています。
1. オートエンコーダーの基本原理
オートエンコーダーの基本構造は3つの部分で構成されます:
- エンコーダー(Encoder):入力データ \(x\) を低次元の潜在表現 \(z\) にマッピングします
- 潜在空間(Latent Space):エンコーダーが出力する低次元ベクトルで、ボトルネック層とも呼ばれます
- デコーダー(Decoder):潜在表現 \(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):
"""デコード"""
# ベクトルを特徴マップに reshape
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 [{epoch+1}/{num_epochs}], Loss: {avg_loss:.6f}")
return model
# データローダーが既にあると仮定
# train_autoencoder(model, train_loader, criterion, optimizer, num_epochs=10)
print(オートエンコーダーのトレーニングが完了しました!)
3. デノイジングオートエンコーダー (DAE)
デノイジングオートエンコーダー(Denoising Autoencoder,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)
変分オートエンコーダー(Variational Autoencoder,VAE)は生成モデルであり、データを固定ベクトルではなく潜在空間内の確率分布としてエンコードします。これにより、潜在空間からサンプリングして新しいデータを生成できます。
4.1 VAEの核心原理
VAEの重要な革新は、潜在変数の確率分布を学習することです:
- エンコーダーは平均 \(\mu\) と標準偏差 \(\sigma\) を出力します
- 正規分布 \(\mathcal{N}(\mu, \sigma)\) からサンプリングして潜在ベクトル \(z\) を取得します
- デコーダーは \(z\) からデータを再構成します
微分可能なサンプリングプロセスを実現するために、次が使用されます:再パラメータ化トリック(Reparameterization Trick):
\[ 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 # 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('Latent Dimension 1')
plt.ylabel('Latent Dimension 2')
plt.title('VAE Latent Space')
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が生成する画像は通常ぼやけます。これは、正確な対数尤度ではなく下界を最適化しているためです。
5. スパースオートエンコーダー
スパースオートエンコーダ(Sparse Autoencoder)損失関数にスパース性制約を追加し、潜在ベクトルの活性化数を制限します。これにより、モデルはより意味のある特徴を学習できます。
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('Latent Dimension 1')
plt.ylabel('Latent Dimension 2')
plt.title('Autoencoder 2D Latent Space Visualization')
plt.show()
8. APIクイックリファレンス
8.1 一般的なオートエンコーダーの種類
| 種類 | 特徴 | 適用シーン |
|---|---|---|
| 基本オートエンコーダ | シンプルな対称構造 | 次元削減、特徴抽出 |
| 畳み込みオートエンコーダ | 畳み込み層を使用して空間構造を保持 | 画像処理 |
| デノイジングオートエンコーダ | ノイズ除去を学習 | 画像のノイズ除去、ロバストな特徴 |
| 変分オートエンコーダ | 確率分布を学習し、新しいデータを生成可能 | 生成モデル、データ生成 |
| スパースオートエンコーダ | スパース制約、解釈可能な特徴を学習 | 特徴の分離、解釈可能性 |
| シーケンスオートエンコーダ | RNN/LSTMを使用してシーケンスを処理 | テキスト、時系列 |
8.2 損失関数の選択
| タスク | 推奨損失関数 |
|---|---|
| 画像再構築 | MSELoss、SSIMLoss |
| 二値画像 | BCELoss、BCEWithLogitsLoss |
| テキスト再構築 | CrossEntropyLoss |
| VAE | MSE + KL Divergence |
| 異常検知 | MSE、MAE |
8.3 潜在次元の選択
数据维度低(<100维)
-> 潜在维度设为 2~10
数据维度中等(100~1000维)
-> 潜在维度设为 10~50
数据维度高(>1000维)
-> 潜在维度设为 50~200
生成任务(VAE)
-> 潜在维度 2~32(便于采样和可视化)
异常检测
-> 潜在维度 16~64(保留足够信息检测异常)
その他の拡張