GAN生成器与判别器


文档摘要

GAN生成器与判别器 本节摘要:Goodfellow 2014 的奇思妙想是——彻底跳过密度。两个网络,一个造假,一个抓假,它俩对抗直到假货与真货无法区分。这套博弈在数学上是一个极小极大(minimax)游戏,它本不该工作,它常常也确实不工作,但当它工作时,产出的样本在窄领域至今仍是文献里最锐利的。本节讲透:为什么 VAE 模糊而 GAN 锐利(损失奖励「合理性」而非像素距离)、非饱和损失为什么是命脉、模式崩塌与梯度消失如何发生、WGAN 与谱归一化如何稳住训练。读完本节,你会明白为什么 2026 年 GAN 不再是开放领域的 SOTA,却仍是 StyleGAN 人脸、对抗蒸馏(SDXL-Turbo)和扩散训练中感知损失的核心。

GAN生成器与判别器

本节摘要:Goodfellow 2014 的奇思妙想是——彻底跳过密度。两个网络,一个造假,一个抓假,它俩对抗直到假货与真货无法区分。这套博弈在数学上是一个极小极大(minimax)游戏,它本不该工作,它常常也确实不工作,但当它工作时,产出的样本在窄领域至今仍是文献里最锐利的。本节讲透:为什么 VAE 模糊而 GAN 锐利(损失奖励「合理性」而非像素距离)、非饱和损失为什么是命脉、模式崩塌与梯度消失如何发生、WGAN 与谱归一化如何稳住训练。读完本节,你会明白为什么 2026 年 GAN 不再是开放领域的 SOTA,却仍是 StyleGAN 人脸、对抗蒸馏(SDXL-Turbo)和扩散训练中感知损失的核心。

对应原课程:Phase 08 · Lesson 03 · gans-generator-discriminator(原英文 phases/08-generative-ai/03-gans-generator-discriminator/docs/en.md)。

学习目标

阅读完本节,你应当能够:

  1. 说清 GAN 与 VAE 的本质区别:GAN 不写 log p(x),用判别器学一个「合理性」损失。
  2. 推导 minimax 博弈的目标,并解释为什么生成器要用非饱和损失 -log D(G(z)) 而非原始的 log(1 - D(G(z)))
  3. 诊断 GAN 的两大失败模式——模式崩塌(Mode Collapse)梯度消失,并给出对应修复(降低 D 学习率、WGAN-GP、谱归一化、minibatch discrimination)。
  4. 在一维混合高斯上手写一个 GAN 的前向、反向与 minimax 训练循环。
  5. 解释为什么 2026 年 GAN 仍以组件身份存活(感知损失、对抗蒸馏),而非作为独立生成器。

一、问题与直觉

VAE 的样本之所以模糊,是因为它的 MSE 解码器损失对 L2 是贝叶斯最优的——最优解是一堆合理数字的均值,而均值天生就是一张模糊图。你真正想要的,是一个奖励合理性(plausibility)、而非「逐像素逼近某个目标」的损失。但合理性没有闭式,你只能它。

Goodfellow 的主意:训一个分类器 D(x) 区分真假,再训一个生成器 G(z) 去骗过 DG 收到的损失信号,就是「D 当前认为什么像真」——这个信号会随着 G 的进步而移动,永远在追一个移动靶。如果两个网络都收敛,G 就学到了数据分布,而从头到尾没写过 log p(x)

这就是对抗训练(adversarial training),数学上是一个 minimax 博弈:

min_G max_D E_real[log D(x)] + E_fake[log(1 - D(G(z)))]

💡 在 2026 年,GAN 已不再是 SOTA 生成器(扩散与流匹配夺走了王冠)。但 StyleGAN 2/3 仍是史上最锐利的人脸模型;GAN 的判别器被当作扩散训练中的感知损失;对抗训练驱动着那些让你能实时跑扩散的快速一步蒸馏(SDXL-Turbo、SD3-Turbo、LCM)。

博弈的均衡与崩塌

为什么它能工作? 如果 G 完美匹配了 p_data,那么 D 无论如何都做不到比随机猜更好,会到处输出 0.5;G 拿不到任何梯度,游戏停在均衡点

为什么它会崩? 三种典型崩法:

  1. 模式崩塌(Mode Collapse):G 找到某一个 D 无法分辨的模式,然后永远只产这一个样本。
  2. 梯度消失(Vanishing Gradient):D 学得太快、太自信,log D 进入饱和区,G 拿不到有效梯度。
  3. 训练不稳定:学习率、批大小,任何东西都可能让两边失衡。

一条「让 GAN 真正能用」的演化线

年份 创新 修复了什么
2015 DCGAN 卷积 / 反卷积、批归一化、LeakyReLU——第一个稳定架构。
2017 WGAN、WGAN-GP 用 Wasserstein 距离 + 梯度惩罚替换 BCE,修复梯度消失。
2017 谱归一化 给判别器加 Lipschitz 约束,2026 年仍在用。
2018 Progressive GAN 先训低分辨率再逐层加,第一批百万像素结果。
2019 StyleGAN / StyleGAN2 映射网络 + 自适应实例归一化,窄领域照片级真实度的标杆。
2021 StyleGAN3 无混叠、平移等变——2026 年仍是人脸金标准。
2022 StyleGAN-XL 条件化、类别感知、更大规模。
2024 R3GAN 用更强的正则化重新包装,无技巧即可上 1024²。

二、从零实现:一维 GAN 与两大失败

code/main.py一维混合双高斯数据上训一个迷你 GAN。生成器与判别器都是单隐层 MLP,我们手写前向、反向与 minimax 循环。目标是让你亲眼看见两大失败模式(模式崩塌 + 梯度消失)在训练过程中如何发生。

步骤 1:非饱和损失

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

