Lecture 9 · 生成对抗网络(一):两样本检验与 GAN · Generative Adversarial Networks I

Deep Generative Models · Lecture 09。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应 Maps to:Stanford CS236 Deep Generative Models(Fall 2023,Stefano Ermon),Lecture 9 · 2023-10-25 · Generative Adversarial Networks(slides:cs236_lecture9.pdf,26 页);课程笔记 Generative Adversarial Networks。 依据说明:本讲按原课 slides 的顺序展开:回顾(三个似然家族都在最小化 KL)→ 为什么用最大似然 → 似然与样本质量的三种关系(Theis et al. 2016)→ 用样本比较分布:两样本检验 → 用判别器做检验统计量、最优判别器 → GAN 的极小极大博弈 → V(G,D∗)=2 JSD−log⁡4V(G, D^*) = 2\,\mathrm{JSD} - \log 4 与 JSD 的性质 → GAN 小结 → 训练算法与交替优化 → 前沿与困难:优化不稳定、模式坍塌、评估 → “美在判别器的眼中”。置换检验、分类器两样本检验(C2ST)、非饱和生成器损失的梯度分析、“生成器恰好可逆时精确地看 GAN 在做什么”(Flow-GAN)、PacGAN是本讲义补充的。所有实验的真实分布都已知,所以”似然”和”样本质量”可以分别精确地量。 配套代码 Code:code/lecture09/(PyTorch;1 个模块 + 4 个演示脚本,最长的约 85 秒) 预计阅读时间:3 小时(含运行代码)


0. 本讲导航 · How to read this lecture

0.1 学习目标 Learning goals

学完这一讲,你应该能够:

  1. 举出”似然好、样本差”和”样本好、似然差”的例子,说明为什么在高维里 log⁡100\log 100 这样的差距会被淹没,以及为什么要把似然和样本质量分开考虑。
  2. 说清两样本检验的框架(H0H_0、检验统计量、拒绝域),解释手工统计量为什么在高维里不够用,以及”训练一个分类器当检验统计量”的想法。
  3. 推导最优判别器 D∗(x)=pdata(x)pdata(x)+pG(x)D^*(x) = \frac{p_{\text{data}}(x)}{p_{\text{data}}(x) + p_G(x)},以及判别器最优时 GAN 的目标等于 2 DJSD(pdata,pG)−log⁡42\,D_{\mathrm{JSD}}(p_{\text{data}}, p_G) - \log 4;说出 JSD 的四条性质。
  4. 写出 GAN 的交替训练算法,解释原始生成器损失 log⁡(1−D(G(z)))\log(1 - D(G(z))) 为什么会饱和、非饱和损失 −log⁡D(G(z))-\log D(G(z)) 为什么能缓解它。
  5. 描述 GAN 的三个实际困难——优化不稳定、模式坍塌、评估——并能用一个二维例子复现模式坍塌、解释它为什么会发生。
  6. 理解 GAN 和最大似然在”犯什么样的错误”上的区别:JSD 偏向抓住部分模式,KL 偏向盖住所有模式。

0.2 先修与本讲范围 Prerequisites & scope

默认你已经会 Assumed本讲只给直觉,后面几讲再展开 Previewed only
第 4 讲:KL 散度、最大似然 = 最小化 DKL(pdata∥pθ)D_{\mathrm{KL}}(p_{\text{data}} \Vert p_\theta)、前向 / 反向 KLff-散度、Wasserstein 距离、BiGAN、CycleGAN(第 10 讲)
第 1 讲代码 05:用分类器比较两个分布噪声对比估计——“用分类器训练能量模型”(第 12 讲)
第 7–8 讲:流模型(本讲会把一个 RealNVP 当作生成器)生成模型的系统评估:FID、精度 / 召回(第 15 讲)
二分类的交叉熵损失、逻辑回归

0.3 本讲地图 Map

§1  回顾:三个似然家族都在最小化 KL;为什么用最大似然
§2  似然 ≠ 样本质量:噪声混合、背诵训练集、"只输出一张图"                          ← 代码 01
§3  用样本比较分布:两样本检验;判别器当检验统计量;最优判别器 D*                     ← 代码 02
§4  GAN:极小极大目标;V(G, D*) = 2·JSD − log 4;JSD 偏向抓住部分模式                ← 代码 03 第 1 部分
§5  训练算法:交替优化;饱和与非饱和损失                                            ← 代码 03 第 2 部分
§6  三个困难:优化不稳定(没有停止准则)、模式坍塌、评估                               ← 代码 03 第 3 部分、代码 04
§7  美在判别器的眼中
§8  2023 年之后
§9–13  小结、常见误区、练习、延伸阅读、下一讲预告

0.4 记号 Notation

符号含义
pdatap_{\text{data}},pGp_G(或 pθp_\theta)数据分布;生成器隐式定义的分布
Gθ:z↦xG_\theta: z \mapsto x,p(z)p(z)生成器(确定性函数)与简单先验(通常 N(0,I)\mathcal{N}(0, I))
Dϕ(x)∈(0,1)D_\phi(x) \in (0, 1),ℓϕ(x)\ell_\phi(x)判别器:”xx 是真实数据”的概率;它的 logit,D=σ(ℓ)D = \sigma(\ell)
V(G,D)V(G, D)Epdata[log⁡D(x)]+EpG[log⁡(1−D(x))]\mathbb{E}_{p_{\text{data}}}[\log D(x)] + \mathbb{E}_{p_G}[\log(1 - D(x))]
DG∗D^*_G给定生成器时的最优判别器
DJSD(p,q)D_{\mathrm{JSD}}(p, q)Jensen–Shannon 散度 12DKL(p∥m)+12DKL(q∥m)\frac12 D_{\mathrm{KL}}(p \Vert m) + \frac12 D_{\mathrm{KL}}(q \Vert m),m=p+q2m = \frac{p+q}{2}
H0H_0,H1H_1,T(S1,S2)T(S_1, S_2)零假设 P=QP = Q、备择假设 P≠QP \neq Q、检验统计量

0.5 关于数字 · About the numbers

  • 代码 01 在第 1 讲的像素世界(8×8 黑白图,真实分布精确已知)上做,bit 都是”每张图”的 bit,真实分布的测试集熵约 25.5 bit。
  • 代码 02–04 在二维 / 一维玩具分布上做(第 5 讲的 toy2d.py),真实密度精确已知;JSD、KL 的单位是 nat。GAN 本身没有密度,所以除非生成器恰好是一个流(代码 03 第 3 部分)或一个高斯(代码 03 第 1 部分),我们只能用样本评估它:盖住的模式数、高质量样本比例、分类器两样本检验。
  • GAN 的结果对随机种子和超参数很敏感,代码里所有数字都来自固定种子的单次运行(04 的第 3 部分是 3 个种子);几处和预想不同的结果记录在 代码 README 的”关于实验结果”里。

1. 回顾:三个似然家族 · Recap: likelihood-based models

原课 slide 2 把到目前为止的模型族列在一起:

  • 自回归模型:pθ(x)=∏i=1npθ(xi∣x<i)p_\theta(x) = \prod_{i=1}^n p_\theta(x_i \mid x_{<i})(第 3 讲);
  • 变分自编码器:pθ(x)=∫pθ(x,z) dzp_\theta(x) = \int p_\theta(x, z)\,dz(第 5–6 讲);
  • 归一化流:pX(x;θ)=pZ(fθ−1(x))∣det⁡∂fθ−1(x)∂x∣p_X(x; \theta) = p_Z(f_\theta^{-1}(x))\left|\det\frac{\partial f_\theta^{-1}(x)}{\partial x}\right|(第 7–8 讲)。

它们都通过最小化 DKL(pdata∥pθ)D_{\mathrm{KL}}(p_{\text{data}} \Vert p_\theta) 训练,也就是最大化似然(或者它的近似,比如 ELBO)。

1.1 为什么用最大似然?

slide 3 给了两条理由:

  1. 最优的统计效率。 假设模型容量足够、存在唯一的 θ∗\theta^* 使 pθ∗=pdatap_{\theta^*} = p_{\text{data}},那么当样本数 M→∞M \to \infty 时,最大似然估计 θ^\hat\theta 收敛到 θ∗\theta^* 的速度是所有统计方法里”最快的”。(严格的说法是渐近有效性:M(θ^−θ∗)\sqrt{M}(\hat\theta - \theta^*) 趋于正态分布,协方差等于 Fisher 信息的逆,达到 Cramér–Rao 下界——没有别的无偏估计能有更小的渐近方差。)
  2. 似然越高 = 无损压缩越好。 −log⁡2pθ(x)-\log_2 p_\theta(x) 就是用这个模型给 xx 编码需要的 bit 数(第 4 讲 §3)。

然后是本讲的问题:似然是样本质量的好指标吗? 如果我们真正关心的是”生成的图像看起来好不好”,那么最大化似然是不是在优化正确的东西?


2. 似然 ≠ 样本质量 · Likelihood vs. sample quality

2.1 三种情况

