2013 - VAE 變分自編碼器#
案件摘要#
2013 年,Diederik Kingma(阿姆斯特丹大學)與 Max Welling 發表 變分自編碼器(VAE)——第一個端到端可微分的生成模型。它把「生成」寫成貝葉斯推斷:一個編碼器 \(q_\phi(z|x)\) 把影像壓成潛變數 \(z\) 的後驗分布,一個解碼器 \(p_\theta(x|z)\) 從 \(z\) 重建影像,訓練目標是 ELBO:
但貝葉斯後驗的抽樣是隨機的、不可微——Kingma 用重參數化技巧破解:
隨機性被移出計算圖,梯度得以流動。這樁案件是 2012-AlexNet影像革命.md 之後,「可微分」哲學向生成模型的第一步遠征。
前因 -- 為什麼會有這個案子#
- 變分貝葉斯的傳統:1990 年代 Jordan 等人的變分近似(mean-field)能近似後驗,但只適用共軛指數族——對神經網路的非線性後驗無能為力。
- 2006-欣頓深度信念網路.md:深度信念網路(DBN)是當時唯一的深層生成模型,但訓練靠逐層受限玻茲曼機(RBM)的對比散度,迂迴、緩慢、難以擴張。
- 自動編碼器的老問題:普通自編碼器(壓縮→重建)學到的潛空間是不連續的空洞——在兩個訓練影像的潛編碼之間插值,解碼出來是雜訊。我們需要一個連續、可採樣的潛空間。
- Hinton 的追問:DBN 能「生成」但生成品質模糊;學界需要一個原則性的、可反向傳播的生成框架。
- 2012 年的風向:AlexNet 證明反向傳播 + GPU 的威力(2012-AlexNet影像革命.md),「能不能用同樣的武器做生成」成為最迫切的問題。
線索與推理 -- 數學式、程式、理論#
第一條線索:生成模型的貝葉斯骨架#
假設資料由隱變數生成: \(z \sim p(z)\) , \(x \sim p_\theta(x|z)\) 。真實的對數概似需邊緣化所有 \(z\) :
這個積分不可解。變分法引入一個近似後驗 \(q_\phi(z|x)\) ,用 Jensen 不等式導出下界(ELBO):
極大化 ELBO,等於同時逼真重建 + 讓後驗靠近先驗。
第二條線索:重參數化——隨機性搬家#
\(\mathrm{KL}\) 項可解析計算(兩個高斯之間有閉式解),但 \(\mathbb{E}_q[\cdot]\) 需要從 \(q_\phi(z|x)\) 抽樣,而 \(\nabla_\phi\, z \sim \mathcal{N}(\mu_\phi, \sigma_\phi)\) 沒有定義——抽樣不可微。Kingma 的技巧:把隨機性外置成與參數無關的 \(\epsilon\) :
同樣的技巧後來被稱為「路徑導數估計」,在強化學習(reparameterized policy gradients)與 2020 年的 DDPM 擴散模型中反覆出現。
第三條線索:閉式解的完整目標#
取 \(p(z) = \mathcal{N}(0, I)\) 、 \(q_\phi(z|x) = \mathcal{N}(\mu, \mathrm{diag}(\sigma^2))\) 、解碼器輸出伯努利或高斯,ELBO 有樣本化的閉式形式:
每一項都是 \(z = \mu + \sigma \odot \epsilon\) 的可微函數——整個目標可以一口氣用反向傳播訓練。這在 2013 年是概念性的突破:生成模型第一次被寫成單一可微目標。
第四條線索:潛空間的幾何——插值與算術#
VAE 的 KL 正則把潛空間壓成連續的高斯團塊,帶來兩個可檢驗的性質:
| 性質 | 檢驗方法 | 結果 |
|---|---|---|
| 連續插值 | 在兩張 MNIST 數字的 \(\mu\) 之間線性插值 \(z\) | 平滑過渡的手寫數字,無雜訊 |
| 可採樣性 | \(z \sim \mathcal{N}(0,I)\) 直接解碼 | 似真但模糊的新樣本 |
| 潛方向 | 改變單一潛維度 | 筆畫粗細、傾斜角度等可解讀變化 |
第五條線索:ELBO 兩項的張力——模糊的根源#
ELBO 的兩項互相拉扯,這是理解 VAE 行為的鑰匙: - 重建項 \(\mathbb{E}_q[\log p_\theta(x|z)]\) :要求解碼器精確重建,推動潛編碼攜帶更多細節。 - 正則項 \(\mathrm{KL}(q_\phi(z|x) \| p(z))\) :要求後驗貼近 \(\mathcal{N}(0,I)\) ,推動潛編碼變得平滑、過度壓縮。
兩者的平衡係數(後來的 β-VAE)決定潛空間的性質:β 大 → 解糾纏但重建差;β 小 → 重建好但潛空間有洞。而模糊的數學根源在於邊緣概似的幾何:
對逐像素獨立的高斯解碼器,這個積分是「所有 \(z\) 下的平均影像」——平均化會把離散的模式(清晰的筆畫)抹成連續的霧(模糊的邊緣)。VAE 極大化的是概似,而概似最大的樣本不是最好看的樣本——這條線索直接指向 GAN 的出場。
結案 -- 後果與影響#
- 生成模型的可微化起點:VAE 證明「貝葉斯推斷 + 反向傳播」可以融為一體;變分推斷從統計學的工具變成深度學習的積木。
- 變分家族擴張:β-VAE(2017,解糾纏表示學習)、VQ-VAE(2017,離散潛空間——後來成為音訊與影像 tokenization 的基礎)、CVAE(條件生成)。
- 與 GAN 的競賽:2014-GAN對抗式生成.md 用極小極大賽局解決了 VAE 的模糊問題,兩者開啟了長達八年的生成模型雙雄時代。
- 伏筆——通向擴散模型:VAE 的「逐像素概似」思想在 2020 年被 DDPM 繼承——擴散模型本質上是「層層嵌套的 VAE」(每一步去噪都是一個條件高斯解碼),其訓練目標正是變分下界的簡化形式;DDPM 擴散最終催生 Stable Diffusion 與 Sora,見「科學與歷史/影音技術/」與「科學與歷史/人工智慧/」的生成模型相關檔案。
- 表示學習:VAE 的潛空間成為「無監督表示學習」的範式,影響了世界模型(World Models, 2018)與強化學習的狀態壓縮。
關鍵人物與文獻#
- Diederik Kingma:第一作者,重參數化技巧的發明者,後為 Adam 優化器共同作者、OpenAI 研究員。
- Max Welling:指導教授,機器學習與貝葉斯深度學習大家。
- Geoffrey Hinton:DBN 與深層生成模型的先驅。
- Kingma & Welling, Auto-Encoding Variational Bayes, ICLR, 2014(arXiv 2013.12).
- Rezende, Mohamed, Wierstra, Stochastic Backpropagation and Approximate Inference in Deep Generative Models, ICML, 2014.
- Kingma & Ba, Adam: A Method for Stochastic Optimization, ICLR, 2015.
- van den Oord et al., Neural Discrete Representation Learning (VQ-VAE), NeurIPS, 2017.
- 相關案件:2006-欣頓深度信念網路.md、2012-AlexNet影像革命.md、2014-GAN對抗式生成.md、2017-Transformer注意力機制.md
補充 -- 程式實作(python + pytorch)#
本案 ELBO+重參數化(z = μ + σ⊙ε)的最小可執行版本,見 _code/2013-VAE.py(已實測可跑,CPU 秒級;以 2D 雙團代替 MNIST):
# 2013 - VAE 變分自編碼器 (Kingma & Welling)
# 公式: ELBO = E_q[log p(x|z)] - KL(q(z|x)||p(z)); z = μ + σ⊙ε
import torch
import torch.nn as nn
class VAE(nn.Module):
def __init__(self, latent=2):
super().__init__()
self.enc = nn.Sequential(nn.Linear(2, 32), nn.Tanh(), nn.Linear(32, 32), nn.Tanh())
self.mu = nn.Linear(32, latent)
self.lv = nn.Linear(32, latent) # log σ²
self.dec = nn.Sequential(nn.Linear(latent, 32), nn.Tanh(), nn.Linear(32, 2))
def forward(self, x):
h = self.enc(x)
mu, lv = self.mu(h), self.lv(h)
z = mu + (0.5 * lv).exp() * torch.randn_like(mu) # 重參數化: 隨機性搬家到 ε
xh = self.dec(z)
recon = ((x - xh) ** 2).sum(1).mean()
kl = -0.5 * (1 + lv - mu ** 2 - lv.exp()).sum(1).mean()
return recon + kl, recon, kl, z, xh
def main():
torch.manual_seed(0)
a = torch.randn(300, 2) * 0.4 + torch.tensor([2.0, 2.0])
b = torch.randn(300, 2) * 0.4 + torch.tensor([-2.0, -2.0])
X = torch.cat([a, b])
net = VAE()
opt = torch.optim.Adam(net.parameters(), lr=1e-2)
for ep in range(300):
opt.zero_grad()
elbo, recon, kl, *_ = net(X)
elbo.backward()
opt.step()
elbo, recon, kl, z, xh = net(X)
print(f"ELBO={elbo.item():.3f} (重建項={recon.item():.3f} + KL項={kl.item():.3f})")
with torch.no_grad():
ma, mb = net.mu(net.enc(a[:1])), net.mu(net.enc(b[:1]))
path = torch.stack([ma[0] * (1 - t) + mb[0] * t for t in torch.linspace(0, 1, 5)])
decoded = net.dec(path)
print("潛插值解碼路徑 (應從[2,2]平滑走到[-2,-2]):")
for p in decoded:
print(f" [{p[0]:.2f}, {p[1]:.2f}]")
with torch.no_grad():
samp = net.dec(torch.randn(4, 2))
print("先驗採樣解碼:", [[round(float(v), 2) for v in s] for s in samp])
if __name__ == "__main__":
main()
執行結果(python3 _code/2013-VAE.py,torch 2.12.0):
ELBO=1.497 (重建項=0.422 + KL項=1.075)
潛插值解碼路徑 (應從[2,2]平滑走到[-2,-2]):
[2.03, 2.00]
[1.28, 1.27]
[-0.49, -0.50]
[-1.73, -1.73]
[-2.06, -2.04]
先驗採樣解碼: [[-1.61, -1.62], [1.45, 1.45], [1.48, 1.47], [2.08, 2.07]]
程式解說:z = mu + (0.5*lv).exp() * randn 即本文第二條線索的重參數化——隨機性外置到與參數無關的 ε,梯度得以流進 μ, σ,整個 ELBO 一口氣反向傳播(2013 年「生成模型第一次被寫成單一可微目標」)。潛插值五步從 [2.03,2.00] 平滑走到 [-2.06,-2.04],中途無雜訊——KL 正則把潛空間壓成連續團塊,普通自編碼器在此會掉進空洞。先驗採樣四點全落在兩團之內:可採樣性成立,代價是模糊(重建項 0.422 的張力),正是第五條線索「模糊的根源」。