def g_loss(d_fake): # 最大化 log D(G(z)) <=> 最小化 -log D(G(z)) return -sum(math.log(max(p, 1e-8)) for p in d_fake) / len(d_fake)

⚠️ max(p, 1e-8) 是为了防止 log(0) 爆炸;真实训练中应配合更稳的数值技巧(如 WGAN 的损失)。

步骤 2:判别器一步、生成器一步

for step in range(steps): # 训 D real_batch = sample_real(batch_size) fake_batch = [G(z) for z in sample_noise(batch_size)] update_D(real_batch, fake_batch) # 训 G(必须用新生成的假样本,否则梯度是陈旧的) fake_batch = [G(z) for z in sample_noise(batch_size)] update_G(fake_batch)

关键细节:G 那一步必须用新生成的假样本,否则你拿的是上一轮 G 算出来的梯度,训练会偏离。

步骤 3:监控模式崩塌

if 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 不再把它当假样本看见,它就不再纠正 G——这是一个自我强化的死亡螺旋。

三、典型陷阱与修复

  • 判别器太强:把 D 的学习率砍掉 2~5 倍,或给 D 输入加实例 / 层噪声。一旦 D 准确率 >95%,G 基本就死了。

  • 生成器记住一个模式:给 D 输入加噪声,用 minibatch discrimination 层,或切到 WGAN-GP。

  • 批归一化泄漏统计量:真样本与假样本流过同一层 BN 会混掉各自的统计量。改用实例归一化或谱归一化。

  • Inception Score 被钻空子:FID 和 IS 在样本量低时噪声很大。评估时至少用 1 万个样本。

  • 「一步采样」对条件任务是谎言:你仍然需要 CFG 无分类器引导比例、截断(truncation)技巧、重采样,才能拿到能用的输出。

💡 WGAN 的核心贡献:把 BCE 换成 Wasserstein 距离(地球移动距离)。BCE 在 D 自信时梯度消失;Wasserstein 距离的梯度D 的置信度无关,永远平滑。代价是 D 必须满足 Lipschitz 约束(用权重裁剪或梯度惩罚 WGAN-GP 来近似)。

四、框架对比:2026 年的 GAN 技术栈

场景 选什么
照片级人脸、固定姿态 StyleGAN3(最锐利、最小)
动漫 / 风格化人脸 StyleGAN-XL 或 Stable Diffusion LoRA
图像到图像翻译 Pix2Pix / CycleGAN(第 04 节)或 ControlNet(第 08 节)
快速一步文生图 扩散的对抗蒸馏(SDXL-Turbo、SD3-Turbo)
扩散训练器内的感知损失 在图像裁剪上跑一个小 GAN 判别器
多模态、开放领域 别用——上扩散或流匹配

结论:GAN 锐利但窄。一旦你的领域打开——照片、任意文本提示、视频——就切到扩散。对抗这个技巧作为组件(感知损失、蒸馏)活了下来,但不再是独立的生成器。

与 VAE、扩散的对照

维度 VAE GAN 扩散
密度 显式(下界) 隐式(无) 显式(下界)
采样步数 1 步 1 步 几十步
样本锐度 模糊 锐利 锐利
训练稳定 稳定 不稳定 稳定
似然可评估 是(下界)
失败模式 后验崩塌、模糊 模式崩塌、梯度消失

GAN 与扩散在「锐度」上并列第一,但 GAN 训练不稳、无法算似然——这正是它被扩散取代的两大原因。

五、可复用产物

本节产出一个调试技能文件(位于原课程 outputs/skill-gan-debugger.md)。

  • skill-gan-debugger.md:输入一个跑崩的 GAN(损失曲线、样本网格、数据集大小),输出一个排序的「可能原因 + 一句话修复 + 重跑协议」清单。

六、练习

  1. 简单。 用默认设置跑 code/main.py。然后把 D_LR = 5 * G_LR 重跑。G 的损失多快塌成一个常数?

  2. 中等。 把 Goodfellow BCE 损失换成 WGAN 损失:loss_D = E[D(fake)] − E[D(real)]loss_G = −E[D(fake)],并把 D 权重裁剪到 [-0.01, 0.01]。训练更稳了吗?比较墙上时钟收敛速度。

  3. 困难。 把一维示例扩展到二维(8 个高斯排成环)。追踪 G 在第 1k、5k、10k 步各捕获了几个模式。实现 minibatch discrimination,重新测量。

本节要点回顾

  1. GAN 跳过密度:用判别器学「合理性」损失,G 追着一个移动靶,直到假货无法分辨;从头到尾不写 log p(x)
  2. minimax 博弈:min_G max_D E[log D(x)] + E[log(1 - D(G(z)))];均衡点是 D 处处输出 0.5。
  3. 非饱和损失是命脉:G-log D(G(z)) 而非 log(1 - D(G(z))),否则 D 一自信 G 的梯度就消失。
  4. 两大失败:模式崩塌(G 永远产一个模式)、梯度消失(D 学太快);修复靠降 D 学习率、WGAN-GP、谱归一化、minibatch discrimination。
  5. 训练循环:D 一步、G 一步,且 G 那步必须用新生成的假样本。
  6. GAN 锐但窄:开放领域已被扩散取代;但作为组件(感知损失、对抗蒸馏 SDXL-Turbo)仍鲜活。
  7. 一步推理是 GAN 的持久优势:无 prefill/decode、无 KV-cache、静态批即最优——这是对抗蒸馏能把 20-50 步扩散压成 1-4 步的根本。

下一节,我们进入桶 3 的进阶——条件 GAN 与 Pix2Pix:把对抗训练从「无条件生成」升级为「图像到图像翻译」,用成对监督 + 对抗损失,实现轮廓转照片、线稿转彩图。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U