slides 4–6 引用了 Theis, van den Oord & Bethge(2016)A note on the evaluation of generative models:

  • Case 1:最优的生成模型(pθ=pdatap_\theta = p_{\text{data}})样本质量最好、测试似然也最高。问题出在不完美的模型上:对它们来说,高似然不一定意味着好样本,反之亦然。
  • Case 2:似然很好,样本很差。 噪声混合模型 pθ(x)=0.01 pdata(x)+0.99 pnoise(x).p_\theta(x) = 0.01\,p_{\text{data}}(x) + 0.99\,p_{\text{noise}}(x). 99% 的样本都是噪声。可是取对数后有一个下界: log⁡pθ(x)=log⁡[0.01 pdata(x)+0.99 pnoise(x)]≥log⁡0.01 pdata(x)=log⁡pdata(x)−log⁡100.\log p_\theta(x) = \log[0.01\,p_{\text{data}}(x) + 0.99\,p_{\text{noise}}(x)] \geq \log 0.01\,p_{\text{data}}(x) = \log p_{\text{data}}(x) - \log 100. 对期望,下界 Epdata[log⁡pθ]≥Epdata[log⁡pdata]−log⁡100\mathbb{E}_{p_{\text{data}}}[\log p_\theta] \geq \mathbb{E}_{p_{\text{data}}}[\log p_{\text{data}}] - \log 100;上界来自 KL 非负,Epdata[log⁡pdata]≥Epdata[log⁡pθ]\mathbb{E}_{p_{\text{data}}}[\log p_{\text{data}}] \geq \mathbb{E}_{p_{\text{data}}}[\log p_\theta]。随着维数 nn 增加,∣log⁡pdata(x)∣=∣∑i=1nlog⁡p(xi∣x<i)∣|\log p_{\text{data}}(x)| = |\sum_{i=1}^n \log p(x_i \mid x_{<i})| 正比于 nn 增长,而 log⁡100\log 100 是常数——在很高的维数里,这个模型的似然几乎和真实分布一样好。
  • Case 3:样本很好,似然很差。 背诵训练集:样本和训练集一模一样(不能更好了),测试集被赋予零概率(不能更差了)。

slide 6 的结论:这些例子说明,把似然和样本质量分开考虑是有用的。 “不依赖似然的学习”(likelihood-free learning)考虑不直接依赖似然函数的训练目标。

2.2 在一个知道真相的世界里量一量

真实世界里我们没法同时量这两样东西:数据的真实密度是未知的。像素世界(第 1 讲)里两样都能精确算:

  • 似然 = 测试集上的 −log⁡2pθ(x)-\log_2 p_\theta(x),报告”比真实分布多几 bit”;
  • 样本质量 = 模型样本在真实分布下的平均 −log⁡2pdata(x)-\log_2 p_{\text{data}}(x)(真实分布自己的样本约 25.4 bit),以及”像样的样本”比例(离 177 个合法模板之一不超过 6 个像素)。

代码 01 第 1 部分(2,000 个样本):

模型测试 bits(比真实多)样本 −log⁡2pdata-\log_2 p_{\text{data}}像样的样本不同样本数
真实分布(Case 1)+0.0025.496.5%1,979
GRU 自回归(第 3 讲)+0.8329.185.0%1,980
VAE dz=8d_z = 8(第 6 讲)+2.2132.180.2%1,998
独立像素(第 1 讲)+9.9842.334.5%2,000
0.01·真实 + 0.99·噪声(Case 2)+6.64119.21.2%2,000
背诵训练集(Case 3)∞25.696.1%1,786
只输出最可能的那张图∞11.8100%1
  • 噪声混合比真实分布只多 log⁡2100=6.64\log_2 100 = 6.64 bit——比独立像素模型好——可它的样本 99% 是雪花点。按似然排,它排在独立像素前面;按样本质量排,它是最后一名。
  • 背诵训练集:样本就是训练图(在真实分布下和真实样本一样典型),测试图里只有 4.9% 恰好在训练集里出现过,其余的概率是 0,测试似然是 −∞-\infty。
  • 最后一行是一个警告:如果只看”样本在真实分布下有多典型”,一个永远只输出同一张最可能的图(一条横线)的模型得分最高(11.8 bit,比真实样本还”典型”),可它的多样性是 1。样本质量本身也要分成保真度和多样性两个方面——这正是后面 GAN 的模式坍塌问题(§6.3),第 15 讲会用”精度 / 召回”把它们正式分开。

2.3 维数越高,log⁡100\log 100 越不起眼

代码 01 第 2 部分把 kk 张独立的像素世界图拼成一张 64k64k 维的大图,比较真实分布和噪声混合:

kk维数真实 bits噪声混合 bits差相对差
16425.932.66.64425.6%
161,024409.1415.76.6441.6%
25616,3846,554.06,560.76.6440.10%

差值始终是 6.644 bit(slide 5 的下界几乎是紧的:pdata(x)≫2−64kp_{\text{data}}(x) \gg 2^{-64k},噪声项可以忽略),而真实的 bits 随维数线性增长。按 bits/维 排名,这个”99% 样本都是噪声”的模型和真实分布在第三位小数上才分得开。一张 256×256 的彩色图有约 20 万维——你可以想象这个论证在 ImageNet 上意味着什么。

2.4 一个旋钮,两个最优点

代码 01 第 3 部分给”背诵”加一点模糊:pδ(x)=1N∑n∏i[δ 若 xi≠xi(n),否则 1−δ]p_\delta(x) = \frac1N\sum_n \prod_i[\delta \text{ 若 } x_i \neq x^{(n)}_i \text{,否则 } 1 - \delta]——每张训练图周围放一个”随机翻转”的核(离散版本的核密度估计)。

δ\delta训练 bits(比真实多)测试 bits(比真实多)样本 −log⁡2pdata-\log_2 p_{\text{data}}像样的样本
0−12.47∞25.795.8%
0.001−12.38+14.2425.796.6%
0.03−9.68+3.1232.479.4%
0.05−7.78+2.8137.160.0%
0.2+7.73+11.2869.80.6%
  • δ→0\delta \to 0:训练集似然比真实分布还好 12 bit(完全过拟合),样本最”真”;
  • 测试似然在 δ≈0.05\delta \approx 0.05 最好(+2.81 bit,和第 6 讲的 VAE 差不多),这时 40% 的样本已经不像样了。

按似然挑模型和按样本挑模型会挑出不同的 δ\delta。 这就是本讲的出发点:如果我们在乎的是样本,也许应该换一个训练目标。

思考:这是不是说”似然没用”?不是。似然仍然是唯一一个对整个分布负责的指标——背诵、模式坍塌、只输出一张图,这些”样本看起来很好”的病态模型都会被似然无情地揭穿。问题在于两个指标衡量的是不同的东西,而对不完美的模型,它们可以给出不同的排名。


3. 用样本比较分布:两样本检验 · Two-sample tests

3.1 换一个”距离”

slide 7:三个似然家族都选 d(pdata∥pθ)=DKLd(p_{\text{data}} \Vert p_\theta) = D_{\mathrm{KL}}。今天:换一个 dd。 什么样的 dd 只需要样本?

slide 8:给两组有限的样本 S1={x∼P}S_1 = \{x \sim P\}、S2={x∼Q}S_2 = \{x \sim Q\},怎样判断它们是不是来自同一个分布(P=QP = Q)?

3.2 两样本检验

slide 9:两样本检验考虑两个假设——

  • 零假设 H0H_0:P=QP = Q;
  • 备择假设 H1H_1:P≠QP \neq Q。

检验统计量 TT 比较 S1S_1 和 S2S_2,例如均值之差、方差之差: T(S1,S2)=∥1∣S1∣∑x∈S1x−1∣S2∣∑x∈S2x∥.T(S_1, S_2) = \left\|\frac{1}{|S_1|}\sum_{x \in S_1}x - \frac{1}{|S_2|}\sum_{x \in S_2}x\right\|. TT 大于某个阈值就拒绝 H0H_0,否则说 H0H_0 和观测相容。关键观察:检验统计量是 likelihood-free 的——它不涉及密度 PP 或 QQ,只用样本。

阈值怎么定?一个通用的办法是置换检验(本讲义补充):在 H0H_0 下,两组样本的标签可以互换;把 S1∪S2S_1 \cup S_2 随机重新分成两组很多次,每次算一次 TT,实际的 TT 在这些”假分组”里排在前 5% 就拒绝 H0H_0(显著性水平 α=0.05\alpha = 0.05)。它不需要知道 TT 在 H0H_0 下的分布公式。

3.3 生成模型和两样本检验

slide 10:我们手里有 S1=D={x∼pdata}S_1 = \mathcal{D} = \{x \sim p_{\text{data}}\}(训练集),还有一个模型 pθp_\theta。假设模型能高效地采样(比如有向模型),令 S2={x∼pθ}S_2 = \{x \sim p_\theta\}。另一种分布之间的”距离”:训练生成模型,让两样本检验的目标在 S1S_1、S2S_2 之间变小——让检验分不出来。

3.4 在高维里,好的检验统计量很难设计

slide 11:在高维里找一个好的两样本检验目标很难。均值、方差只看前两阶矩;而两个分布可以前两阶矩完全相同、形状却完全不同。代码 02 第 1 部分(PP = 8 个高斯排成一圈;每次各 200 个样本,重复 100 次,α=0.05\alpha = 0.05):

QQ均值检验协方差检验分类器检验分类器平均测试准确率
Q=PQ = P(H0H_0 成立)0.060.090.050.503
PP 平移 0.30.510.021.000.661
同均值同协方差的高斯0.050.011.000.775
PP 旋转 22.5°0.040.091.000.845
每个团更宽(σ\sigma 0.25 → 0.35)0.040.050.400.549

