跳到主要内容

生成对抗网络 — 让两个网络互相逼着进步

这一章讲三件事: 「生成模型」和前几章的「判别模型」差在哪; 生成器与判别器的博弈怎么写进损失函数;以及一个能跑通的 GAN 从噪声到数字 的完整装配线。读完你能回答「为什么 GAN 的训练时好时坏」。

1. 生成 vs 判别:两个方向的「学」

前面所有章节的网络都在做判别:输入数据,输出标签——学的是「数据 → 答案」的映射。 生成模型(generative model)反着学:目标是抓住数据本身的分布, 然后从分布里造出新的、像真一样的样本——原书的招牌例子: 喂一大堆人脸照片,生成人脸;喂旋律,生成音乐1

问题在于:「像真的一样」没有标准答案可以比对——你没法对一张生成的脸判「对错」。 GAN 的答案是全书最聪明的一步棋:别自己判,雇一个裁判。

2. 机制:造假者与打假者的军备竞赛

GAN(generative adversarial network)由两个网络组成2:

噪声 z ──→ [生成器 G] ──→ 假样本 ──┐
├──→ [判别器 D] ──→ 真 / 假
训练集的真样本 ────────────────────┘

图说:G 的目标——让 D 把假货判成「真」;D 的目标——火眼金睛。
双方在训练中互相逼着进步:裁判变强,造假者必须更精;
造假者变精,裁判必须再学。

原书给这个设计的理论定位:「数据生成器好 = 产出的样本与真数据不可区分」, 这本质是统计里的双样本检验(判断两批数据是否来自同一个分布)—— GAN 的巧思是把「检验」从单纯鉴别变成给生成器供训练信号3

损失函数三件套

博弈要能训练,得写成分数。判别器那份分数,属于分类里最常用的一族损失——名字里带熵(信息论里衡量「不确定程度」的量)。原书的三条式子(记结论就够)4:

优化什么一句话
判别器 D最小化交叉熵(一种标准的「差多远」分数):真样本判近 1、假样本判近 0尽力打假
生成器 G(原版)最小化 −log(1 − D(G(z)))让「假货被判为假」的概率变小
G 的替换版最小化 −log D(G(z))换个方向:直接逼 D 判「真」

第三行是实战经验:当 G 进步太快、D 的梯度趋于消失时,原版目标对 G 几乎给不出梯度, 换成「直接奔着骗过 D 去」的等价改写,训练才稳得住——原书把这个改写讲清楚了, 这是 GAN 训练实践里最重要的一个细节5

3. 主走查:从噪声到手写数字的全流程

原书 6.7 节给了一条完整的 MNIST 装配线(Keras)。把它走成一条流水线, 每个数字都是书里的实配值:

① 数据:MNIST 手写数字,6 万张训练图,每张 28×28
像素缩放到 [−1, +1] (x/255×2−1)——因为生成器输出层用 tanh,
值域也是 [−1,1],两边必须对齐。再摊平成 784 维向量。
② 生成器:输入 100 维噪声(latent_dim=100)
→ Dense(7×7×128) 升维 → 整形成 7×7×128 的小图
→ 两次转置卷积(负责放大)→ 输出 28×28,激活 tanh
③ 判别器:Dense(512) → Dense(256) → Dense(1)+sigmoid → 真/假概率
④ 优化器:Adam(lr=0.0002, β1=0.5)——GAN 圈的经典配方
⑤ 训练(每一轮两步):
训 D:抽一批真图(标签 1)+ G 造一批假图(标签 0)→ 更新 D
训 G:再造一批噪声 → 走 G→D 通路,但标签给 1、且冻结 D
→ 只有 G 的权重被更新(「骗过裁判」成为 G 的梯度来源)
⑥ 看效果:第 0 轮的「生成图」是纯噪声(什么都没学会);
训练推进后,数字轮廓逐渐成形(原书图 6.4 → 图 6.5 的对比)。

两个工程细节值得点名:**「冻结(锁住权重不让更新)D 训 G」**是怎么实现的——把判别器设为不可训练, 接成「噪声 → G → D → 判决」的组合模型,损失照样反向传播、但只更新 G; 「转置卷积」(transposed convolution,别名反卷积)是 G 用来放大的工具—— 第 07 章的卷积把大图缩成小图,它把小图扩回大图,原书算了账: 16×16 输入经转置卷积块(核 4、步长 2、补 1)变成 32×326

4. GAN 的三种病

原书 6.4 节的清单,按危害排序7:

  • 模式坍塌(mode collapse):G 发现「只画一种最骗得过 D 的图」最省事, 于是千张图长得一样——多样性丢了。这是 GAN 最著名的病;
  • 训练不稳定:两个网络互为环境,任何一方突然变强都会把对方打崩, 振荡、原地踏步是常态——第 2 节那个「损失函数换法」就是给这个病打的补丁;
  • 没法评估:分类网络有准确率,生成网络「像不像」没有公认的数—— 原书照实承认这是未解的研究题8

