GAN——生成器与判别器

Build~75 minutesPython先修要求: Phase 3 · 02 (Backprop), Phase 3 · 08 (Optimizers), Phase 8 · 02 (VAE)
Goodfellow 在 2014 年的技巧是彻底跳过密度。两个网络。一个造假,一个抓假。它们一直斗,直到假样本与真样本无法区分。这本来不该奏效,它经常也确实不奏效。但一旦奏效,在窄领域里它的样本至今仍是文献中最锐利的。

问题

VAE 的样本模糊,因为它的 MSE 解码损失对均值图像是贝叶斯最优的——而许多可能数字的均值就是一个模糊的数字。你想要一个奖励合理性的损失,而不是奖励与某个目标逐像素接近。合理性没有闭式表达。你必须把它学出来。

Goodfellow 的想法:训练一个分类器 D(x) 区分真实图像和假图像。训练一个生成器 G(z) 去骗过 D。给 G 的损失信号,就是 D 当前认为「什么让东西看起来像真的」。这个信号随 G 的改进而更新,追着一个移动的目标跑。如果两个网络都收敛,G 就在从未写出 log p(x) 的情况下学会了数据分布。

这就是对抗训练。数学上是一个极小极大博弈:

\min_G \max_D \; \mathbb{E}_{\text{real}}[\log D(x)] + \mathbb{E}_{\text{fake}}[\log(1 - D(G(z)))]

2026 年,GAN 已不再是 SOTA 生成器(扩散和流匹配抢走了那顶王冠)。但 StyleGAN 2/3 仍是有史以来交付的最锐利人脸模型,GAN 判别器被用作扩散训练中的感知损失,对抗训练还驱动着快速的单步蒸馏(SDXL-Turbo、SD3-Turbo、LCM),让你能上线实时扩散。

概念

GAN 训练:生成器与判别器的极小极大博弈

生成器 G(z)。 把噪声向量 z \sim \mathcal{N}(0, I) 映射成样本 \hat{x}。一个解码器形状的网络(全连接或转置卷积)。

判别器 D(x)。 把样本映射成一个标量概率(或分数)。真 → 1,假 → 0。

损失。 两次交替更新:

  • 训练 D: \text{loss}_D = -[ \log D(x) + \log(1 - D(G(z))) ]。真实=1、虚假=0 的二元交叉熵。
  • 训练 G: \text{loss}_G = -\log D(G(z))。这是 Goodfellow 使用的非饱和形式(原始的 \log(1 - D(G(z))) 在 D 自信时会饱和,把梯度杀掉)。

训练循环。 一步 D,一步 G。重复。

为什么有效。 如果 G 完美匹配 p_{\text{data}},那么 D 无法做得比随机猜更好,处处输出 0.5;G 再也拿不到梯度。达到均衡。

为什么会崩。 模式崩溃(G 找到一个 D 分不出来的模式,然后永远只造它)、梯度消失(D 学得太快,\log D 饱和)、训练不稳定(学习率、batch size,什么都可能)。

让 GAN 真正可用的变体

年份创新修复了什么
2015DCGAN卷积/反卷积、batch norm、LeakyReLU——首个稳定的架构。
2017WGAN、WGAN-GP用 Wasserstein 距离 + 梯度惩罚替代 BCE。修复梯度消失。
2017谱归一化对判别器做 Lipschitz 约束。2026 年的判别器仍在用。
2018Progressive GAN先训低分辨率,再逐层添加。首批百万像素结果。
2019StyleGAN / StyleGAN2映射网络 + 自适应实例归一化。固定领域逼真度的 SOTA。
2021StyleGAN3无混叠、平移等变——2026 年仍是人脸的黄金标准。
2022StyleGAN-XL条件式、类别感知、更大规模。
2024R3GAN以更强的正则化重新出发;在 1024² 上无需额外技巧即可工作。
gan-minimax静态版本未包含此交互图

构建它

code/main.py 在一维数据上训练一个迷你 GAN:两个高斯组成的混合。生成器和判别器都是单隐藏层 MLP。我们手写前向、反向和极小极大循环。目标是亲眼看到两种关键失效模式(模式崩溃 + 梯度消失)发生。

第 1 步:非饱和损失

原始的 Goodfellow 损失 \log(1 - D(G(z))) 在 D 以高置信度把 G 的假样本判为假时趋近 0。此时 G 的梯度基本为零——G 无法改进。非饱和形式 -\log D(G(z)) 的渐近行为相反:当 D 自信时它会爆炸,给 G 一个强信号。

pythondef g_loss(d_fake):
    # maximize log D(G(z))  <=>  minimize -log D(G(z))
    return -sum(math.log(max(p, 1e-8)) for p in d_fake) / len(d_fake)

第 2 步:每个生成器步配一个判别器步

pythonfor step in range(steps):
    # train D
    real_batch = sample_real(batch_size)
    fake_batch = [G(z) for z in sample_noise(batch_size)]
    update_D(real_batch, fake_batch)

    # train G
    fake_batch = [G(z) for z in sample_noise(batch_size)]  # fresh fakes
    update_G(fake_batch)