(表里是拒绝 H0H_0 的比例:H0H_0 成立时应该 ≈ 0.05,P≠QP \neq Q 时越接近 1 越好。)

  • 同均值同协方差的高斯和旋转 22.5° 的圆环:均值、协方差检验的拒绝率和 H0H_0 成立时一样——它们根本看不见这种差别。(旋转的圆环和原来的圆环有完全相同的 1–7 阶矩,练习 3。)
  • 连平移——均值检验”设计来看”的差别——分类器也更灵敏(1.00 vs 0.51):0.3 的位移相对整个圆环的散布(每个方向标准差 1.44)很小,相对每个 σ=0.25\sigma = 0.25 的小团却很大。分类器自己找到了”在哪个尺度上看”。

关键想法(slide 11):既然我们知道 S1S_1、S2S_2 来自不同的分布,那就学一个统计量,让它自动找出两组样本在哪方面不同。怎么学?训练一个分类器(称为判别器)!

3.5 判别器当检验统计量

slide 12:任何一个二分类器 DϕD_\phi(比如神经网络),尝试区分数据集里的”真”样本(y=1y = 1)和模型生成的”假”样本(y=0y = 0)。

  • 检验统计量 = 分类器损失的相反数。 损失低 → 真假样本容易区分(不同);损失高 → 难以区分(相似)。
  • 判别器的目标:最大化检验统计量(支持备择假设 pdata≠pθp_{\text{data}} \neq p_\theta),等价地,最小化分类损失。

slide 13:判别器的训练目标—— max⁡DϕV(pθ,Dϕ)=Ex∼pdata[log⁡Dϕ(x)]+Ex∼pθ[log⁡(1−Dϕ(x))]≈∑x∈S1log⁡Dϕ(x)+∑x∈S2log⁡(1−Dϕ(x)).\max_{D_\phi} V(p_\theta, D_\phi) = \mathbb{E}_{x \sim p_{\text{data}}}[\log D_\phi(x)] + \mathbb{E}_{x \sim p_\theta}[\log(1 - D_\phi(x))] \approx \sum_{x \in S_1}\log D_\phi(x) + \sum_{x \in S_2}\log(1 - D_\phi(x)).

对固定的 pθp_\theta,这就是用交叉熵做二分类:给真实数据点(S1S_1)概率 1,给假样本(S2S_2)概率 0。

3.6 最优判别器

Dθ∗(x)=pdata(x)pdata(x)+pθ(x).D^*_\theta(x) = \frac{p_{\text{data}}(x)}{p_{\text{data}}(x) + p_\theta(x)}.

推导(逐点最大化):把期望写成积分, V=∫[pdata(x)log⁡D(x)+pθ(x)log⁡(1−D(x))] dx.V = \int \big[p_{\text{data}}(x)\log D(x) + p_\theta(x)\log(1 - D(x))\big]\,dx. DD 可以在每个 xx 上独立取值,所以只要对每个 xx 最大化被积函数。对 a,b>0a, b > 0,函数 y↦alog⁡y+blog⁡(1−y)y \mapsto a\log y + b\log(1 - y) 在 (0,1)(0, 1) 上的导数是 ay−b1−y\frac{a}{y} - \frac{b}{1-y},在 y=aa+by = \frac{a}{a + b} 处为零,且二阶导数 −ay2−b(1−y)2<0-\frac{a}{y^2} - \frac{b}{(1-y)^2} < 0——唯一的最大值。代入 a=pdata(x)a = p_{\text{data}}(x)、b=pθ(x)b = p_\theta(x) 即得。

检查(slide 13):若 pθ=pdatap_\theta = p_{\text{data}},分类器不可能比瞎猜好:D∗=1/2D^* = 1/2。

换个角度看:D∗1−D∗=pdatapθ\frac{D^*}{1 - D^*} = \frac{p_{\text{data}}}{p_\theta}——最优判别器的 logit 就是对数密度比 log⁡pdata(x)−log⁡pθ(x)\log p_{\text{data}}(x) - \log p_\theta(x)。判别器在不知道任何一个密度的情况下,学到了两个密度的比值。第 10 讲的 ff-GAN 和第 12 讲的噪声对比估计都建立在这个事实上。

3.7 实验:判别器的损失就是 JSD 的估计

§4.2 会证明 max⁡DV=2 DJSD−log⁡4\max_D V = 2\,D_{\mathrm{JSD}} - \log 4。反过来,训练好一个判别器,(V+log⁡4)/2(V + \log 4)/2 就是 JSD 的一个估计。代码 02 第 2 部分(两个密度都已知,所以精确的 JSD 能算出来;判别器 128 × 2,训练 2,000 步,测试集各 20,000 个样本):

分布对精确 JSDn=200n = 200:训练 / 测试n=2,000n = 2{,}000n=20,000n = 20{,}000
同均值同协方差的高斯0.34100.3955 / 0.29270.3352 / 0.33220.3359 / 0.3410
旋转 22.5°0.40210.4476 / 0.34410.3990 / 0.38860.4008 / 0.3966
每个团更宽0.04940.1017 / −0.02400.0597 / 0.03850.0442 / 0.0435
Q=PQ = P00.0605 / −0.05930.0026 / −0.00270.0002 / −0.0001
  • 测试集上的估计不会高于精确值(在误差范围内):任何判别器都满足 V(D)≤V(D∗)V(D) \leq V(D^*),所以 (V+log⁡4)/2(V + \log 4)/2 是 JSD 的变分下界。样本越多、判别器越接近 D∗D^*,下界越紧;n=20,000n = 20{,}000 时第一行恰好碰到精确值。
  • 训练集上的估计在样本少时会高于精确值:判别器记住了那 200 个点。Q=PQ = P 那一行最清楚——真实 JSD 是 0,训练集上却给出 0.06;同一个判别器在新样本上反而比瞎猜还差(估计为负)。“判别器分得开”不一定说明分布不同,也可能只是判别器过拟合了。

代码 02 第 3 部分把学到的 D(x)D(x) 和闭式的 D∗(x)D^*(x) 画成字符图(PP = 圆环,QQ = 同均值同协方差的高斯):两张图几乎一样,8 个团上接近 1、团之间和远处接近 0,平均 ∣D−D∗∣=0.032|D - D^*| = 0.032。判别器”学会了”两个分布差在哪里,而我们从没告诉它 pp 或 qq 的公式。

对 GAN 的启示:生成器真正优化的是判别器给出的这个估计,不是精确的 JSD。判别器的好坏(容量、训练程度、是否过拟合)直接决定生成器收到什么信号——§6 的很多困难都可以追溯到这里。


4. 生成对抗网络 · Generative Adversarial Networks

4.1 生成器:一个隐式模型

slide 14:GAN 是生成器和判别器之间的两人极小极大博弈。

生成器是一个有向的隐变量模型,zz 和 xx 之间是确定性的映射 GθG_\theta:

  • 采样 z∼p(z)z \sim p(z)(简单先验,比如高斯);
  • 令 x=Gθ(z)x = G_\theta(z)。

和流模型很像,但 GθG_\theta 不必可逆——zz 的维数可以比 xx 低,GG 可以把很多 zz 映射到同一个 xx。于是 pθ(x)p_\theta(x) 只被隐式地定义:能采样,但没有似然!生成器最小化两样本检验的目标(支持零假设 pdata=pθp_{\text{data}} = p_\theta)。

为什么”不可逆”是一种自由? 第 7–8 讲花了大量篇幅设计”可逆、雅可比便宜”的网络;GAN 直接扔掉了这个约束:任何网络结构(卷积、转置卷积、Transformer)都定义一个合法的采样器。代价是失去了 pθ(x)p_\theta(x),所以不能用最大似然训练——只能用不需要似然的目标。

4.2 目标与最优判别器下的形式

slide 15: min⁡Gmax⁡DV(G,D)=Ex∼pdata[log⁡D(x)]+Ex∼pG[log⁡(1−D(x))].\min_G \max_D V(G, D) = \mathbb{E}_{x \sim p_{\text{data}}}[\log D(x)] + \mathbb{E}_{x \sim p_G}[\log(1 - D(x))].

把最优判别器 DG∗D^*_G 代进去:

V(G,DG∗)=Epdata[log⁡pdatapdata+pG]+EpG[log⁡pGpdata+pG]=Epdata[log⁡pdatapdata+pG2]+EpG[log⁡pGpdata+pG2]−log⁡4=DKL(pdata ∥ pdata+pG2)+DKL(pG ∥ pdata+pG2)−log⁡4=2 DJSD(pdata,pG)−log⁡4.\begin{aligned} V(G, D^*_G) &= \mathbb{E}_{p_{\text{data}}}\left[\log\frac{p_{\text{data}}}{p_{\text{data}} + p_G}\right] + \mathbb{E}_{p_G}\left[\log\frac{p_G}{p_{\text{data}} + p_G}\right] \\ &= \mathbb{E}_{p_{\text{data}}}\left[\log\frac{p_{\text{data}}}{\frac{p_{\text{data}} + p_G}{2}}\right] + \mathbb{E}_{p_G}\left[\log\frac{p_G}{\frac{p_{\text{data}} + p_G}{2}}\right] - \log 4 \\ &= D_{\mathrm{KL}}\left(p_{\text{data}} \,\Big\Vert\, \tfrac{p_{\text{data}} + p_G}{2}\right) + D_{\mathrm{KL}}\left(p_G \,\Big\Vert\, \tfrac{p_{\text{data}} + p_G}{2}\right) - \log 4 \\ &= 2\,D_{\mathrm{JSD}}(p_{\text{data}}, p_G) - \log 4. \end{aligned}

