第13章的标题虽然是“深度生成模型”,但它真正想回答的问题只有一个:机器到底能不能“创造”?我第一次把这章内容放进整套学习资料时,团队里有人质疑:前面12章都在教模型怎么识别、怎么预测、怎么做序列翻译,怎么突然转到生成?我的回答很简单:正因为前面把判别模型的路走到头了,才会轮到生成模型登场。在这章里,生成不再是魔法,而是概率分布的另一种玩法。
这章适合谁读?适合那些已经会用某个主流的自动微分框架写完分类网络、看过损失函数曲线、被过拟合折磨过,但还从没让模型输出过“新东西”的读者。你会看到三类主流技术路线——自回归模型、变分自编码器、生成对抗网络,以及现在讨论热度最高的扩散模型。耐心看完后,你至少能回答三个问题:生成模型到底在优化什么?不同路线之间为什么差那么多?我自己的任务该选哪条路?
1. 第13章在整套学习路径中的位置:从“学会判断”到“学会生成”
1.1 为什么生成模型被刻意放在后面
很多初学者拿到课程大纲,第一个翻的就是生成模型章节,因为他们听说“AI绘画”“AI写诗”都是这么来的。但我可以明确说:如果前面12章你没有认真走完,第13章几乎不可能真正读懂。
原因很简单。生成模型不是一项独立技术,它是前面所有知识点的汇总。你需要理解梯度下降怎么让损失函数变小,才能看懂生成模型里那个复杂的博弈训练过程;你需要知道卷积和注意力机制怎么提取特征,才能明白生成器里那些上采样层在干什么;你需要踩过过拟合的坑,才能真正理解为什么生成模型训练到后期会“记住”训练集而不是“学会”分布。
所以这章在整套教材里更像一个“验收关卡”。我见过某个A同学,前面分类网络写得飞起,结果第一次做生成模型,卡了整整三天,最后发现他连“生成得好不好”这个基本问题都答不上来。这不是因为他笨,而是因为判别任务做久了,他默认“模型输出一个标签、我算一下准确率”就是评价标准。生成模型里没有这种标准答案,你必须有对概率分布和数据形态的直觉,而这种直觉只能靠前面的实战慢慢攒。
1.2 判别模型与生成模型:保安和画像师的差别
要理解生成模型的本质,最好先把它和判别模型放在一起对比。判别模型学的是决策边界。给它一张图,它输出“猫”或“狗”的概率。它根本不需要知道猫长什么样、毛发质感如何,只要能把两类分开就行。就像一个保安,他不需要会画嫌疑人画像,只要能认出来者是不是名单上的人就行。
生成模型学的是数据本身的分布。它要学习的不是p(标签|图像),而是p(图像)这个联合概率,或者至少学习一个能从中采样的近似分布。给它一堆猫的照片,它得能“画出”一只从来没见过但看起来很真实的猫。这就像画像师,光靠嘴说“这人脸型偏方、眼睛不大”就能落笔,因为他脑子里已经内化了一整套人脸的结构规律。
这个区别解释了为什么生成模型普遍比判别模型难训练。分类任务只需要抓住少数区分性特征,生成任务却要对所有特征都有把握。你可以不关心猫的胡须是几根就把猫认出来,但如果你生成一只猫时漏了胡须,画面马上就不自然。联合分布就是这样一个“一个都不能少”的东西。
1.3 读完这一章前,你最好已经掌握什么
我列一份自查清单,不是为劝退,是为了让你读这章时不至于卡壳。
- 能独立实现并训练一个多层神经网络,对交叉熵损失有一定直觉;
- 知道反向传播是在干什么,理解“梯度不更新”意味着网络可能哪里断了;
- 会做最基本的图像预处理,比如归一化、尺寸调整、数据划分;
- 有被过拟合折磨过的经历,知道dropout、正则化大概怎么运作;
- 至少有一次把训练过程中的中间产物可视化出来,看一眼特征图长什么样。
没有这些前置知识,你也能“跑通”代码,但遇到问题时会像在黑箱子里找开关,无从下手。我自己带人做项目时,只要发现对方连“验证集loss比训练集高很多”都判断不出原因,就会先让他回头补前面章节。这不是门槛,而是保护你不在第13章浪费太多无意义的时间。
2. 四条技术路线逐一拆开:从自回归到扩散模型
2.1 自回归生成:一个字一个字“猜”出来的图像
自回归模型是很好理解的一条路线。它的核心思想是把一个复杂对象的生成,拆成一连串有序的单步预测。拿图像举例,一张28×28的灰度图有784个像素点,自回归模型就把它当成一个有784个“字符”的序列,每次预测下一个像素的值,然后把预测到的值当成输入,继续预测再下一个。用公式写就是p(x)=p(x1)p(x2|x1)p(x3|x1,x2)…,把联合分布拆成了条件分布的连乘。
这个思路之所以重要,是因为它把“生成”变成了“序列建模”。这样一来,自然语言处理里积累的大量成熟技巧都能迁移过来。文本本身就是序列,语音也是一帧一帧的序列,所以自回归路线在语音合成、文本生成这些领域长期是主力。
不过自回归模型也有明显短板。第一,生成速度慢。因为必须一个接一个地预测,等你把一张图的所有像素都“读”完,图像早就生成完了。这个串行过程无法直接并行加速。第二,误差会累积。前面某个像素预测偏了,后面所有条件分布都建立在错误基础上,最后生成出来的东西可能越来越离谱。所以我在做这类实验时,通常会特别关注“早期预测是否正确”,这个问题往往比后期微调更关键。
2.2 变分自编码器:隐变量里的压缩与还原
变分自编码器(VAE)走的是另一条路。它不把图像当序列,而是假设每张图背后存在一个低维的隐变量z,这个z包含了“这张图是什么”的核心信息。比如z里某个维度可能表示了物体形状,另一个维度表示了背景亮度。生成过程就是先从先验分布里采样一个z,再让解码器根据z生成图像。
听起来很直观,但训练时有一个问题:我们不知道每个样本背后真正的z是什么,而做梯度下降又要求每一步都可导。VAE的解决办法是重参数化技巧:把“从某个分布里采样”这一步,改写成“先从标准正态分布里采样噪声ε,再用均值μ和标准差σ把它线性变换过去”。这样整个采样过程就变成对μ和σ的可导操作了。代码逻辑大致是这样:
# 伪代码,演示重参数化核心逻辑 def reparameterize(mu, logvar): std = exp(0.5 * logvar) eps = random_normal_like(std) return mu + eps * stdVAE训练时优化的目标叫ELBO,你可以把它粗理解为两部分:一部分是“重建损失”,逼着生成图像跟原图像素接近;另一部分是KL散度,逼着编码器输出的隐变量分布不要离标准正态分布太远。这个KL项很重要,它像一个约束器,让隐空间变得规整、连续。没有了它,模型为了偷懒,会把每个样本单独编码到互不连通的区域,生成时随便采一个中间点,得到的图像就会糊成一团。
VAE最大的优点是训练稳定。它没有对抗博弈,用的还是“编码—解码—重建”这种熟悉套路。缺点也明显:因为它对像素级别的重建要求太强,反而容易忽略全局结构,生成的图像趋于模糊。但这不意味着VAE过时,很多需要操作隐变量的任务,比如图像编辑、异常检测,到现在仍然大量使用它。
2.3 生成对抗网络:让判别器当裁判
生成对抗网络(GAN)是另一座里程碑。它不是让模型直接拟合分布,而是巧妙地把生成问题变成两个网络之间的博弈。生成器负责把随机噪声变成尽量真实的样本,判别器负责区分哪个是真实数据、哪个是生成器伪造的。随着对抗升级,生成器越来越会骗,判别器越来越能分辨,最后生成器产出的样本就能以假乱真。
我用一个类比来理解它:生成器是造假者,判别器是验钞机。造假者每做出一版假钞,验钞机就升级一次防伪能力,然后造假者再根据漏洞改进工艺。这个循环如果顺利,最终会达到一种纳什均衡:生成器输出的样本和真实样本在判别器眼里几乎无法区分。
训练目标写出来就是minimax博弈:生成器想让判别器对生成样本的输出概率接近1,判别器想让真实样本的输出概率接近1、生成样本接近0。这个目标的特殊之处在于,生成器不是直接拿“像素差”当损失学,而是通过“能不能骗过判别器”来学。这既让GAN能生成非常锐利的图像,也让训练过程天然不稳定。我在后面第3章会专门讲这里的坑。
2.4 扩散模型:从噪声里一步一步“显影”出图像
扩散模型是这几年绕不开的话题。它的思路特别像“逆向显影”:训练阶段,我们给一张干净图像逐步加噪,加一次噪声、再加一次噪声,直到它彻底变成一堆高斯噪声;生成阶段,模型学习反向操作,从纯噪声开始一步步去噪,每一步都把图像“显影”得更清晰一点。
这个设计的妙处在于:训练时每一步的代价函数其实都是一个去噪回归任务,目标非常明确,不像GAN那样有对抗博弈。所以扩散模型训练起来远比GAN稳定,模式坍塌问题也少得多。而且它对覆盖全部数据分布很“上心”,不会像某些GAN那样只挑容易骗过判别器的模式去生成。
扩散模型最明显的缺点是采样速度慢。以前GAN一次前向推理就能出图,扩散模型要做几十步甚至上千步去噪,生成成本高很多。后来业界用了各种加速采样技巧,比如减少步数、蒸馏、隐空间扩散等,才把它推到实用水平。如果你时间有限,至少要理解反过程“从噪声回推图像”是一个什么样的条件概率建模过程,这对后面调接口、换采样器都有帮助。
3. 我实际训练中最想删掉的三个坑:坍塌、波动和不知道怎么打分
3.1 模式坍塌:生成器“偷懒”的话,判别器也拦不住
模式坍塌是我见过最多、也最让人头疼的问题。现象很典型:生成器每轮生成的样本几乎一模一样,有时候是同一张脸,有时候是同一段花纹。表面上看生成质量似乎还行,但多样性全无。
背后的逻辑是:生成器优化目标是骗过当前的判别器,它只要找到判别器最容易失误的那一小块区域,不停输出这个区域里的样本,就能快速降低自己的损失。它没必要去覆盖训练数据里的所有模式,因为覆盖更多模式意味着在每类上的表现都可能变弱,反而更容易被抓到破绽。这就像学生背题,发现某类题必考、背熟就能及格,于是干脆放弃其他题型。
缓解手段我实际用过好几种。给判别器目标加标签平滑,让它不要对真实样本打出“1.0”这种绝对自信的分数;把生成器和判别器的学习率调低,尤其是判别器不能学太快;用小批量判别或特征匹配这类技巧,给判别器增加对“整批样本多样性”的感知。最笨但最有效的办法是:每训练一定轮数,就把当前生成器产出的样本存成图片,人眼盯一遍。我一直强调,看生成样本不仅是检查质量,更是在监测多样性。
3.2 损失函数在跳,不代表训练在崩溃
很多人一开始训练GAN就慌,因为loss曲线永远在震荡。这个需要说明白:对抗训练的本质就是两个网络的损失互相拉扯,D想让“真实/生成”分得越开越好,G拼命想让生成样本被判定为真。所以loss有波动是常态,不是错误信号。
真正需要警惕的是两种极端。第一种,判别器损失长期趋近于0,说明判别器太强,生成器给出的梯度信号基本没有方向,再训练下去就是原地打转。第二种,生成器损失一路走低、但生成样本肉眼可见地变成同一张模糊脸,这多半是模式坍塌,而不是训练成功。
我推荐的实操判断动作是:每500步记录一次判别器对真实样本的置信度、对生成样本的置信度,再配上三张生成样本快照。不要只看单一曲线,而要交叉看“判别器是否平衡”和“生成样本的具体形态”。光看loss,很容易被一句“训练稳定”骗过去,甚至模型早就不学了还不知道。
3.3 评估该看什么:从肉眼到FID
生成模型不好评估,这是行业公认的。我踩过最深的坑就是拿生成loss高低当质量标杆,结果两个模型一个loss低但全生成重复图,另一个loss高但图很漂亮。loss是训练信号,不是质量度量。
肉眼比较是最直接的,但主观性太强。后来我主要看FID这类指标。FID的思路是:把真实样本和生成样本分别输入到一个训练好的特征提取网络里,取中间特征,然后计算这两组特征在高维空间里的分布距离。分布越接近,说明生成样本越能覆盖真实样本的多样性,这比单看每张图是否清晰更有意义。
实操中有几个细节要留心。计算FID时,样本数量不能太少,否则统计波动很大。我一般至少用5000张生成图去比真实图。如果算出来FID一阵高一阵低,先检查是不是生成样本数量、随机种子、图像缩放方式不一致。这些细节经常让实验结论翻转。有人只看指标高低,却忽略特征提取器的输入分辨率没有对齐,最后得出完全相反的结论。这类低级错误,我自己就犯过。
4. 模型选型表:什么任务该用哪条路线
4.1 图像与视频生成:扩散模型为主,GAN仍适合低延迟
现在做图像生成,扩散模型基本是默认首选。它生成的样本质量高、模式覆盖全,不容易出现“只会生成某一类图”的问题。代价是采样速度慢,在交互式场景里可能要等上几秒,这在部分产品里不可接受。
GAN的优势是单次前向推理出图,速度快,适合实时性要求高的场景,比如风格迁移、特效滤镜、实时人像编辑。但它的训练难度和模式坍塌风险是实打实的,生产环境里维护起来相当费劲。
我在项目里通常这样判断:如果是离线批量生成、对质量要求高,用扩散模型;如果需要实时出图、能接受偶尔的模式偏差,用GAN。当然两者都能用,但各自的工程复杂度差别很大,选择其实就是取舍。
| 场景 | 推荐路线 | 关键理由 | 主要风险 |
|---|---|---|---|
| 离线高质量图像生成 | 扩散模型 | 覆盖全面、清晰度高 | 采样慢,推理成本高 |
| 实时风格迁移 | GAN | 单次推理,速度快 | 训练不稳定、易模式坍塌 |
| 图像编辑/隐空间操作 | 自编码器系列 | 隐变量便于控制语义 | 生成细节可能偏模糊 |
| 文本/语音序列生成 | 自回归模型 | 天然契合序列结构 | 串行采样慢、误差累积 |
| 小样本适配 | 预训练生成模型微调 | 收敛快,效果稳定 | 依赖源头数据质量 |
4.2 文本和序列生成:自回归路线仍是主角
文本生成跟图像生成不太一样。文本天然是离散序列,自回归模型每一步预测一个词,正好贴合“一字一句写出来”的过程。虽然现在也有“一次生成整段序列”的尝试,但从实际稳定性和可控性来看,自回归路线依然是主力。
原因很好理解:语言中的依赖关系高度复杂且依序展开,前面一个词的选择会影响后面整句结构。只有按照从左到右的顺序逐一预测,模型才能把已经生成的上下文都纳入下一词的条件。那种直接并行生成所有词的方案,很容易丢失长程依赖。所以在文本任务里,我基本默认用自回归模型,只是在推理时关注解码速度。
4.3 资源受限时怎么办:小模型微调和蒸馏
不是所有人都有从头训练一个生成模型的算力。现实点的做法是:拿一个别人训练好的生成模型,在自己领域的小数据集上微调。这里的技巧在于,不要一上来就用很大学习率把整个模型都改动,否则会把预训练阶段学到的通用知识冲掉。
我一般先冻结网络的大部分层,只微调输出层和靠后的一部分模块,用更低的学习率、小批数据跑几十轮,观察生成样本是否开始带上目标领域特征。如果效果还不够,再逐步解冻更多层。如果解冻太多层,模型在小数据上容易过拟合,生成内容会退化成“背训练集图片”。这个小数据适配的思路,性价比远高于从头开始训练。
5. 动手路线图:把第13章变成你手下的代码
5.1 用最小数据集跑通一条完整的训练链路
别一开始就冲向高分辨率图像,那只会让你把所有时间耗在等待和调参上。我建议用类似手写数字识别那种28×28灰度小图起步,目标是“让模型生成肉眼可辨的形状”,而不是追求惊艳效果。
推荐复现顺序是:先写一个VAE,它能让你熟悉隐变量、重建损失、KL散度这一套;然后写一个GAN,感受对抗训练的不稳定;最后试扩散模型,体会去噪过程。每一步都不要急着加花活,先按默认参数跑通一遍。跑通的意思是你已经能从随机噪声出发,在训练结束后看到一组看起来还算合理的生成结果。只要这个链路跑通了,后面换数据集、换网络结构都是水到渠成的事。
5.2 调参经验:学习率、批大小、梯度惩罚
我把自己压箱底的经验值列一下,供你起点参考。优化器用Adam,学习率在2e-4到1e-4之间;批大小要么64要么128,太小会让样本估计波动大,太大会让训练变慢;生成网络的激活函数、归一化方式也要小心,小批量时层归一化往往比常用的批归一化更稳;GAN里偶尔需要梯度惩罚,它能在判别器过强时给一个缓冲。
判断训练是否健康,我养成了一个习惯:定期打印“真实样本在判别器上的平均置信度”和“生成样本在判别器上的平均置信度”。如果前者长期维持在0.9以上、后者长期低于0.5,说明判别器太强,生成器学不到有效信号。此时我会调低判别器学习率,或者增加生成器每轮更新的次数。这些都是非常琐碎、但真的有用的经验。
5.3 安全边界:生成内容不是用来“造谣”的
技术在飞速进步,但一个负责任的工程师必须想清楚:生成式模型可以产生逼真的图片、文本、语音,同样可以用来制造虚假信息、伪造人像、批量生成歧视性或低俗内容。这章讲的是技术能力,但用在哪里,是使用者的问题。
我自己在做生成模型相关项目时,一定会加一道合规审查:确认数据来源合法、生成内容不会误导他人、不对弱势群体造成伤害。建议你也把这个习惯写进自己的工作流。技术不应该被粗暴限制,但使用者应该有边界感。第13章教你的是“怎么生成”,而“生成什么”这个问题,永远需要你来回答。
最后再分享一点体会。很多人学完生成模型,第一反应是赶紧换更大数据集、上更多显卡。我反而建议你在最小例子上多停留一阵:把生成过程中的中间结果存下来,观察模型从“噪声”到“轮廓”再到“细节”的演化。这个阶段积累的直觉,比任何花里胡哨的榜顶分数都值钱。踩过几次坑之后你会明白,生成模型的难点从来不只在数学公式里,更多是在你面对一幅模糊图像时,还能不能冷静判断“它现在是欠拟合、收敛太慢,还是已经跑偏了”。把这一步想明白,第13章才算真的变成你自己的东西。