跳轉到

2013 - VAE 變分自編碼器#

案件摘要#

2013 年,Diederik Kingma(阿姆斯特丹大學)與 Max Welling 發表 變分自編碼器(VAE)——第一個端到端可微分的生成模型。它把「生成」寫成貝葉斯推斷:一個編碼器 \(q_\phi(z|x)\) 把影像壓成潛變數 \(z\) 的後驗分布,一個解碼器 \(p_\theta(x|z)\) 從 \(z\) 重建影像,訓練目標是 ELBO:

\[ \log p_\theta(x) \ \ge\ \mathbb{E}_{q_\phi(z|x)}\big[\log p_\theta(x \mid z)\big] \;-\; \mathrm{KL}\big(q_\phi(z \mid x)\,\big\|\,p(z)\big) \]

但貝葉斯後驗的抽樣是隨機的、不可微——Kingma 用重參數化技巧破解:

\[ z = \mu_\phi(x) + \sigma_\phi(x) \odot \epsilon, \qquad \epsilon \sim \mathcal{N}(0, I) \]

隨機性被移出計算圖,梯度得以流動。這樁案件是 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\) :

\[ \log p_\theta(x) = \log \int p_\theta(x \mid z)\, p(z)\, dz \]

這個積分不可解。變分法引入一個近似後驗 \(q_\phi(z|x)\) ,用 Jensen 不等式導出下界(ELBO):

\[ \log p_\theta(x) = \underbrace{\mathbb{E}_{q}\big[\log p_\theta(x \mid z)\big]}_{\text{重建項}} \;-\; \underbrace{\mathrm{KL}\big(q_\phi(z|x)\,\|\,p(z)\big)}_{\text{正則項}} \;+\; \mathrm{KL}\big(q_\phi(z|x)\,\|\,p_\theta(z|x)\big) \ \ge \ \text{ELBO} \]

極大化 ELBO,等於同時逼真重建 + 讓後驗靠近先驗。

第二條線索:重參數化——隨機性搬家#

\(\mathrm{KL}\) 項可解析計算(兩個高斯之間有閉式解),但 \(\mathbb{E}_q[\cdot]\) 需要從 \(q_\phi(z|x)\) 抽樣,而 \(\nabla_\phi\, z \sim \mathcal{N}(\mu_\phi, \sigma_\phi)\) 沒有定義——抽樣不可微。Kingma 的技巧:把隨機性外置成與參數無關的 \(\epsilon\) :

\[ z = \mu_\phi(x) + \sigma_\phi(x) \odot \epsilon,\quad \epsilon \sim \mathcal{N}(0,I) \qquad\Rightarrow\qquad \frac{\partial z}{\partial \phi} = \frac{\partial \mu_\phi}{\partial \phi} + \frac{\partial \sigma_\phi}{\partial \phi}\odot\epsilon \]

同樣的技巧後來被稱為「路徑導數估計」,在強化學習(reparameterized policy gradients)與 2020 年的 DDPM 擴散模型中反覆出現。

第三條線索:閉式解的完整目標#

取 \(p(z) = \mathcal{N}(0, I)\) 、 \(q_\phi(z|x) = \mathcal{N}(\mu, \mathrm{diag}(\sigma^2))\) 、解碼器輸出伯努利或高斯,ELBO 有樣本化的閉式形式:

\[ \mathcal{L}(\theta,\phi;x) = \frac{1}{L}\sum_{l=1}^{L} \log p_\theta\big(x \mid z_l\big) \;-\; \frac{1}{2}\sum_{j=1}^{J}\left(1 + \log \sigma_j^2 - \mu_j^2 - \sigma_j^2\right) \]

每一項都是 \(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)決定潛空間的性質:β 大 → 解糾纏但重建差;β 小 → 重建好但潛空間有洞。而模糊的數學根源在於邊緣概似的幾何:

\[ p_\theta(x) = \int p_\theta(x \mid z)\, p(z)\, dz \]

對逐像素獨立的高斯解碼器,這個積分是「所有 \(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 的張力),正是第五條線索「模糊的根源」。