(第二行:每个分母除以 2,相当于每个 log 里多了 log⁡2\log 2,两项一共 −2log⁡2=−log⁡4-2\log 2 = -\log 4。)在判别器最优的理想条件下,训练生成器 = 最小化 Jensen–Shannon 散度。

4.3 Jensen–Shannon 散度

slide 16:也叫对称 KL 散度, DJSD(p,q)=12(DKL(p ∥ p+q2)+DKL(q ∥ p+q2)).D_{\mathrm{JSD}}(p, q) = \frac12\left(D_{\mathrm{KL}}\left(p \,\Big\Vert\, \tfrac{p+q}{2}\right) + D_{\mathrm{KL}}\left(q \,\Big\Vert\, \tfrac{p+q}{2}\right)\right).

性质:

  • DJSD(p,q)≥0D_{\mathrm{JSD}}(p, q) \geq 0;
  • DJSD(p,q)=0D_{\mathrm{JSD}}(p, q) = 0 当且仅当 p=qp = q;
  • DJSD(p,q)=DJSD(q,p)D_{\mathrm{JSD}}(p, q) = D_{\mathrm{JSD}}(q, p)(对称,KL 不是);
  • DJSD(p,q)\sqrt{D_{\mathrm{JSD}}(p, q)} 满足三角不等式 → Jensen–Shannon 距离(一个真正的度量)。

另外(本讲义补充)它有界:DJSD≤log⁡2D_{\mathrm{JSD}} \leq \log 2,当 pp、qq 的支撑集不相交时取等号(m=(p+q)/2m = (p+q)/2 在 pp 的支撑上等于 p/2p/2,所以 DKL(p∥m)=log⁡2D_{\mathrm{KL}}(p \Vert m) = \log 2)。这个”有界”既是优点(不会像 KL 那样变成 ∞),也是第 10 讲 WGAN 的出发点(支撑集不相交时 JSD 恒为 log⁡2\log 2,没有梯度)。

JSD/负交叉熵 GAN 的最优生成器是 pG=pdatap_G = p_{\text{data}};此时最优判别器 D∗=1/2D^* = 1/2,V(G∗,DG∗∗)=−log⁡4V(G^*, D^*_{G^*}) = -\log 4。

4.4 实验:JSD 偏向”抓住一部分”

最大似然最小化 DKL(pdata∥pθ)D_{\mathrm{KL}}(p_{\text{data}} \Vert p_\theta),GAN(理想情况下)最小化 JSD。当模型族不够大、装不下真实分布时,这两个目标会选出不同的近似。代码 03 第 1 部分用一个最简单的例子:数据是 0.7 N(−2,0.52)+0.3 N(2,0.52)0.7\,\mathcal{N}(-2, 0.5^2) + 0.3\,\mathcal{N}(2, 0.5^2),生成器只能输出一个高斯 x=μ+σzx = \mu + \sigma z。一维里 JSD 可以在细网格上精确积分:

解μ\muσ\sigmaJSD
JSD 的全局最小−2.0000.5040.117
JSD 的局部最小(右边,抓住小模式)2.0000.5040.342
JSD 的局部最小(宽高斯,见下文)−0.841.860.201
最大似然(= 矩匹配)−0.8001.9000.201

JSD 的最低点是只抓住大的那个模式,几乎完美地拟合它、完全放弃小模式;最大似然的解是一个宽高斯,盖住两个模式、把大量质量放在中间没有数据的地方。直觉:DKL(pdata∥pθ)D_{\mathrm{KL}}(p_{\text{data}} \Vert p_\theta) 在 pθ→0p_\theta \to 0 而 pdata>0p_{\text{data}} > 0 的地方趋于无穷——漏掉任何真实数据都是不可接受的,所以它宁可”铺开”;JSD 有界,漏掉 30% 的数据只付出有限的代价,换来在剩下 70% 上的精确拟合(第 4 讲的前向 / 反向 KL 之争,JSD 介于两者之间、更接近反向 KL)。

GAN 训练真的找到了这些解吗?(非饱和损失,判别器 64 × 2,Adam lr = 2e-3,4,000 步;表中是 (μ,σ) ∣ (\mu, \sigma)\,|\,精确 JSD)

初值 (μ,σ)(\mu, \sigma)第 1,000 步第 2,000 步第 3,000 步第 4,000 步
(0,1)(0, 1)−0.58, 1.78 | 0.204−1.04, 1.52 | 0.207−2.01, 0.49 | 0.117−2.00, 0.49 | 0.117
(0,3)(0, 3)−0.66, 1.66 | 0.206−2.00, 0.50 | 0.117−2.01, 0.50 | 0.117−2.00, 0.49 | 0.117
(−3,0.3)(-3, 0.3)−2.03, 0.51 | 0.118−2.00, 0.50 | 0.117−2.01, 0.50 | 0.117−2.00, 0.46 | 0.119
(1.5,0.5)(1.5, 0.5)+1.99, 0.48 | 0.342+1.99, 0.50 | 0.342+1.99, 0.49 | 0.342+1.97, 0.48 | 0.342
  • 从中间出发,GAN 先在”宽高斯”附近徘徊一两千步(JSD ≈ 0.205,和最大似然的解差不多),然后突然”选定”大的模式,落到全局最小。
  • 从 (1.5,0.5)(1.5, 0.5) 出发,它停在小模式上再也出不来——JSD 的地形不是凸的,有局部最优。

一个意外的对照。如果 GAN 真的在最小化 JSD,那么不要判别器、直接对精确的 JSD 做梯度下降,应该得到同样的结果。代码 03 也做了这个实验(步长 0.1,1,200 步):

初值最小化精确 JSD最小化精确的 DKL(pG∥pdata)−2DJSDD_{\mathrm{KL}}(p_G \Vert p_{\text{data}}) - 2D_{\mathrm{JSD}}
(0,1)(0, 1)−0.84, 1.86 | 0.201−2.00, 0.50 | 0.117
(0,3)(0, 3)−0.84, 1.86 | 0.201−2.00, 0.50 | 0.117
(−3,0.3)(-3, 0.3)−2.00, 0.50 | 0.117−2.00, 0.50 | 0.117
(1.5,0.5)(1.5, 0.5)+2.00, 0.50 | 0.342+2.00, 0.50 | 0.342

对精确 JSD 做梯度下降,从中间出发会停在 (−0.84,1.86)(-0.84, 1.86)——宽高斯附近还有第三个局部最小(JSD 0.201,就在最大似然解旁边)。GAN 却没有停在那里。原因是 GAN 实际用的非饱和生成器损失(§5.2)优化的根本不是 JSD:判别器最优时,它的梯度等于 DKL(pG∥pdata)−2DJSD(pdata,pG)D_{\mathrm{KL}}(p_G \Vert p_{\text{data}}) - 2D_{\mathrm{JSD}}(p_{\text{data}}, p_G) 的梯度(Arjovsky & Bottou 2017,第 10 讲推导)。多出来的反向 KL 强烈地偏向”抓住一个模式”,把生成器从宽高斯推了出去。对这个目标做精确的梯度下降,结果和 GAN 一致(表的第三列)。“GAN 最小化 JSD”这句话,即使在判别器最优时也只对原始的 minimax 损失成立。

训练结束时,学到的 DD 和闭式的 D∗D^* 几乎一样:在大模式上都约 0.41(生成器把全部质量放在只占 0.7 的模式上,那里 pG>pdatap_G > p_{\text{data}}),在小模式 x=2x = 2 处都是 1.000——判别器”知道”那里有生成器没覆盖的真实数据,但生成器离得太远,它在 x≈−2x \approx -2 附近感受到的梯度并不指向那里。

4.5 GAN 小结

slide 17:

  • 选 d(pdata,pθ)d(p_{\text{data}}, p_\theta) 为一个两样本检验统计量,通过训练分类器(判别器)学这个统计量;在理想条件下,等价于选 d=DJSDd = D_{\mathrm{JSD}}。
  • 优点:损失只需要 pθp_\theta 的样本,不需要似然!神经网络结构非常灵活,任何 GθG_\theta 都定义一个合法的采样过程;采样快(一次前向)。
  • 缺点:实践中非常难训练。

5. 训练算法 · The GAN training algorithm

5.1 交替的随机梯度

slide 18:

  1. 从 D\mathcal{D} 中抽一个小批量 x(1),…,x(m)x^{(1)}, \dots, x^{(m)};
  2. 从 pzp_z 中抽一个小批量噪声 z(1),…,z(m)z^{(1)}, \dots, z^{(m)};
  3. 用随机梯度上升更新判别器参数 ϕ\phi: ∇ϕV(Gθ,Dϕ)=1m∇ϕ∑i=1m[log⁡Dϕ(x(i))+log⁡(1−Dϕ(Gθ(z(i))))];\nabla_\phi V(G_\theta, D_\phi) = \frac1m\nabla_\phi\sum_{i=1}^m\left[\log D_\phi(x^{(i)}) + \log(1 - D_\phi(G_\theta(z^{(i)})))\right];
  4. 用随机梯度下降更新生成器参数 θ\theta: ∇θV(Gθ,Dϕ)=1m∇θ∑i=1mlog⁡(1−Dϕ(Gθ(z(i))));\nabla_\theta V(G_\theta, D_\phi) = \frac1m\nabla_\theta\sum_{i=1}^m\log(1 - D_\phi(G_\theta(z^{(i)})));
  5. 重复固定的轮数。