5. DCGAN:把卷积纪律带进 GAN

DCGAN(深度卷积 GAN)不是新算法,是一份「怎么把 CNN 用在 GAN 上才稳」的配方, 原书 6.8 用 PyTorch 在 Pokemon 数据集上走了一遍,配方四条9:

  1. G 用转置卷积放大(不带全连接层),D 用带步长的卷积缩小——对称的漏斗;
  2. 两边都上批归一化(batch normalization:把每层输入拉回稳定的均值方差, 抗训练漂移——原书在这里补了第 04 章「只提名不展开」的欠账);
  3. D 用 leaky ReLU(第 04 章的「防死」),G 输出层用 tanh(对齐 [−1,1]);
  4. 训练尺寸链:G 的转置卷积块把 16×16 翻成 32×32、再翻 64×64; D 的卷积块反过来 16→8→4,最后卷成一个数。

6. 作者的判断与证据

  • 机制与公式完整的: 双样本检验的定位、三件套损失、非饱和替换的动机, 是本章可放心引的部分;MNIST 流水线每个超参数都有实配值10
  • 聊天腔残留(全书最扎眼的证据): 「A full implementation of the DCGAN is beyond the scope of a single response」和「the update_D and update_G functions are not provided in the code snippet you shared」——两句对话体原样留在书里, 后者对应的两个函数全书确实没给,DCGAN 训练代码照抄跑不通11
  • 引用错位(本章最烂的部位): 正文说 GAN 由 Goodfellow 2014 开山, 参考文献列的却是他同年另一篇短文;GAN 总述处挂的引用是 2019 年的自注意力(Transformer 的核心零件)GAN; DCGAN 处补引的 Lee et al. 2009 是卷积深度信念网络论文——三处全错位12。 补充(不在书里,来自通用知识):GAN 的开山论文是 Goodfellow 等, 《Generative Adversarial Nets》,NIPS 2014;DCGAN 是 Radford、Metz、Chintala,2015。
  • 参数自相矛盾: 6.7.9 定义 epochs=10000、每 200 步出样图;6.7.11 又定义 epochs=20000、每 1000 步出样图——两套代码版本缝在一起,取哪套都行,但书没交代13
  • 图注错位: 图 6.5 标题写「1,000 epochs」,正文说的是 10,000 轮14

判断(我们的,不是书里的): GAN 的博弈结构是全书三条先验里最特殊的一条—— 卷积和循环的先验来自数据(空间、时间),博弈的先验来自训练方式本身: 它不假设数据长什么样,假设「可区分性」本身就是可优化的信号。 这个设计的天才和脆弱是同一枚硬币:没有标准答案 → 雇裁判;裁判本身在变 → 训练飘。 如果错,会错在: 如果评估问题被解决(后来的 FID 等分数部分做到了), 「GAN 天生没法评估」就成了历史而非本质;但「训练不稳定源于双方互为环境」 这一条是结构性的,不随评估工具改善。

7. 边界与局限

  • 原书没讲的时代坐标: 补充(不在书里,来自通用知识):GAN 的黄金期约 2014-2021(StyleGAN 的人脸、超分辨率、 图到图翻译);原书 2025 年出版却没有交代扩散模型(diffusion)已接过生成任务的王座—— 今天新学生成模型,应先学扩散,GAN 的价值在思想(对抗、博弈)而非工程首选。
  • 原书没讲: WGAN 为什么稳定(Wasserstein 距离的几何直觉)、条件生成的实现、 以及 GAN 评价分数(FID/IS)——6.5 的变体清单只报了名字。
  • 两个用例的落差: MNIST 用例可跑通(但 DCGAN 训练函数缺失);Pokemon 用例 依赖 d2l 库且训练函数同样缺失——照书复现需要在别的材料里补齐训练循环。

8. 可带走的

  1. 判别模型学「数据→答案」,生成模型学「数据本身长什么样」;
  2. GAN = 生成器造假 + 判别器打假;「不可区分 = 学到位」,本质是统计学的双样本检验;
  3. 损失三件套:D 的交叉熵、G 的 −log(1−D(G(z)))、G 太强时换 −log D(G(z));
  4. 主走查记住四个数:噪声 100 维、像素缩到 [−1,1]Adam(0.0002, 0.5)、 第 0 轮噪声 → 十轮成形;
  5. 「冻结 D 训 G」是 GAN 训练的全部机关:骗过裁判的判决,就是造假者的梯度;
  6. 转置卷积是放大器:16×16 → 32×32;与第 07 章的卷积(缩小)互为逆操作;
  7. GAN 三病:模式坍塌(只会画一样的)、不稳定(双方互为环境)、没法评估;
  8. DCGAN 配方:转置卷积+批归一化+leaky ReLU+tanh 输出;
  9. 本章机制可引,参考文献三处错位、训练代码缺函数、聊天腔残留——引用请绕开它的文献表

