Ainsteinx Logo
Ainsteinx
👤
欢迎使用 Ainsteinx
登录

切换语言

货币

首页
博客
服务
第 03 课 · 六大核心方法

变分自编码器(VAE)

把图像压缩成潜在空间中的点,再从随机点画出新图像。

自编码器由编码器(把图像压缩成小向量,即潜在表示)和解码器(还原图像)组成。但它的潜在空间有空隙,随机采样的效果很差。

VAE 的解决办法是让编码器输出一个分布(μ, σ),并用 KL 散度把它拉向 N(0, I)。训练后只需从 N(0, I) 采样 z 再解码,就能得到新图像。示例用字符画出一个新的 8×8 数字。

z = μ + σ · ε, ε ~ N(0, I) ← reparameterization trick loss = reconstruction(x, x̂) + β · KL( N(μ, σ²) ‖ N(0, I) ) KL = −½ Σ (1 + log σ² − μ² − σ²)
重建损失让重建图像接近原图
KL 损失让潜在空间连续无空洞,从而可以采样

要点

  • VAE = 自编码器 + 随机性 + KL
  • 潜在向量可以做运算,例如 人脸 + “眼镜” = 戴眼镜的人脸
generative-ai-ep03-vae.py
import torch, torch.nn as nn
from sklearn.datasets import load_digits

torch.manual_seed(0)
X = torch.tensor(load_digits().data / 16.0, dtype=torch.float32)   # 8x8 digits

class VAE(nn.Module):
    def __init__(self, z=2):
        super().__init__()
        self.enc = nn.Sequential(nn.Linear(64, 128), nn.ReLU(), nn.Linear(128, 2 * z))
        self.dec = nn.Sequential(nn.Linear(z, 128), nn.ReLU(), nn.Linear(128, 64), nn.Sigmoid())

    def forward(self, x):
        mu, logvar = self.enc(x).chunk(2, dim=1)
        z = mu + torch.randn_like(mu) * torch.exp(0.5 * logvar)    # reparameterization trick
        return self.dec(z), mu, logvar

vae = VAE()
opt = torch.optim.Adam(vae.parameters(), lr=1e-3)
for epoch in range(200):
    recon, mu, logvar = vae(X)
    rec = nn.functional.binary_cross_entropy(recon, X, reduction="sum") / len(X)
    kl = -0.5 * torch.sum(1 + logvar - mu ** 2 - logvar.exp()) / len(X)
    loss = rec + kl
    opt.zero_grad(); loss.backward(); opt.step()
    if epoch % 50 == 49:
        print(f"epoch {epoch + 1}  reconstruction {rec.item():.1f}  KL {kl.item():.2f}")

# Generate: decode random points from N(0, I)
with torch.no_grad():
    sample = vae.dec(torch.randn(1, 2)).view(8, 8)
for row in sample:
    print("".join(" .:-=+*#%@"[int(v * 9.99)] for v in row))

输出结果

epoch 50  reconstruction 29.1  KL 1.31
epoch 100  reconstruction 27.7  KL 0.97
epoch 150  reconstruction 26.7  KL 1.09
epoch 200  reconstruction 25.5  KL 1.42
..=%#+..
 :%*+#:.
.:#:-#..
..+=+#: 
 .: :#:.
  .  *-.
  +-=#-.
..-%%+..
  • #GenerativeAI
  • #DeepLearning
  • #PythonສຳລັບຄົນLaos
  • #AI
  • #ບອກຕໍ່ຄວາມຮູ້