基本信息

项目 内容
论文标题 Auto-Encoding Variational Bayes
作者 Diederik P. Kingma 和 Max Welling
作者单位
发表会议/期刊 2013
论文链接
别名 Variational Autoencoder,变分自编码器

方法概览

特点 文章性质
输入 单张 RGB 图像
输出 分类、分割
所属领域 视觉 Transformer

背景

传统自编码器 (Autoencoder) 的局限,比如PCA:

  • 传统AE由编码器(Encoder)和解码器(Decoder)组成。
  • 编码器将输入数据 x 压缩成一个低维的潜在向量 z
  • 解码器尝试从 z 重构回原始数据 x
  • PCA:x本身是一个矩阵,通过一个变换W变成了一个低维矩阵c,因为这一过程是线性的,所以再通过一个WT变换就能还原出一个x ^ \widehat{x} x ,现在我们要找到一种变换W,使得矩阵x与x ^ \widehat{x} 能够尽可能地一致,在PCA中找这个变换W用到的方法是SVD(奇异值分解)算法
  • 学习到的潜在空间 z 可能是不连续、不规则的。例如,两个在潜在空间中很接近的点 z1 和 z2,解码后可能产生完全无关的输出。这使得直接从潜在空间采样生成新数据变得困难且不可控

创新点

    • VAE 不再让编码器输出一个确定的点 z,而是输出一个概率分布(通常是高斯分布)的参数(均值 μ 和方差 σ²)。它强制这个潜在空间 z 遵循一个简单的先验分布(通常是标准正态分布 N(0, I))。通过优化一个下界(ELBO),VAE 学习一个既能良好重构数据,又能使潜在空间平滑、连续的模型。这样,你就可以从标准正态分布中采样 z,然后用解码器生成新的、合理的数据。

怎么使用VAE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import torch
import torch.nn as nn
import torch.nn.functional as F

class VAE(nn.Module):
def __init__(self, input_dim=784, hidden_dim=400, latent_dim=20):
super(VAE, self).__init__()
self.input_dim = input_dim
self.hidden_dim = hidden_dim
self.latent_dim = latent_dim

# 编码器 (Encoder)
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.fc21 = nn.Linear(hidden_dim, latent_dim) # 均值 μ
self.fc22 = nn.Linear(hidden_dim, latent_dim) # 对数方差 log(σ²)

# 解码器 (Decoder)
self.fc3 = nn.Linear(latent_dim, hidden_dim)
self.fc4 = nn.Linear(hidden_dim, input_dim)

def encode(self, x):
h1 = F.relu(self.fc1(x))
return self.fc21(h1), self.fc22(h1) # μ, log(σ²)

def reparameterize(self, mu, logvar):
std = torch.exp(0.5 * logvar)
eps = torch.randn_like(std) # ε ~ N(0, I)
return mu + eps * std # z = μ + ε * σ

def decode(self, z):
h3 = F.relu(self.fc3(z))
return torch.sigmoid(self.fc4(h3)) # 假设输入是[0,1]归一化的图像

def forward(self, x):
mu, logvar = self.encode(x.view(-1, self.input_dim)) # 展平图像
z = self.reparameterize(mu, logvar)
return self.decode(z), mu, logvar

# 实例化模型
model = VAE(input_dim=784, hidden_dim=400, latent_dim=20) # 例如,用于28x28的MNIST图像
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# VAE的损失函数由两部分组成:
def vae_loss(recon_x, x, mu, logvar):
"""
recon_x: 重构后的数据
x: 原始输入数据
mu, logvar: 编码器输出的均值和对数方差
"""
# 1. 重构损失: 使用二值交叉熵 (适用于[0,1]归一化的图像)
# 注意: sum(-log(p(x|z))),这里用BCELoss
BCE = F.binary_cross_entropy(recon_x, x.view(-1, 784), reduction='sum')

# 2. KL散度损失: D_KL(q(z|x) || p(z)) = -0.5 * sum(1 + log(σ²) - μ² - σ²)
# 其中 σ² = exp(logvar)
KLD = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp())

return BCE + KLD # 最小化这个总损失

自编码器历史

  1. Autoencoder
  2. Denoising Autoencoder:在输入数据中引入噪声,然后训练网络恢复原始未受扰动的数据。这个过程迫使网络学习更为鲁棒的数据表示,忽略随机噪声,从而提高模型对输入数据中噪声或缺失值的容忍度。
  3. Sparse Autoencoder:在隐藏层上应用“稀疏”约束以防止过拟合并增强模型的鲁棒性。该模型通过限制隐藏层中同时激活的神经元数量,强制使大部分神经元大多数时间处于非激活状态。
  4. K-Sparse Autoencoder:由Makhzani和Frey于2013年提出
  5. Contractive Autoencoder:收缩自编码器在损失函数中加入额外的项来鼓励模型在被压缩的空间中学习更稳健的表示。

之后向VAE(Variational Autoencoder)转变:不是将输入直接映射到一个固定的向量,而是将输入映射到一个概率分布上。
6. Conditional VAE:通过引入额外的条件变量来控制生成过程。
7. Beta-VAE:2017年提出。其核心目标是发现解耦或分解的潜在因子。
8. VQ-VAE:由van den Oord等人于2017年提出,潜在空间的离散化,这种离散化使得模型能够有效地处理和生成高度结构化的数据。
9. VQ-VAE-2:由Ali Razavi等人于2019年提出,是VQ-VAE的升级版。它引入了一个层次化的结构
10. 时间序列数据的TD-VAE

VAE

这里有一个非常好的解释为什么要做变分的自编码器:【VAE学习笔记】全面通透地理解VAE(Variational Auto Encoder)_vae架构-CSDN博客