9. 原文地图

主题原书章原文位置
生成 vs 判别6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:5(搜「discriminative」) · text/43-ch06-6-generative-adversarial-networks.txt:21(搜「generate new samples」)
人脸生成例6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:23(搜「photorealistic」)
GAN 三词拆解6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:46(搜「correct breakdown」)
Goodfellow 20146 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:43(搜「Goodfellow」)
双样本检验6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:70(搜「indistinguishable」) · text/43-ch06-6-generative-adversarial-networks.txt:71(搜「two-sample」)
D 的 sigmoid 与损失6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:114(搜「binary classifier」) · text/43-ch06-6-generative-adversarial-networks.txt:129(搜「log D」)
G 的损失6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:150(搜「log(1」)
非饱和替换6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:157(搜「too good」) · text/43-ch06-6-generative-adversarial-networks.txt:163(搜「log(D」)
模式坍塌6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:245(搜「Mode Collapse」)
训练不稳定6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:249(搜「Training Instability」)
评估难6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:254(搜「Evaluation and Metrics」)
变体清单6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:284(搜「Conditional GANs」) · text/43-ch06-6-generative-adversarial-networks.txt:294(搜「Wasserstein」)
MNIST 数据与归一化6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:367(搜「28」) · text/43-ch06-6-generative-adversarial-networks.txt:418(搜「255」)
展平 7846 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:449(搜「H * W」) · text/43-ch06-6-generative-adversarial-networks.txt:454(搜「784」)
生成器 latent 1006 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:473(搜「latent_dim = 100」) · text/43-ch06-6-generative-adversarial-networks.txt:480(搜「7 * 7 * 128」)
生成器 tanh 输出6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:466(搜「tanh」)
判别器结构6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:582(搜「Dense(512」) · text/43-ch06-6-generative-adversarial-networks.txt:584(搜「sigmoid」)
Adam(0.0002, 0.5)6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:607(搜「0.0002」)
冻结 D 训 G6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:615(搜「trainable = False」) · text/43-ch06-6-generative-adversarial-networks.txt:617(搜「combined」)
交替训练6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:343(搜「Train the Discriminator」) · text/43-ch06-6-generative-adversarial-networks.txt:798(搜「Train the Generator」)
第 0 轮噪声6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:875(搜「does not yield」) · text/43-ch06-6-generative-adversarial-networks.txt:898(搜「10,000」)
转置卷积 16→326 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:1102(搜「default settings」) · text/43-ch06-6-generative-adversarial-networks.txt:1120(搜「32」)
1×1 输入变 4×46 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:1140(搜「increased by 3」) · text/43-ch06-6-generative-adversarial-networks.txt:1150(搜「4」)
D_block 16→86 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:3(搜「16」) · text/43-ch06-6-generative-adversarial-networks.txt:1329(搜「(2, 20, 8, 8)」)
DCGAN 配方6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:927(搜「Strided Convolution」) · text/43-ch06-6-generative-adversarial-networks.txt:932(搜「Batch Normalization」) · text/43-ch06-6-generative-adversarial-networks.txt:936(搜「Leaky ReLU」)
权重初始化 N(0,0.02)6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:1379(搜「0.02」)
聊天腔两句6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:954(搜「single response」) · text/43-ch06-6-generative-adversarial-networks.txt:1436(搜「you shared」)
引用错位三处6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:1515(搜「distinguishability」) · text/43-ch06-6-generative-adversarial-networks.txt:1539(搜「Self-attention」) · text/43-ch06-6-generative-adversarial-networks.txt:1524(搜「Lee, H.」)
参数自相矛盾6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:695(搜「epochs = 10000」) · text/43-ch06-6-generative-adversarial-networks.txt:773(搜「epochs = 20000」)
图注错位6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:909(搜「1,000 epochs」) · text/43-ch06-6-generative-adversarial-networks.txt:898(搜「10,000」)
批归一化的四条理由6 Generative Adversarial Networkstext/43-ch06-6-generative-adversarial-networks.txt:546(搜「Importance of using Batch」) · text/43-ch06-6-generative-adversarial-networks.txt:550(搜「Training Speed」)

Footnotes

  1. 出处:「6 Generative Adversarial Networks」第 5 段(text/43-ch06-6-generative-adversarial-networks.txt:5,搜「discriminative」)与第 23 段(搜「photorealistic」)。原文:生成建模要学训练数据的底层分布,产出「像能放进原数据集」的新样本。

  2. 出处:「6 Generative Adversarial Networks」第 52 段(搜「Adversarial」)。原文:生成器造合成样本,判别器分辨真(训练集)与假(生成);造假者想骗过裁判,裁判想准确分类。

  3. 出处:「6 Generative Adversarial Networks」第 69 段(搜「indistinguishable」)与第 71 段(搜「two-sample」)。原文:生成器好=与真数据不可区分,类似统计学的双样本检验;GAN 把检验用作训练信号、迭代改进生成器。

  4. 出处:「6 Generative Adversarial Networks」第 129 段(text/43-ch06-6-generative-adversarial-networks.txt:129,搜「log D」)(判别器交叉熵:D(x)=1/(1+e^(−o)) 在第 118 段);第 150 段(搜「log(1」)(生成器原版目标)。

  5. 出处:「6 Generative Adversarial Networks」第 157 段(搜「too good」)与第 163 段(text/43-ch06-6-generative-adversarial-networks.txt:163,搜「log(D」)。原文:G 太好、D 梯度变小时,改用最小化 −log D(G(z)) 以防 G 压过 D、保持平衡训练。

  6. 出处:「6 Generative Adversarial Networks」第 473 段(搜「latent_dim = 100」)、第 418 段(搜「255」)、第 448 段(搜「H * W」)、第 607 段(搜「0.0002」)、第 615 段(搜「trainable = False」)、第 778 段(搜「Train the Discriminator」)、第 798 段(搜「Train the Generator」)、第 875 段(搜「does not yield」)、第 898 段(搜「10,000」);转置卷积 16→32 在第 1102-1120 段(:1102,搜「default settings」)。生成器结构 Dense(7×7×128)→Reshape→两次 Conv2DTranspose→tanh 在第 480-497 段;判别器 Dense 512→256→sigmoid 在第 582-584 段。

  7. 出处:「6 Generative Adversarial Networks」第 245 段(text/43-ch06-6-generative-adversarial-networks.txt:245,搜「Mode Collapse」)。原文:模式坍塌=生成器产出有限且重复的样本、忽略训练数据的多样性;诱因常是判别器过强。

  8. 出处:「6 Generative Adversarial Networks」第 254 段(搜「Evaluation and Metrics」)。原文:传统评估指标(准确率/损失)难以刻画生成样本的质量与多样性,可靠指标是进行中的研究方向。

  9. 出处:「6 Generative Adversarial Networks」第 927 段(搜「Strided Convolution」)、第 932 段(搜「Batch Normalization」)、第 936 段(搜「Leaky ReLU」)、第 940 段(搜「No Fully Connected」);尺寸链 16→32 在第 1102-1120 段、D 侧 16→8 在第 1305-1310 段;权重初始化 N(0,0.02) 与 Adam betas=[0.5,0.999] 在第 1377-1387 段(:1379,搜「0.02」)。

  10. 出处:「6 Generative Adversarial Networks」第 69-175 段(机制)与第 358-830 段(MNIST 用例);主走查各实配值的出处已在 6 逐条给出。

  11. 出处:「6 Generative Adversarial Networks」第 954 段(text/43-ch06-6-generative-adversarial-networks.txt:954,搜「single response」)与第 1436 段(搜「you shared」)。原文分别是「beyond the scope of a single response」与「not provided in the code snippet you shared」;update_D/update_G 全书未提供。

  12. 出处:「6 Generative Adversarial Networks」第 1515 段(搜「distinguishability」)、第 1539 段(搜「Self-attention」)、第 1524 段(搜「Lee, H.」)。正文第 43 段称 GAN 出自 Goodfellow 2014 开山论文,文献列的却是同年短文《On distinguishability criteria...》;GAN 总述(:32)挂 Zhang et al. 2019(自注意力 GAN);DCGAN 处补引 Lee et al. 2009(卷积 DBN)。补充(不在书里,来自通用知识):GAN 开山论文为 Goodfellow et al.《Generative Adversarial Nets》(NIPS 2014);DCGAN 为 Radford, Metz & Chintala(2015,arXiv:1511.06434)。

  13. 出处:「6 Generative Adversarial Networks」第 695 段(搜「epochs = 10000」)与第 773 段(搜「epochs = 20000」)。前一处 sample_period=200,后一处 sample_interval=1000。

  14. 出处:「6 Generative Adversarial Networks」第 909 段(text/43-ch06-6-generative-adversarial-networks.txt:909,搜「1,000 epochs」)与第 898 段(搜「10,000」)。正文讲 10,000 轮后的生成效果,图 6.5 标题却是「Image generation after 1,000 epochs」。