基础 · 08

GAN 与扩散模型

两代生成模型的核心直觉:GAN 用对抗博弈让生成器骗过判别器;扩散模型把生成拆成逐步去噪——更稳、更多样、质量更高。

14 min read

GAN:对抗博弈生成

自编码器通过「压缩再重建」学到了数据的低维表示,VAE 更进一步让瓶颈服从先验分布从而能随机采样生成。但 2014 年 Goodfellow 提出了一种截然不同的思路——不需要显式的编码器,不需要重建损失,只需要两个网络互相博弈

这就是 GAN(Generative Adversarial Network)。核心思想极其直觉:

  • 生成器 GG:从随机噪声 zpz\mathbf{z} \sim p_z 生成假样本 G(z)G(\mathbf{z}),目标是「骗过判别器」。
  • 判别器 DD:接收真样本 x\mathbf{x} 或假样本 G(z)G(\mathbf{z}),输出一个概率 D()[0,1]D(\cdot) \in [0, 1],判断输入是真还是假。

类比:GG 是造假画家,DD 是鉴定师。造假画家不断提升技艺,鉴定师不断提升鉴别力——两者在对抗中共同进步,直到假画和真画分不开。

对抗训练与目标函数

GAN 的训练是一个 minimax 博弈。目标函数:

minGmaxD  V(D,G)=Expdata[logD(x)]+Ezpz[log(1D(G(z)))]\min_G \max_D \; V(D, G) = \mathbb{E}_{\mathbf{x} \sim p_{\text{data}}}[\log D(\mathbf{x})] + \mathbb{E}_{\mathbf{z} \sim p_z}[\log(1 - D(G(\mathbf{z})))]

拆开看两部分:

  • E[logD(x)]\mathbb{E}[\log D(\mathbf{x})]:判别器看到真数据时希望输出高(接近 1),取 log 后尽量大。
  • E[log(1D(G(z)))]\mathbb{E}[\log(1 - D(G(\mathbf{z})))]:判别器看到假数据时希望输出低(D(G(z))0D(G(\mathbf{z})) \to 0),所以 log(1D)0\log(1 - D) \to 0 最大化。

训练过程是交替优化:

  1. 固定 GG,优化 DD:让 DD 更准确地区分真假。
  2. 固定 DD,优化 GG:让 GG 生成的样本骗过当前的 DD(最小化 VV)。

理论结果:当 GG 达到最优时,pG=pdatap_G = p_{\text{data}},判别器对所有输入输出 12\frac{1}{2}——彻底分不出真假。

GAN 的训练困难

GAN 的想法优美,但训练出了名地困难。三大核心问题:

模式坍塌(Mode Collapse):生成器找到几个能骗过判别器的「安全模式」后,就只生成这几种样本,忽略数据分布的其他部分。比如在人脸生成中只产出几张类似的面孔。

梯度消失:如果判别器太强(DD 一眼就看出假的),log(1D(G(z)))\log(1 - D(G(\mathbf{z}))) 饱和在接近 log1=0\log 1 = 0 的位置,生成器收不到有意义的梯度——不知道往哪个方向改进。

训练不稳定GGDD 的能力需要同步增长。一方太强则另一方崩溃,训练过程振荡甚至发散。实践中需要精心调节学习率、网络容量、训练比例。

后续工作(WGAN、Spectral Normalization、StyleGAN 等)大量精力花在稳定训练上——但问题从未彻底消失。这正是扩散模型兴起的背景。

扩散模型:前向加噪

扩散模型(Diffusion Model)的核心直觉完全不同:

把「生成」拆成很多很小的去噪步骤——每一步只做一点点事,但叠加起来就能从纯噪声变出真实数据。

前向过程(Forward / Diffusion Process) 是一条固定的马尔可夫链,逐步往数据上加高斯噪声:

q(xtxt1)=N(xt;  1βtxt1,  βtI)q(\mathbf{x}_t | \mathbf{x}_{t-1}) = \mathcal{N}(\mathbf{x}_t;\; \sqrt{1 - \beta_t}\, \mathbf{x}_{t-1},\; \beta_t \mathbf{I})