注意第 4 步的梯度要穿过判别器流回生成器:∇θlog⁡(1−Dϕ(Gθ(z)))=∂log⁡(1−D)∂x∣x=Gθ(z)∂Gθ(z)∂θ\nabla_\theta \log(1 - D_\phi(G_\theta(z))) = \frac{\partial \log(1 - D)}{\partial x}\Big|_{x = G_\theta(z)}\frac{\partial G_\theta(z)}{\partial \theta}。生成器从判别器那里得到的唯一信息就是”DD 在 xx 空间里往哪个方向增加”——∇xDϕ(x)\nabla_x D_\phi(x)。生成器从来没有直接见过真实数据。

slide 19 是 Goodfellow et al.(2014)那张著名的一维示意图:真实分布(黑点)、生成器分布(绿线)、判别器(蓝虚线)交替更新——判别器先学会在两个分布之间画出 D∗D^* 的形状,生成器顺着 DD 上升的方向把质量移向真实数据,最后两个分布重合、D≡1/2D \equiv 1/2。代码 03 第 1 部分是这张图的”数字版”:每 500 步,判别器以为的 JSD((log⁡4−d_loss)/2(\log 4 - \texttt{d\_loss})/2)都大体跟着精确的 JSD 走(单个小批量有约 ±0.03 的噪声),包括第 2,000 → 2,500 步那次”跳到大模式”。

5.2 饱和与非饱和损失

本讲义补充(Goodfellow et al. 2014 原论文里就有):第 4 步的生成器损失 log⁡(1−D(G(z)))\log(1 - D(G(z))) 有一个实际问题。用 logit 写,D=σ(ℓ)D = \sigma(\ell),log⁡(1−D)=−softplus(ℓ)\log(1 - D) = -\mathrm{softplus}(\ell),对 ℓ\ell 的导数是 −σ(ℓ)=−D-\sigma(\ell) = -D。

  • 训练初期,生成器很差,判别器很容易很自信地识破假样本:D(G(z))≈0D(G(z)) \approx 0,于是导数 ≈0\approx 0——生成器几乎收不到梯度。这叫饱和。
  • 非饱和(non-saturating)损失:改为最小化 −log⁡D(G(z))=softplus(−ℓ)-\log D(G(z)) = \mathrm{softplus}(-\ell),导数是 −(1−D)-(1 - D),在 D(G(z))≈0D(G(z)) \approx 0 时最大。
D(G(z))D(G(z))∣∂/∂ℓ∣\lvert\partial/\partial\ell\rvert,minimax =D= D∣∂/∂ℓ∣\lvert\partial/\partial\ell\rvert,非饱和 =1−D= 1 - D
0.0010.0010.999
0.10.10.9
0.50.50.5

两个损失的不动点相同(都希望 D(G(z))D(G(z)) 变大),但梯度在”生成器很差”时差别巨大。非饱和损失不再是一个严格的零和博弈(它对应的生成器目标不是 −V-V):判别器最优时,它的梯度是 DKL(pG∥pdata)−2DJSDD_{\mathrm{KL}}(p_G \Vert p_{\text{data}}) - 2D_{\mathrm{JSD}} 的梯度(§4.4 的对照实验),第 10 讲会推导这一点。

代码 03 第 2 部分:把生成器固定在初始状态,先单独训练判别器 TT 步,再看两种损失给生成器的梯度(1,000 个样本):

判别器先训练 TT 步平均 D(G(z))D(G(z))∥∇θ∥\lVert\nabla_\theta\rVert minimax∥∇θ∥\lVert\nabla_\theta\rVert 非饱和比值
00.47459.31e-021.03e-011×
3000.02459.37e-023.27e+0035×
1,0000.00161.34e-026.31e+00472×

判别器越自信,minimax 的梯度越小。但从 T=1,000T = 1{,}000 的状态继续用 Adam 训练,两种损失最后都学会了(4,000 步后都盖住 8 个模式、95–97% 高质量样本),minimax 只是在前一两千步慢一些(第 2,000 步高质量样本 76% / 89%,非饱和 93% / 92%)。原因:Adam 按梯度的历史尺度归一化步长,“梯度整体小 472 倍”对它来说只是尺度问题。2014 年的这个建议在今天的优化器下没有那么致命,但非饱和损失仍然是标准做法。(作者试过把生成器换成普通 SGD:minimax 版本数值发散、非饱和版本坍塌到一个模式——结论和优化器紧密相关,所以没有把它放进表里。)


6. 前沿与困难 · Challenges

slide 20 展示两张人脸,问”哪张是真的?“——两张都是 GAN 生成的。slide 21 是 2014–2018 年 GAN 生成人脸的进展(Goodfellow et al. 2014 → DCGAN 2015 → CoGAN 2016 → Progressive GAN 2017 → StyleGAN 2018)。GAN 在很多领域和任务上都很成功,但实际使用非常有挑战性:

  • 优化不稳定(unstable optimization);
  • 模式坍塌(mode collapse);
  • 评估(evaluation)。

需要一大堆技巧(bag of tricks)才能训练成功。

6.1 优化:理论保证的假设不现实

slide 22:定理(非正式):如果生成器的更新是在函数空间里做的,并且判别器每一步都是最优的,那么生成器保证收敛到数据分布。

这两条假设都不现实:生成器是一个参数化的网络,更新在参数空间里;判别器每一步只更新一两次梯度,远不是最优的。实践中,生成器和判别器的损失一直在振荡;也没有可靠的停止准则(不像最大似然,验证集似然不再下降就可以停)。

为了精确地看到这一点,代码 03 第 3 部分用了一个技巧:让生成器恰好是一个流(8 层 RealNVP,第 8 讲)。GAN 训练完全不用它的密度——对 GAN 来说它就是一个普通的 z↦xz \mapsto x 网络——但我们在旁边可以精确地算 JSD 和两个方向的 KL(Flow-GAN,Grover, Dhar & Ermon 2018)。数据是双月牙:

步数d_loss判别器以为的 JSD精确 JSDDKL(pdata∥pG)D_{\mathrm{KL}}(p_{\text{data}} \Vert p_G)DKL(pG∥pdata)D_{\mathrm{KL}}(p_G \Vert p_{\text{data}})
1,0001.357+0.0140.1393.51.127
2,0001.382+0.0020.313233.41.386
4,0001.384+0.0010.279131.41.178
6,0001.392−0.0030.389473.81.789
  • 判别器的损失一直停在 log⁡4≈1.386\log 4 \approx 1.386 附近——“判别器以为的 JSD”≈ 0——而精确的 JSD 在 0.14 到 0.39 之间起伏,并且第 1,000 步最好、之后反而变差。只看损失,你既不知道它在变好还是变坏,也不知道该在哪里停。
  • 和 §4.4 的一维例子对比:那里判别器比生成器强得多,它的损失是 JSD 的不错估计;这里两者”势均力敌”,判别器始终追不上 D∗D^*,它的损失就不再反映 JSD。

最终比较(同一个 RealNVP,2 万个样本):

DKL(pdata∥pG)D_{\mathrm{KL}}(p_{\text{data}} \Vert p_G)DKL(pG∥pdata)D_{\mathrm{KL}}(p_G \Vert p_{\text{data}})精确 JSDlog 密度比真实低 10 nat 以上的数据点新分类器准确率
最大似然训练(3,000 步)0.0230.0400.00690.0%0.507
GAN 训练(6,000 步)488.11.7600.39761.6%0.806

GAN 训练的流把密度挤在一些细细的曲线上(代码输出的第二张密度图),61.6% 的真实数据点在它看来几乎不可能——前向 KL 是几百 nat。一个训练到收敛的新分类器能把它的样本和真实样本分开(准确率 0.806),而最大似然训练的流分不开(0.507)。在这个二维例子里,同一个网络用最大似然训练,按样本看也更好。GAN 的优势出现在”似然和样本质量不一致”的高维数据上(§2);Flow-GAN 论文在图像上观察到的正是这个:对抗训练的流样本更清晰,似然却差很多。

6.2 模式坍塌

slide 23:GAN 以模式坍塌闻名:生成器坍缩到一个或少数几个样本(称为”模式”)上。

slide 24 是 Metz et al.(2017,Unrolled GANs)的图:真实分布是排成一圈的 8 个高斯,生成器的分布在不同模式之间来回振荡。代码 04 第 1 部分复现了它(σ = 0.05 的尖高斯,生成器的隐变量 dz=64d_z = 64;模式条的 8 个字符依次对应角度 0°、45°、…、315°,越黑表示越多样本最靠近这个模式):

