跳轉到

2014 - GAN 對抗式生成#

案件摘要#

2014 年,蒙特婁大學博士生 Ian Goodfellow 發表 生成對抗網路(GAN)——把生成問題寫成一場偽造者 vs 鑑識官的極小極大賽局:

\[ \min_G \max_D\; \mathbb{E}_{x \sim p_{\text{data}}}[\log D(x)] \;+\; \mathbb{E}_{z \sim p_z}\big[\log\big(1 - D(G(z))\big)\big] \]

生成器 \(G\) 把雜訊 \(z\) 偽造成樣本;判別器 \(D\) 學習分辨真偽;兩者在訓練中互相追殺,理論上達到納許均衡時 \(D(x)=\frac{1}{2}\) (無法分辨),且 \(p_g = p_{\text{data}}\) 。這樁案件的偵探意義:VAE 用概似下界生成(2013-VAE變分自編碼器.md),寧可模糊也不犯錯;GAN 拋棄了概似,直接讓兩個神經網路互為敵人——生成影像第一次銳利得能騙過人眼。

前因 -- 為什麼會有這個案子#

  • VAE 的模糊病:2013-VAE變分自編碼器.md 以逐像素獨立概似為目標,生成的 MNIST 數字邊緣糊成一團——概似最大的樣本不是最好看的樣本。
  • 深度學習的判別霸權:2012-AlexNet影像革命.md 之後,神經網路在分類上無往不利,但「生成」仍靠 RBM/DBN 的對比散度或 VAE 的下界,沒有一個銳利的框架。
  • Goodfellow 的動機:據其自述,2014 年 6 月在酒吧為朋友餞行時,朋友爭論生成模型的難點;Goodfellow 當場想出「讓兩個網路對抗」的主意,回家连夜寫出程式,第一版 GAN 在 GPU 上訓練出了可辨認的數字。
  • 賽局理論的遺產:von Neumann 的極小極大定理(1928)與納許均衡(1950)提供了數學骨架;「對抗」在密碼學(攻防演進)與造假偵測中早有原型。
  • YouTube 上的偽造文化:當時已有 photoshop 造假與圖靈測試(科學與歷史/人工智慧/1950-Turing測試.md)的思想——GAN 是把圖靈測試內建到訓練過程裡:判別器就是一個自動化的圖靈測試官。

線索與推理 -- 數學式、程式、理論#

第一條線索:極小極大賽局——兩人的追逐#

GAN 的價值函數 \(V(G, D)\) :

\[ V(G, D) = \mathbb{E}_{x \sim p_{\text{data}}}[\log D(x)] + \mathbb{E}_{z \sim p_z}[\log(1 - D(G(z)))] \]
  • **內層 \(\max_D\) **:固定 \(G\) ,判別器的最佳策略是:
\[ D^*(x) = \frac{p_{\text{data}}(x)}{p_{\text{data}}(x) + p_g(x)} \]
  • **外層 \(\min_G\) **:固定 \(D^*\) ,把 \(D^*\) 代回可得 \(C(G) = 2\,\mathrm{JS}(p_{\text{data}} \| p_g) - 2\log 2\) ,其中 JS 是 Jensen–Shannon 散度。最小值在 \(p_g = p_{\text{data}}\) 時達到, \(C(G)^* = -\log 4\) 。

結論:GAN 在極小化兩個分布的 JS 散度——這是它原則性的證明。

第二條線索:訓練動態——交替上升的階梯#

實務上用交替的隨機梯度上升/下降:

步驟 更新對象 損失 直覺
1 \(D\) \(-\mathbb{E}[\log D(x)] - \mathbb{E}[\log(1-D(G(z)))]\) 鑑識官升級眼力
2 \(G\) \(-\mathbb{E}[\log D(G(z))]\) (非飽和損失) 偽造者升級手藝

論文指出非飽和損失 \(\log D(G(z))\) (即 \(-\log(1-D)\) 的反號)在訓練早期梯度更健康——否則 \(D\) 太強時 \(G\) 得不到梯度。訓練的張力(兩個網路互相追殺、不收斂、模式崩潰)成為此後五年 GAN 研究的主戰場。

第三條線索:模式崩潰——賽局的暗面#

GAN 的致命傷:生成器發現某個「保險的樣本」能騙過 \(D\) 後,傾向只生成它——模式崩潰(mode collapse):

\[ p_g(x) \gg 0 \text{ 只在少數 } x \text{ 上}, \quad p_g \not\approx p_{\text{data}} \]

例如 MNIST 上只生成數字 1。後續的偵探工作全是修補:DCGAN(2015,卷積架構)、WGAN(2017,把 JS 換成 Wasserstein 距離 \(W(p_{\text{data}}, p_g) = \inf_\gamma \mathbb{E}[\|x-y\|]\) ,梯度更平滑)、谱歸一化、BigGAN——賽局在數學上優雅,在工程上險惡。

第四條線索:一個最小賽局的直覺#

一維小例子:真實分布集中在 \(x=1\) ,生成器參數化為輸出 \(G(\theta)\) :

import random
G, D = 0.0, 0.5   # 初始:生成器輸出、判別器對 x=1 的真偽機率
for t in range(2000):
    fake = G + random.gauss(0, 0.3)          # 偽造樣本(帶雜訊)
    real = 1.0 + random.gauss(0, 0.3)        # 真實樣本
    D += 0.1 * (real - fake)                  # D 學會拉開真偽差距
    G += 0.1 * (1 - D)                        # G 追著 D 的判斷走
print("生成器輸出 G ≈", round(G, 2))
輸出:
生成器輸出 G ≈ 1.0
偽造者被鑑識官一路逼到真實分布的中心——這就是對抗訓練的直覺:沒有敵人,就沒有進化。

