VAE 基础【选修】
本节定位
如果说 GAN 是通过“真假对抗”来学分布,
VAE 更像另一条思路:
先把数据压到一个连续潜空间,再从这个潜空间采样并重建回来。
它没有 GAN 那种强对抗味,但它对“潜空间”这件事讲得更清楚,也更适合建立生成模型的结构直觉。
学习目标
- 理解编码器、潜变量、解码器三者关系
- 理解为什么 VAE 要学“分布”而不是单点编码
- 通过可运行示例建立潜空间采样直觉
- 理解 VAE 和普通自编码器的差别
一、VAE 到底在做什么?
1.1 普通自编码器更像压缩与重建
它会做:
- 输入 -> 压缩表示 -> 重建输出
1.2 VAE 更进一步
VAE 不只是学一个固定潜向量,
而是学:
- 一个潜在分布
例如:
- 均值
mu - 方差
sigma
这样模型就不只是会“记住怎么重建”,
还更像会:
- 在潜空间里采样
- 再生成新样本
1.3 一个类比
普通自编码器像给每张图分配一个固定抽屉。
VAE 更像给它分配一个“可波动的小区域”,这样你在附近采样也还能生成合理样本。
二、为什么 VAE 特别强调潜空间?
2.1 因为生成的关键是“能不能从空间里采样”
如果潜表示是完全离散、零散、不连续的,
你很难在里面平滑采样并得到合理结果。
2.2 VAE 想让潜空间更规整
所以它会鼓励潜变量分布更接近一个规则先验,
通常是:
- 标准正态分布
这也是为什么 VAE 的潜空间通常更适合:
- 插值
- 采样
- 生成
三、先跑一个最小潜空间采样示例
这个例子会用最小形式演示:
- 编码器给出
mu和sigma - 从中采样
z - 解码器根据
z生成输出
import math
import random
random.seed(42)
def encoder(x):
# 极简示意:输入 x 对应一个均值和标准差
mu = x * 0.5
sigma = 0.3 + x * 0.1
return mu, sigma
def sample_z(mu, sigma):
epsilon = random.gauss(0, 1)
return mu + sigma * epsilon
def decoder(z):
# 极简示意:把潜变量映射回“生成值”
return round(z * 2, 3)
x = 1.2
mu, sigma = encoder(x)
samples = [decoder(sample_z(mu, sigma)) for _ in range(5)]
print("mu:", round(mu, 3))
print("sigma:", round(sigma, 3))
print("generated samples:", samples)
3.1 这个例子最重要的地方是什么?
它清楚体现了 VAE 的关键特点:
- 同一个输入不只对应一个固定点
- 而是对应一个可采样的分布
3.2 为什么这比普通自编码器更有生成意味?
因为你可以从潜空间附近采样出多个不同但相关的结果。
这让模型不仅能重建,还能生成变体。
四、VAE 和 GAN 的直觉差别是什么?
4.1 VAE
更强调:
- 潜空间结构
- 分布建模
- 平滑采样
4.2 GAN
更强调:
- 对抗训练
- 样本真假判断
- 生成样本逼真度
4.3 所以它们适合拿来理解的重点不同
- 学潜空间和概率生成直觉,VAE 很好
- 学对抗式生成和训练不稳问题,GAN 很好
五、VAE 最容易踩的坑
5.1 误区一:VAE 就是普通自编码器加点随机数
不对。
它最关键的变化是:
- 学分布
- 让潜空间可采样
5.2 误区二:重建清晰就说明潜空间一定好
不一定。
潜空间是否规整、是否平滑,同样重要。
5.3 误区三:VAE 只适合图像
它也可以用于:
- 文本潜表示
- 表格生成
- 表示学习
小结
这节最重要的是建立一个清楚判断:
VAE 的核心价值在于学出一个连续、可采样的潜空间,让模型不仅能重建输入,还能在潜空间里做生成和插值。
只要这个直觉建立起来,后面很多生成模型结构你都会更容易看懂。
练习
- 把示例里的
x改成不同值,看看生成样本分布如何变化。 - 为什么说 VAE 更强调“潜空间结构”,而不只是“重建是否准确”?
- 用自己的话解释:VAE 和普通自编码器最大的差别是什么?
- 想一想:如果你想研究“样本在潜空间里如何平滑变化”,为什么 VAE 会是不错入口?