步数  8 个模式    盖住  高质量
500   [  .@    ]     1      2%
1000  [  @     ]     1      1%
1500  [   @    ]     1      8%
2000  [      @ ]     0      0%
2250  [@       ]     1      9%
2750  [   @@   ]     0      0%
3250  [     @  ]     0      0%
3500  [:@      ]     1      2%
4500  [==#+--*@]     0      2%
6500  [@=+*%=++]     8     16%
8000  [@=#*@+*+]     8     59%

前 4,000 步,几乎每个时刻所有样本都挤在一个模式附近,而这个模式每隔几百步就换一个。之后样本逐渐散开,6,500 步以后 8 个模式都盖住了——这一次训练自己”逃”出了坍塌(同样设置的另外 3 个种子都没有逃出来,见 §6.4)。d_loss、g_loss 在坍塌阶段和恢复以后看起来差不多。

6.3 坍塌时判别器在想什么?

代码 04 第 2 部分取第 1,250 步的状态(所有样本都在 90° 的模式附近),看判别器:

模式0°45°90°135°180°225°270°315°
DD(中心)0.950.890.510.250.430.760.910.94
样本比例001.0000000

你可能以为判别器会画出”7 个真模式亮、1 个假模式暗”的精细图像。实际上它只是一个粗糙的斜坡:生成器所在的一侧低,对面高;135°、180° 两个真模式甚至被判成了”更像假的”(D<0.5D < 0.5)。它只学到了”假样本在那边”。生成器整团地顺着斜坡往 DD 高的方向搬——所有 zz 都被映射到同一个小区域,梯度方向几乎相同——100 步后它已经跳到 270° 附近;判别器随即把斜坡翻过来……接下来 500 步样本依次出现在 270°、135°、315°、135°/180°、45°。

为什么会坍塌? 一个直觉:对固定的判别器,生成器的最优反应是把所有样本都放到 DD 最大的那一点——一个 δ\delta 分布。生成器目标 Ez[log⁡D(G(z))]\mathbb{E}_z[\log D(G(z))] 是对每个 zz 单独求和的,没有任何一项要求”不同的 zz 映射到不同的地方”。只有当判别器追上来、学会惩罚那一点时,生成器才被迫移开。如果两者”你追我赶”而不是同时收敛,就会出现 slide 24 那样的振荡。极小极大问题 min⁡Gmax⁡D\min_G\max_D 和”极大极小”max⁡Dmin⁡G\max_D\min_G 一般不相等;交替的梯度下降有时更像在解后者——先让生成器对当前判别器做最优反应(坍塌到一点),再让判别器反应。

6.4 什么能缓解?

slide 25:修补模式坍塌的办法大多是经验性的:换网络结构、换 GAN 损失、加正则项……Soumith Chintala 的 How to Train a GAN? Tips and tricks to make GANs work(ganhacks)列了一长串。

代码 04 第 3 部分做了一个小的消融实验(每种设置 3 个种子,6,000 步):

设置最后盖住的模式数(各种子)高质量样本最后 2,000 步全盖住的比例新分类器准确率
dz=2d_z = 28 8 884%100%0.653
dz=8d_z = 88 7 152%38%0.742
dz=64d_z = 640 0 01%0%0.982
dz=64d_z = 64 + PacGAN-28 8 869%100%0.642
dz=64d_z = 64 + PacGAN-48 8 829%83%0.841
  • 同样的网络、同样的数据,只改隐变量的维数,坍塌就从没有、到偶发、到常态。这是 slide 25 说”修补办法大多是经验性的”的原因:模式坍塌对看起来无关的设置很敏感,很难事先预测。
  • PacGAN(Lin et al. 2018)让判别器一次看 mm 个样本拼起来的向量(全真或全假)。一组样本”全挤在同一个模式里”本身就是假的证据,于是判别器能直接惩罚坍塌。打包 2 个就治好了 dz=64d_z = 64 的坍塌;打包 4 个在 6,000 步内收敛得更慢。类似的思路还有 minibatch discrimination(Salimans et al. 2016)、ProGAN 的 minibatch 标准差特征。
  • 另一类办法改变优化本身:Unrolled GAN(Metz et al. 2017)让生成器”预见”判别器接下来几步的反应(对展开的 kk 步判别器更新求导),直接针对 §6.3 的”你追我赶”;两时间尺度更新(TTUR)、梯度惩罚、谱归一化让判别器更平滑、更接近最优。第 10 讲的 WGAN 换了一个距离,slide 15 称它”训练更稳定、模式坍塌更少”。

6.5 评估

最后一列提醒第三个难题:即使 8 个模式全盖住,新分类器的准确率也明显高于 0.5。 “盖住了几个模式”是一个粗糙的指标;GAN 没有似然,我们只能靠样本统计量来评估,而每个统计量都只看到分布的一部分(§2.2 的最后一行就是一个极端例子)。第 15 讲会专门讨论 Inception Score、FID、精度 / 召回、似然各自看到了什么、漏掉了什么。


7. 美在判别器的眼中 · Beauty lies in the eyes of the discriminator

slide 26:2018 年,佳士得拍卖了一幅由 GAN 生成的画(Obvious 团队,基于 Robbie Barrat 的代码)。估价 7,000–10,000 美元,成交价 432,500 美元。

这张 slide 的标题值得多想一下。GAN 的生成器从来没有见过任何一张真实的图像——它所知道的关于”真实”的一切,都来自判别器的梯度。什么叫”像真的”,是由一个神经网络在训练过程中学出来的标准决定的,而这个标准随着训练不断变化(§6.3 的斜坡)。这既是 GAN 的力量(不需要手工定义”好样本”,判别器会自动找出人眼也会注意的差别,比如纹理和边缘的锐利程度),也是它的弱点(判别器看不见的差别,比如漏掉的模式,生成器就没有动力去修正)。


8. 2023 年之后 · Since 2023

  • GAN 在扩散模型时代的位置。 2021 年以后,图像生成的主流转向扩散模型(第 16 讲),原因正是本讲的三个困难:扩散模型的训练目标是稳定的回归、有似然界、不坍塌。但 GAN 没有消失:GigaGAN(Kang et al., CVPR 2023)和 StyleGAN-T(Sauer et al., ICML 2023)表明把 GAN 放大到文本到图像的规模仍然可行,且一步就能采样。
  • 对抗损失作为组件。 现在最常见的用法是把判别器当作一个”感知损失”:潜空间扩散模型(Stable Diffusion)的自编码器、VQGAN、很多神经音频编解码器都在重构损失之外加一个(逐块的)对抗损失,让重构更锐利——第 6 讲 VAE “样本模糊”问题的一个工程解法。
  • 对抗蒸馏。 把几十步的扩散模型压缩成一到四步:Adversarial Diffusion Distillation(SDXL-Turbo,Sauer et al. 2023)、DMD2(Yin et al., NeurIPS 2024)都用判别器来弥补”学生”和真实数据之间的差距。这是第 8 讲 Parallel WaveNet “慢老师 → 快学生”的又一个版本,而判别器帮助学生避免了纯回归式蒸馏的模糊。
  • “现代基线”的重新审视。 The GAN is dead; long live the GAN! A Modern GAN Baseline(R3GAN,Huang et al., NeurIPS 2024)认为,很多”技巧”是为不良的损失函数打的补丁;用一个带正则的相对论式损失(有局部收敛保证)配上现代网络结构,可以去掉大部分技巧、稳定地训练。
  • 评估仍是难题。 Stein et al.(NeurIPS 2023)发现 FID 依赖的 Inception 特征系统性地低估了扩散模型的样本,建议改用 DINOv2 特征;第 15 讲会回到这个问题。

9. 小结 · Summary

  1. 三个似然家族都在最小化 DKL(pdata∥pθ)D_{\mathrm{KL}}(p_{\text{data}} \Vert p_\theta)。最大似然统计效率最优、等价于压缩,但对不完美的模型,似然和样本质量可以脱节:噪声混合似然只差 log⁡100\log 100(像素世界 6.64 bit,维数越高越不起眼)、样本 99% 是噪声;背诵训练集样本完美、似然 −∞-\infty。
  2. 两样本检验只用样本判断 P=QP = Q;手工统计量只看得见它被设计来看的差别(同均值同协方差的分布,拒绝率 ≈ α)。训练一个分类器当检验统计量:它自己学出两组样本差在哪里。
  3. 最优判别器 D∗=pdata/(pdata+pG)D^* = p_{\text{data}}/(p_{\text{data}} + p_G),它的 logit 是对数密度比;判别器损失给出 JSD 的变分下界(测试集上),样本少时会过拟合。
  4. GAN:隐式生成器 x=Gθ(z)x = G_\theta(z)(不必可逆、没有似然)+ 判别器,min⁡Gmax⁡DV\min_G\max_D V;判别器最优时等于 2 DJSD−log⁡42\,D_{\mathrm{JSD}} - \log 4。JSD 有界、对称,在模型族不够大时可以偏向抓住部分模式(一维例子:全局最小 0.117 vs 最大似然解 0.201),并且有多个局部最优。实际常用的非饱和损失在判别器最优时对应 DKL(pG∥pdata)−2DJSDD_{\mathrm{KL}}(p_G \Vert p_{\text{data}}) - 2D_{\mathrm{JSD}},更偏向抓住一个模式。
  5. 训练:交替的随机梯度上升 / 下降,生成器只通过 ∇xD\nabla_x D 了解真实数据;原始损失会饱和(判别器自信时梯度小几百倍),非饱和损失 −log⁡D(G(z))-\log D(G(z)) 是标准做法(Adam 部分掩盖了饱和)。
  6. 三个困难:优化不稳定——理论保证需要”判别器每步最优”,实践中损失振荡、没有停止准则(Flow-GAN 实验:判别器损失 ≈ log 4,精确 JSD 第 1,000 步后变差);模式坍塌——生成器在模式之间跳,对设置极其敏感,PacGAN 等经验办法能缓解;评估——没有似然,每个样本统计量都只看到一部分。

10. 常见误区 · Common pitfalls

  1. “GAN 在最小化 JSD。” 只有在判别器每一步都最优时才成立(§4.2)。实际训练中判别器离 D∗D^* 很远,生成器优化的是一个有偏、随时间变化的估计;代码 03 第 3 部分里判别器损失 ≈ log 4,精确 JSD 却有 0.3–0.4。
  2. “判别器损失越接近 log 4,生成器越好。” 它也可能说明判别器太弱或刚被生成器甩开(§6.1、§6.2)。判别器损失不是停止准则。
  3. “似然高的模型样本一定好”或反过来。 对不完美的模型都不成立(§2);两者衡量的是不同的东西。
  4. “样本看起来都很真,模型就好。” 可能是背诵训练集(Case 3),也可能是模式坍塌(多样性很低)。样本质量要分保真度和多样性。
  5. “判别器分得开 = 两个分布不同。” 样本少时判别器会过拟合(代码 02:真实 JSD = 0,训练集上估计 0.06)。要在新样本上测。
  6. “均值和方差都对了,分布就差不多对了。” 前两阶矩相同的分布可以完全不同(同均值同协方差的高斯 vs 圆环,JSD = 0.34)。
  7. “非饱和损失和原始损失是同一个目标。” 不动点相同,但梯度在训练初期差几百倍,对应的目标也不同:判别器最优时是 DKL(pG∥pdata)−2DJSDD_{\mathrm{KL}}(p_G \Vert p_{\text{data}}) - 2D_{\mathrm{JSD}},不是 JSD(§4.4 的对照实验里,两者从同一个初值走到不同的局部最小)。
  8. “模式坍塌是因为生成器容量不够。” 不是:代码 04 里同样的网络,dzd_z 从 2 换到 64 就从不坍塌变成总坍塌;PacGAN 只改判别器就治好了它。坍塌是博弈动力学的问题(§6.3)。
  9. “GAN 已经过时了。” 作为独立的生成模型它让位给了扩散模型,但对抗损失作为组件(自编码器、蒸馏)至今无处不在(§8)。

11. 练习 · Exercises

练习 1(最优判别器) 对固定的 pGp_G,证明 V(G,D)V(G, D) 关于 DD 的逐点最大值在 D∗(x)=pdata(x)pdata(x)+pG(x)D^*(x) = \frac{p_{\text{data}}(x)}{p_{\text{data}}(x) + p_G(x)} 处取得。如果 pdata(x)>0p_{\text{data}}(x) > 0 而 pG(x)=0p_G(x) = 0,D∗(x)D^*(x) 是多少?这时 VV 中对应的被积项是多少?

参考答案

见 §3.6:alog⁡y+blog⁡(1−y)a\log y + b\log(1-y) 在 y=a/(a+b)y = a/(a+b) 处取唯一最大值。pG(x)=0p_G(x) = 0 时 D∗(x)=1D^*(x) = 1,被积项 pdata(x)log⁡1+0⋅log⁡0p_{\text{data}}(x)\log 1 + 0\cdot\log 0;按约定 0log⁡0=00\log 0 = 0,所以是 0——这一点的真实数据被完美识别。注意此时 log⁡(1−D∗)=−∞\log(1 - D^*) = -\infty,但它乘的是 pG(x)=0p_G(x) = 0。如果生成器有一点点质量移到这里,它会立刻受到 −∞-\infty 的”惩罚”吗?不会:D∗D^* 会随 pGp_G 一起变;但如果判别器没有及时更新,生成器在 D≈1D \approx 1 的地方会得到很强的”往这里走”的信号——这正是 §6.3 里生成器整团搬家的动力。

练习 2(JSD 的上界) 证明 DJSD(p,q)≤log⁡2D_{\mathrm{JSD}}(p, q) \leq \log 2,并找出等号成立的条件。由此说明:判别器损失 −V-V 的取值范围是什么?

参考答案

DKL(p∥m)=Ep[log⁡2pp+q]≤Ep[log⁡2pp]=log⁡2D_{\mathrm{KL}}(p \Vert m) = \mathbb{E}_p[\log\frac{2p}{p+q}] \leq \mathbb{E}_p[\log\frac{2p}{p}] = \log 2(因为 p+q≥pp + q \geq p),同理另一项,所以 DJSD≤log⁡2D_{\mathrm{JSD}} \leq \log 2。等号当且仅当在 p>0p > 0 的地方 q=0q = 0、在 q>0q > 0 的地方 p=0p = 0,即支撑集(几乎处处)不相交。判别器最优时 −V=log⁡4−2DJSD∈[0,log⁡4]-V = \log 4 - 2D_{\mathrm{JSD}} \in [0, \log 4]:两个分布完全分开时判别器损失可以降到 0,完全相同时是 log⁡4≈1.386\log 4 \approx 1.386。

练习 3(矩相同的分布) 设 PP 是 8 个等权的点质量,位于单位圆上角度 2πk/82\pi k/8 处,QQ 是把 PP 旋转 π/8\pi/8。证明对任意 j+l<8j + l < 8,EP[xjyl]=EQ[xjyl]\mathbb{E}_P[x^j y^l] = \mathbb{E}_Q[x^j y^l]。(提示:用复数 w=x+iyw = x + iy,xjylx^j y^l 是 wawˉbw^a\bar w^b(a+b=j+la + b = j + l)的线性组合。)为什么”比较前几阶矩”的检验分不开这两个分布?

参考答案

PP 的点是 wk=e2πik/8w_k = e^{2\pi ik/8},EP[wawˉb]=18∑ke2πik(a−b)/8\mathbb{E}_P[w^a\bar w^b] = \frac18\sum_k e^{2\pi ik(a-b)/8},当 8∤(a−b)8 \nmid (a - b) 时为 0,当 a=ba = b 时为 1。若 a+b<8a + b < 8,则 ∣a−b∣<8|a - b| < 8,所以只有 a=ba = b 时非零,值为 1。旋转后 wk′=wkeiπ/8w_k' = w_k e^{i\pi/8},w′awˉ′b=wawˉbeiπ(a−b)/8w'^a\bar w'^b = w^a\bar w^b e^{i\pi(a-b)/8};a=ba = b 时因子为 1,a≠ba \neq b 时原期望本来就是 0。所以 7 阶以内所有矩相同。任何只看 7 阶以内矩的检验都分不开 PP、QQ,而一个分类器只要学会”角度  mod  45°\bmod\,45° 接近 0 还是 22.5°“就能完美区分它们(代码 02 中分类器准确率 0.845,加上 σ = 0.25 的高斯后两个分布有重叠)。

练习 4(判别器是密度比估计器) 设判别器的 logit 为 ℓ(x)\ell(x),D=σ(ℓ)D = \sigma(\ell)。证明在最优时 ℓ∗(x)=log⁡pdata(x)−log⁡pG(x)\ell^*(x) = \log p_{\text{data}}(x) - \log p_G(x)。如果 pGp_G 已知(比如是一个流),怎样用训练好的判别器得到 pdatap_{\text{data}} 的一个估计?这个想法在第 12 讲叫什么?

参考答案

σ(ℓ∗)=pdatapdata+pG\sigma(\ell^*) = \frac{p_{\text{data}}}{p_{\text{data}} + p_G} ⇒ eℓ∗=D∗1−D∗=pdatapGe^{\ell^*} = \frac{D^*}{1 - D^*} = \frac{p_{\text{data}}}{p_G}。所以 p^data(x)=pG(x) eℓ(x)\hat p_{\text{data}}(x) = p_G(x)\,e^{\ell(x)}(一般还要重新归一化,因为学到的 ℓ\ell 不是精确的)。这就是第 12 讲 slide 13 的”用分类器修正基础模型的密度”,也是噪声对比估计(NCE)的出发点:把 pGp_G 换成一个已知的噪声分布 pnp_n,把判别器参数化成 pθpθ+pn\frac{p_\theta}{p_\theta + p_n}。

练习 5(饱和的梯度) 用 D=σ(ℓ)D = \sigma(\ell) 计算 ∂∂ℓlog⁡(1−D)\frac{\partial}{\partial\ell}\log(1 - D) 和 ∂∂ℓ(−log⁡D)\frac{\partial}{\partial\ell}(-\log D)。在 D=0.001D = 0.001 时两者相差多少倍?Adam 能完全消除这个差别吗?(提示:考虑 minimax 的每样本权重正比于 D(G(zi))D(G(z_i))。)

参考答案

log⁡(1−σ(ℓ))=−softplus(ℓ)\log(1 - \sigma(\ell)) = -\mathrm{softplus}(\ell),导数 −σ(ℓ)=−D-\sigma(\ell) = -D;−log⁡σ(ℓ)=softplus(−ℓ)-\log\sigma(\ell) = \mathrm{softplus}(-\ell),导数 −(1−σ(ℓ))=−(1−D)-(1 - \sigma(\ell)) = -(1 - D)。D=0.001D = 0.001 时相差 999 倍。Adam 用梯度二阶矩的平方根做归一化,能消除整体尺度的差别(代码 03:梯度小 472 倍,但 Adam 下仍能学会),但不能消除方向的差别:minimax 的梯度是 ∑iD(G(zi))∇(⋅)\sum_i D(G(z_i))\nabla(\cdot),各样本的权重不同时(有的假样本 D=0.1D = 0.1、有的 10−510^{-5}),方向由少数”较像真”的样本主导。代码 03 里所有假样本的 DD 都差不多小,有效样本数仍有 853 / 1000,所以这个问题没有显现。

练习 6(JSD 的模式选择) 在 §4.4 的例子里,把数据的两个权重改成 0.5 / 0.5。预测 JSD 的最小值在哪里(一个模式?两个都盖住?),然后修改 03_gan.py 的 W1D 验证。

参考答案

作者的运行结果:0.5 / 0.5 时,以原点为中心的宽高斯(μ=0\mu = 0,σ≈2.09\sigma \approx 2.09)JSD 为 0.201,反而低于抓住一个模式的 0.216——全局最小变成了”盖住两个”。JSD 并不总是”模式寻找”:它介于前向 KL(一定盖住)和反向 KL(一定抓住一个)之间,选哪一种取决于模式的权重和间距。0.7 / 0.3 时放弃小模式只损失 30% 的质量,划算;0.5 / 0.5 时放弃一半太贵。这也说明 GAN 的模式坍塌不能简单地归因于”JSD 是模式寻找的”(代码 04 的坍塌来自博弈的动力学,§6.3)。

练习 7(PacGAN 为什么有效) 设生成器坍塌成一个点质量 δx0\delta_{x_0},x0x_0 恰好是真实分布 8 个模式之一的中心。(a) 一个只看单个样本的判别器在 x0x_0 处能给出多大的 D∗D^*?(b) 一个一次看两个样本 (x,x′)(x, x') 的判别器呢?(提示:真实数据里两个独立样本落在同一个模式、并且几乎完全重合的概率是多少?)

参考答案

(a) D∗(x0)=pdata(x0)pdata(x0)+pG(x0)D^*(x_0) = \frac{p_{\text{data}}(x_0)}{p_{\text{data}}(x_0) + p_G(x_0)};pGp_G 是点质量,在 x0x_0 处”无穷大”,所以 D∗(x0)→0D^*(x_0) \to 0,但这只能告诉生成器”x0x_0 太多了”,不能告诉它”其他模式缺了”——单样本判别器在其他模式上的 D∗=1D^* = 1,生成器会整体搬到另一个模式(§6.3)。(b) 打包后真实数据的分布是 pdata(x)pdata(x′)p_{\text{data}}(x)p_{\text{data}}(x'),两个样本落在同一个模式的概率只有 1/8,而且两者几乎重合(距离 ≈ 0)的概率很小;生成器的打包分布却总是 (x0,x0)(x_0, x_0)。判别器可以学会”两个样本完全一样 → 假”,这个特征无论生成器搬到哪个模式都成立,于是生成器只能通过增加多样性来骗过它。

练习 8(“背诵 + 模糊”的最优 δ) 在代码 01 第 3 部分中,测试似然最好的 δ 约 0.05,恰好等于像素世界的翻转噪声 ε。这是巧合吗?如果训练集无穷大,最优的 δ 会趋向什么?

参考答案

不完全是巧合。训练图本身已经带着 ε = 5% 的翻转噪声,测试图也一样;“以训练图为中心再翻转 δ”相当于在模板上叠加两层噪声,有效翻转率约 ϵ+δ−2ϵδ\epsilon + \delta - 2\epsilon\delta。训练集无穷大时,每个模板周围都有大量训练图,核密度估计会收敛到”训练分布与翻转核的卷积”,最优的 δ → 0(不需要额外平滑,经验分布本身就足够密)。训练集有限时(1 万张图,2^64 种可能),需要 δ > 0 才能给没见过的图非零概率;δ 太大又会把训练图模糊过头。0.05 是这个偏差–方差折中在当前样本量下的结果。

练习 9(动手:判别器更强、步子更小) 在 03_gan.py 第 1 部分里,从 (0,1)(0, 1) 出发,分别试 (a) 每次生成器更新前判别器更新 5 次(d_steps=5);(b) 学习率从 2e-3 降到 5e-4。预测 GAN 还会不会离开宽高斯、走到大模式。

参考答案

作者的运行结果:(a) 判别器更强时离开得更快——第 1,500 步已到 (−1.80,0.83)(-1.80, 0.83),第 2,000 步到 (−2.00,0.52)(-2.00, 0.52)、JSD 0.117。判别器越接近最优,生成器收到的梯度越接近 DKL(pG∥pdata)−2DJSDD_{\mathrm{KL}}(p_G \Vert p_{\text{data}}) - 2D_{\mathrm{JSD}} 的梯度,而这个目标从 (0,1)(0, 1) 出发会直接走向大模式(§4.4 的对照表)。(b) 学习率小时 4,000 步后还停在 (−0.62,1.72)(-0.62, 1.72) 附近(JSD 0.205),在宽高斯区域里慢慢漂移——那一带非饱和目标的地形很平,小步长、加上小批量的噪声,需要更久才能离开。GAN 的结果同时取决于”优化的是什么目标”和”怎样优化”。

练习 10(为什么 GAN 不能直接报告似然) 有人提议:GAN 的生成器是一个隐变量模型 pG(x)=∫δ(x−G(z))p(z) dzp_G(x) = \int \delta(x - G(z))p(z)\,dz,可以用第 5 讲的重要性采样估计它的似然。这个想法有什么问题?如果给生成器的输出加上一点高斯噪声 x=G(z)+σϵx = G(z) + \sigma\epsilon 呢?

参考答案

当 dz<dxd_z < d_x 时,GG 的像是 Rdx\mathbb{R}^{d_x} 里一个低维的流形,pGp_G 对 Lebesgue 测度没有密度(几乎所有真实数据点的”似然”都是 0,对数似然 −∞-\infty)。加噪声后 pG(x)=∫N(x;G(z),σ2I)p(z) dzp_G(x) = \int\mathcal{N}(x; G(z), \sigma^2 I)p(z)\,dz 是一个合法的连续密度,可以用重要性采样估计——这正是 Wu et al.(2017)On the quantitative analysis of decoder-based generative models 用 AIS 评估 GAN 的做法。但结果强烈依赖人为选的 σ,而且 GAN 的训练从来没有让这个量变大,所以通常很差(和代码 03 第 3 部分的 Flow-GAN 一致:对抗训练的模型似然很差)。


12. 延伸阅读 · Further reading

原课材料

本讲的核心论文

  • Goodfellow et al., Generative Adversarial Nets, NeurIPS 2014(极小极大目标、D∗D^*、JSD、非饱和损失)
  • Theis, van den Oord & Bethge, A Note on the Evaluation of Generative Models, ICLR 2016(slides 4–6 的三种情况)
  • Lopez-Paz & Oquab, Revisiting Classifier Two-Sample Tests, ICLR 2017
  • Mohamed & Lakshminarayanan, Learning in Implicit Generative Models, 2016(“用分类器估计密度比”统一看 GAN、NCE 等)
  • Grover, Dhar & Ermon, Flow-GAN: Combining Maximum Likelihood and Adversarial Learning in Generative Models, AAAI 2018

训练困难与修补

  • Metz, Poole, Pfau & Sohl-Dickstein, Unrolled Generative Adversarial Networks, ICLR 2017(slide 24 的图)
  • Salimans et al., Improved Techniques for Training GANs, NeurIPS 2016(minibatch discrimination、Inception Score)
  • Lin, Khetan, Fanti & Oh, PacGAN: The Power of Two Samples in Generative Adversarial Networks, NeurIPS 2018
  • Radford, Metz & Chintala, Unsupervised Representation Learning with Deep Convolutional GANs(DCGAN), ICLR 2016
  • Mescheder, Geiger & Nowozin, Which Training Methods for GANs do actually Converge?, ICML 2018
  • Soumith Chintala 等,ganhacks:https://github.com/soumith/ganhacks

2023 年之后

  • Kang et al., Scaling up GANs for Text-to-Image Synthesis(GigaGAN), CVPR 2023;Sauer et al., StyleGAN-T, ICML 2023
  • Sauer et al., Adversarial Diffusion Distillation, 2023;Yin et al., Improved Distribution Matching Distillation for Fast Image Synthesis(DMD2), NeurIPS 2024
  • Huang, Gokaslan, Kuleshov & Tompkin, The GAN is dead; long live the GAN! A Modern GAN Baseline, NeurIPS 2024
  • Stein et al., Exposing Flaws of Generative Model Evaluation Metrics and Their Unfair Treatment of Diffusion Models, NeurIPS 2023

13. 下一讲预告 · Next lecture

本讲的 GAN 在理想条件下最小化 JSD——可 JSD 只是众多”分布之间的距离”中的一种,而且它有一个致命的弱点:两个分布的支撑集不相交时,JSD 恒等于 log⁡2\log 2,生成器得不到任何有用的梯度(练习 2)。第 10 讲(原课 Lecture 10,GANs):

  • ff-散度家族(KL、反向 KL、JS、Hellinger、χ²……)和用 Fenchel 凸共轭得到的变分下界——任何一个 ff-散度都能写成”训练一个判别器”的形式(ff-GAN);
  • Wasserstein 距离与 Kantorovich–Rubinstein 对偶:支撑集不相交时依然平滑;WGAN 的权重裁剪与梯度惩罚;
  • 让 GAN 也能做推断(BiGAN:编码器 + 生成器 + 联合判别器)和跨域翻译(CycleGAN 的循环一致性、AlignFlow、StarGAN)。
← 返回课程目录