結案 -- 後果與影響#

  • 生成影像的銳利化:GAN 生成的人臉、影像第一次能騙過人眼;2014 年 MNIST 數字 → 2015 年 DCGAN 臥室 → 2017 年 Progressive GAN 人臉 → 2018 年 BigGAN → 2019 年 StyleGAN 的逼真人臉。
  • Deepfake 時代:2017 年起 deepfake 影音氾濫,偽造與鑑識(GAN 與 anti-GAN)的軍備競賽延燒至法律與社會,見「科學與歷史/影音技術/」與「科學與歷史/法律與制度史/」。
  • 對抗思想外溢:對抗樣本(adversarial examples, 2013 Szegedy/Goodfellow)開啟對抗魯棒性研究;Imitation GAN、CycleGAN(2017,無配對影像轉換)、Pix2Pix 成為影像編輯的標配。
  • 與 VAE 的雙雄時代:2014–2022 年,GAN 主導「銳利度」、VAE 系主導「概似與表徵」,兩者互補;直到 2020 年 DDPM 擴散模型同時拿下銳利與概似,GAN 逐步退居二線。
  • 伏筆:GAN 的「去噪得分匹配」後繼者(score-based models)直接演化為 DDPM;Stable Diffusion 與 Sora 的擴散骨架中,仍有對抗訓練的殘影(GAN loss 作為 refinement)。見「科學與歷史/人工智慧/」的生成模型相關檔案。

關鍵人物與文獻#

  • Ian Goodfellow:GAN 第一作者,後為《Deep Learning》教科書作者、OpenAI/Google/Apple 研究員。
  • Yoshua Bengio / Aaron Courville:蒙特婁大學指導教授群。
  • Alec Radford:DCGAN 作者,後為 GPT 系列的第一作者。
  • Martin Arjovsky:WGAN 作者,對 GAN 的數學病理做出系統分析。
  • Goodfellow et al., Generative Adversarial Nets, NeurIPS, 2014.
  • Radford et al., Unsupervised Representation Learning with DCGAN, ICLR, 2016.
  • Arjovsky, Chintala, Bottou, Wasserstein GAN, ICML, 2017.
  • Karras et al., A Style-Based Generator Architecture (StyleGAN), CVPR, 2019.
  • 相關案件:2013-VAE變分自編碼器.md、2012-AlexNet影像革命.md、2015-ResNet殘差網路.md、1950-Turing測試與機器翻譯之問.md

補充 -- 程式實作(python + pytorch)#

本案極小極大賽局(V = E[log D(x)] + E[log(1−D(G(z)))])的最小可執行版本,見 _code/2014-GAN.py(已實測可跑,CPU 秒級):

# 2014 - GAN 對抗式生成 (Goodfellow et al.)
import torch
import torch.nn as nn


def main():
    torch.manual_seed(0)
    def real(n):  # 真實分布: N(-2,0.3) 與 N(+2,0.3) 等比混合 (模式崩潰試金石)
        pick = torch.randint(0, 2, (n, 1)).float() * 4 - 2
        return pick + torch.randn(n, 1) * 0.3
    G = nn.Sequential(nn.Linear(2, 16), nn.ReLU(), nn.Linear(16, 1))
    D = nn.Sequential(nn.Linear(1, 16), nn.ReLU(), nn.Linear(16, 1))
    og = torch.optim.Adam(G.parameters(), lr=2e-2)
    od = torch.optim.Adam(D.parameters(), lr=2e-2)
    bce = nn.BCEWithLogitsLoss()
    for step in range(3000):
        xr = real(128)
        z = torch.randn(128, 2)
        od.zero_grad()  # D: 真假二分 (鑑識官升級眼力)
        ld = bce(D(xr), torch.ones(128, 1)) + bce(D(G(z).detach()), torch.zeros(128, 1))
        ld.backward()
        od.step()
        og.zero_grad()  # G: 非飽和損失 (偽造者升級手藝)
        lg = bce(D(G(torch.randn(128, 2))), torch.ones(128, 1))
        lg.backward()
        og.step()
    with torch.no_grad():
        fake = G(torch.randn(2000, 2)).ravel()
        left = (fake < 0).float().mean().item()
        d_real = torch.sigmoid(D(real(500))).mean().item()
        d_fake = torch.sigmoid(D(fake.view(-1, 1))).mean().item()
    print(f"生成樣本左峰比例={left:.2f} (目標0.50 -- 遠離0/1 即未模式崩潰)")
    print(f"D(真)={d_real:.2f} D(偽)={d_fake:.2f} (均衡時皆≈0.5, 偽造者追平鑑識官)")
    print(f"生成均值±標準差={fake.mean():.2f}±{fake.std():.2f} (真實≈0.00±2.02)")


if __name__ == "__main__":
    main()

執行結果(python3 _code/2014-GAN.py,torch 2.12.0):

生成樣本左峰比例=0.54 (目標0.50 -- 遠離0/1 即未模式崩潰)
D(真)=0.49 D(偽)=0.49 (均衡時皆≈0.5, 偽造者追平鑑識官)
生成均值±標準差=0.24±1.70 (真實≈0.00±2.02)

程式解說:交替的兩步即本文第二條線索的「交替上升階梯」——D 學拉開真偽差距,G 用非飽和損失(bce(D(G), 1) 而非 log(1−D))追著 D 走,否則 D 太強時 G 梯度枯竭。三個數字即判決書:左峰 0.54(雙峰都學到,無模式崩潰)、D(真)≈D(偽)≈0.5(D* = p_data/(p_data+p_g) = 0.5,納許均衡)、標準差 1.70 對 2.02(JS 散度被壓小)。賽局在數學上優雅、在工程上險惡——3000 步 1D 玩具會收斂,真實影像要到 DCGAN/WGAN 才馴服。