其中 β1,β2,,βT\beta_1, \beta_2, \ldots, \beta_T 是预设的噪声调度(schedule)。经过 TT 步后,xT\mathbf{x}_T 几乎是标准高斯噪声。

一个关键性质:可以直接从 x0\mathbf{x}_0 跳到任意 xt\mathbf{x}_t(不用逐步算):

q(xtx0)=N(xt;  αˉtx0,  (1αˉt)I)q(\mathbf{x}_t | \mathbf{x}_0) = \mathcal{N}(\mathbf{x}_t;\; \sqrt{\bar\alpha_t}\, \mathbf{x}_0,\; (1 - \bar\alpha_t)\mathbf{I})

其中 αˉt=s=1t(1βs)\bar\alpha_t = \prod_{s=1}^{t}(1 - \beta_s)。这让训练可以直接随机采一个 tt,不用跑完整条链。

下面可以拖动滑块观察前向和反向过程:

噪声 0%
t=0t=20
x₀ — 原始数据σ(t)
原始分布 x₀拖动滑块观察纯噪声 x_T
扩散的前向过程逐步加噪把数据变为高斯噪声;反向过程学习去噪,从噪声中恢复数据结构。 点击 Forward / Reverse 或拖动滑块观察。

反向去噪与训练目标

反向过程(Reverse Process) 是我们要学的:从 xTN(0,I)\mathbf{x}_T \sim \mathcal{N}(0, \mathbf{I}) 逐步去噪回 x0\mathbf{x}_0。参数化为:

pθ(xt1xt)=N(xt1;  μθ(xt,t),  σt2I)p_\theta(\mathbf{x}_{t-1} | \mathbf{x}_t) = \mathcal{N}(\mathbf{x}_{t-1};\; \boldsymbol{\mu}_\theta(\mathbf{x}_t, t),\; \sigma_t^2 \mathbf{I})

DDPM(Ho et al. 2020)的关键简化:不直接预测均值 μ\boldsymbol{\mu},而是预测噪声 ϵ\boldsymbol{\epsilon}。网络 ϵθ(xt,t)\boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) 的训练目标:

Lsimple=Et,x0,ϵ[ϵϵθ(xt,t)2]\mathcal{L}_{\text{simple}} = \mathbb{E}_{t,\, \mathbf{x}_0,\, \boldsymbol{\epsilon}} \left[ \| \boldsymbol{\epsilon} - \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) \|^2 \right]

翻译成人话:随机采一个时间步 tt,往 x0\mathbf{x}_0 加噪声 ϵ\boldsymbol{\epsilon} 得到 xt\mathbf{x}_t,让网络猜「加了什么噪声」——猜对就行。这个损失极其简洁,训练稳定。

采样时从 xTN(0,I)\mathbf{x}_T \sim \mathcal{N}(0, \mathbf{I}) 开始,逐步用网络预测噪声并减去:

xt1=1αt(xtβt1αˉtϵθ(xt,t))+σtz\mathbf{x}_{t-1} = \frac{1}{\sqrt{\alpha_t}} \left( \mathbf{x}_t - \frac{\beta_t}{\sqrt{1 - \bar\alpha_t}} \boldsymbol{\epsilon}_\theta(\mathbf{x}_t, t) \right) + \sigma_t \mathbf{z}

每一步只去掉一点噪声,TT 步后得到干净的生成样本。

扩散 vs GAN

维度GAN扩散模型
训练方式对抗博弈(minimax)去噪回归(MSE)
训练稳定性困难,需精心调参稳定,损失单调下降
生成质量高(尤其 StyleGAN)更高(FID 更优)
多样性易模式坍塌天然覆盖全部模式
采样速度极快(一次前向)慢(需 TT 步迭代)
可控性需额外条件机制天然支持 classifier-free guidance

扩散模型的主要代价是采样慢——需要数十到数百步迭代。后续工作(DDIM、DPM-Solver、Consistency Model、蒸馏)都在解决这个问题,已经把步数压到 1-4 步。

这个想法在前沿里