给 G 用新鲜的假样本,否则梯度会陈旧。

第 3 步:留意模式崩溃

pythonif step % 200 == 0:
    samples = [G(z) for z in sample_noise(500)]
    mode_a = sum(1 for s in samples if s < 0)
    mode_b = 500 - mode_a
    if min(mode_a, mode_b) < 50:
        print("  [!] mode collapse: one mode is starved")

典型症状:两个真实模式中的一个不再被生成。判别器不再纠正它,因为它从未作为假样本出现过。

常见陷阱

  • 判别器太强。 把 D 的学习率降到 1/2 到 1/5,或者加实例噪声/层噪声。如果 D 的准确率超过 95%,G 就死了。
  • 生成器记住了一个模式。 给 D 的输入加噪声,使用 minibatch discrimination 层,或改用 WGAN-GP。
  • Batch norm 泄露统计量。 真实 batch 和假 batch 流过同一个 BN 层会混合它们的统计量。改用 instance norm 或谱归一化。
  • 刷 Inception score。 FID 和 IS 在样本数少时噪声很大。评估时至少用 1 万个样本。
  • 对条件任务来说,单次采样是个谎言。 你仍然需要 CFG 尺度、截断技巧和重采样,才能得到可用的输出。

使用它

2026 年的 GAN 技术栈:

场景选择
逼真的人脸,固定姿态StyleGAN3(最锐利、最小)
动漫 / 风格化人脸StyleGAN-XL 或 Stable Diffusion LoRA
图生图翻译Pix2Pix / CycleGAN(第 8 阶段 · 04)或 ControlNet(第 8 阶段 · 08)
快速单步文生图扩散的对抗蒸馏(SDXL-Turbo、SD3-Turbo)
扩散训练器内部的感知损失在图像裁剪块上的小 GAN 判别器
任何多模态、开放式任务不要用——改用扩散或流匹配

GAN 锋利但狭窄。一旦你的领域变宽——照片、任意文本提示、视频——就换扩散。对抗技巧作为组件(感知损失、蒸馏)继续存在,而不是作为独立的生成器。

交付它

保存 outputs/skill-gan-debugger.md。Skill 接收一次失败的 GAN 训练(损失曲线、样本网格、数据集大小),输出按可能性排序的原因列表、一行修复方案,以及重跑协议。

练习

  1. 简单。 用默认设置运行 code/main.py。然后把 D_LR = 5 * G_LR 再跑一次。G 的损失多快坍缩成一个常数?
  2. 中等。 把 Goodfellow BCE 损失换成 WGAN 损失:\text{loss}_D = \mathbb{E}[D(\text{fake})] - \mathbb{E}[D(\text{real})],\text{loss}_G = -\mathbb{E}[D(\text{fake})],并把 D 的权重裁剪到 [-0.01, 0.01]。训练更稳定吗?比较实际耗时下的收敛速度。
  3. 困难。 把一维例子扩展到二维数据(圆环上的 8 个高斯混合)。追踪生成器在第 1k、5k、10k 步时捕捉到 8 个模式中的几个。实现 minibatch discrimination 并重新测量。

关键术语

术语常见说法实际含义
Generator「G」从噪声到样本的网络,G: z → x̂。
Discriminator「D」分类器 D: x → [0, 1],真 vs 假。
Minimax「那个博弈」对一个联合目标做 \min_G \max_D。
Non-saturating loss「那个修复」G 用 -\log D(G(z)) 代替 \log(1 - D(G(z)))。
Mode collapse「G 只记住了一个东西」尽管数据多样,生成器只产出少数几种不同输出。
WGAN「Wasserstein」用 Earth-Mover 距离 + 梯度惩罚替代 BCE;梯度更平滑。
Spectral norm「Lipschitz 技巧」约束 D 的权重范数以限制其斜率;稳定训练。
StyleGAN「那个能用的」映射网络 + AdaIN;人脸领域同类最佳,2026 年仍是。

生产说明:单次推理是 GAN 持久的优势

在开放域生成上,GAN 已不再以样本质量取胜,但在推理成本上仍然赢。用生产推理文献的词汇来说,一个 GAN 具有:

  • 没有 prefill,没有 decode 阶段。 只有一次 G(z) 前向传播。TTFT ≈ 总延迟。
  • 没有 KV-cache 压力。 唯一的状态是权重。batch size 受激活内存约束,而非缓存。
  • 极易做 continuous batching。 因为每个请求的 FLOPs 固定,按服务器目标占用率做静态 batch 通常就是最优的。不需要在途调度器。

这就是为什么 GAN 蒸馏(SDXL-Turbo、SD3-Turbo、ADD、LCM)是 2026 年快速文生图的主导技术:它把 20-50 步的扩散 pipeline 压缩成 1-4 次 GAN 式前向传播,同时保持扩散基座的分布。对抗损失作为训练期旋钮活了下来,用来把慢生成器变成快生成器。

延伸阅读

示意图共 1 张

gan diagram
gan

“Stay hungry, stay foolish.”

— Steve Jobs

esc
↑↓切换↵打开esc关闭