生成对抗网络 (GAN)
GAN 不写下概率密度,也不最大化似然:它让两个网络对弈。生成器把随机噪声变成样本,判别器判断样本是真是假,生成器再顺着判别器的梯度改进自己。本节推导最优判别器和它背后的 Jensen-Shannon 散度,在浏览器里实时训练一个二维 GAN,再逐个拆解 GAN 出名难训的原因:梯度饱和、模式坍缩、博弈不收敛,以及非饱和损失、Wasserstein 评论家和 R1 正则这些对策;最后看条件 GAN 怎样给机器人生成多模态动作,以及判别器怎样在 GAIL 和 AMP 里变成奖励。
1为什么机器人需要它
机器人学习里有大量“一对多”的问题。同一个杯子可以从左边抓,也可以从右边抓;同一个障碍物可以从左绕,也可以从右绕;仿真里的同一张图像,换到真实相机下可以有无数种光照和纹理。用均方误差去回归这类目标,网络会学到各个答案的平均:两种抓法的平均是抓在杯把和杯身之间的空气里,两条绕行路线的平均正好撞上障碍物。我们需要的不是平均值,而是一个能采样的模型:每次给出一个合理的、属于某一种模式的答案。这就是第 19 章的生成模型要做的事。
19.1 节的 VAE 走的是似然路线:写出一个潜变量模型,最大化对数似然的下界 ELBO。生成对抗网络(GAN,Goodfellow 等,2014)换了一条完全不同的路:不写密度,只要求“骗得过一个裁判”。生成器 \(G\) 把噪声 \(\mathbf z\) 映射成样本 \(G(\mathbf z)\);判别器 \(D\) 是一个二分类器,输出“这个样本来自真实数据”的概率;两者对着同一个目标一个最大化、一个最小化。训练好的生成器只需一次前向传播就能出一个样本,样本往往很清晰(VAE 的样本常常偏模糊),代价是训练很不稳定。理解它为什么不稳定,以及每一个“训练技巧”背后的数学,是本节的主线。
它和机器人的关系不止于生成图片。判别器“区分专家与非专家”的能力本身就很有用:GAIL 把它当作奖励来做模仿学习(20.6 节),AMP 用它让腿式机器人和仿真角色学出自然的动作风格;在 sim-to-real 里,GAN 被用来把仿真图像“翻译”成看起来像真实相机拍的图像。
2直觉:伪造者与鉴定师
想象一个伪造者(生成器)和一个鉴定师(判别器)。鉴定师看一堆真品和一堆伪造品,学会给每件东西打一个“是真品”的概率 \(D(x)\)。伪造者看不到真品,只能看到鉴定师的打分,并朝着“让分数变高”的方向改进伪造手法。如果鉴定师已经做到最好,他在 \(x\) 处给出的分数应该是多少?在 \(x\) 附近,真品出现的密度是 \(\hl{pdata}{p_{\text{data}}(x)}\),伪造品出现的密度是 \(\hl{pg}{p_g(x)}\),那么一件落在 \(x\) 的东西是真品的概率就是两者之比:
(两堆一样多时;第 6 节会从损失函数严格推出它。)这一个式子已经说明了 GAN 的很多性质。伪造品与真品完全一样时,\(D^*\equiv\tfrac12\),鉴定师只能瞎猜,这正是训练的终点。伪造品离真品很远、两堆不重叠时,\(D^*\) 在真品上是 1、在伪造品上是 0,鉴定师“完美”,可伪造品附近的 \(D^*\) 是一片平坦的 0:伪造者顺着分数往上爬,却没有坡可爬。下图让你亲手摆放生成器的分布 \(p_g\),看最优判别器怎样随之变化,并读出两者之间的 Jensen-Shannon 散度(JS):它就是“最优鉴定师能把真假分得多开”的度量,定义和性质见第 6 节。
- 用一个高斯,把 \(p_g\) 拖到远离数据的一侧(均值 \(|m|>3\))并调窄(σ < 0.3):JS 超过 \(\log 2\) 的 99%,\(D^*\) 在数据上几乎是 1、在 \(p_g\) 上几乎是 0,而且这时再左右拖动,JS 几乎不变。
- 切换到“两个高斯”,把两个均值和宽度对准数据,使 JS < 0.01:\(D^*\) 在每一处都接近 ½,\(V(D^*,G)\) 接近 \(-\log4\approx-1.386\)。
最优判别器把“两个分布差多少”变成了一个可以用分类器学出来的量。GAN 的生成器其实是在最小化 JS 散度,只不过这个散度从来没被显式算过,而是由一个正在学习的判别器近似。也请留意单个高斯的情形:要盖住两个峰,最小的 JS 是 0.162(均值 0、σ ≈ 1.24,把两个峰都罩住),而只贴住一个峰(均值 ±1.2、σ = 0.35)是 JS = 0.215 的一个局部极小。两个解都是稳定点,梯度下降落在哪个取决于起点。
3动手:在浏览器里训练一个 GAN
FIG 1 里的 \(D^*\) 是用真实密度算出来的;真实的 GAN 两边都不知道密度,只有样本。下图是一个真正在训练的 GAN:生成器 \(G\) 是一个 2→24→24→2 的 MLP(leaky ReLU),把二维高斯噪声 \(\mathbf z\) 变成平面上的一个点;判别器 \(D\) 是 2→24→24→1 的 MLP,输出一个 logit \(l(x)\),\(D(x)=\sigma(l(x))\)。每次迭代:
- 判别器一步:取 32 个真样本和 32 个 \(G(\mathbf z)\),用二分类交叉熵(16.1 节)把真样本推向 1、假样本推向 0,Adam 走一步。
- 生成器一步:再取 32 个 \(\mathbf z\),把 \(G(\mathbf z)\) 送进判别器,判别器参数不动,只把损失对判别器输入的梯度 \(\partial L/\partial x\) 反向传回生成器(16.3 节的反向传播:一路穿过 \(D\),再穿过 \(G\)),更新 \(G\) 的参数。
默认用“非饱和”生成器损失 \(-\log D(G(\mathbf z))\),第 4 节解释为什么不用原始的那个。背景颜色是当前判别器的判断:越绿越像“真”,越红越像“假”;青色箭头是判别器给每个生成样本的“推力”\(-\partial L_G/\partial x\),也就是 \(\hl{gradx}{\nabla_x\log D(x)}\) 的方向。
- 选“8 峰”,按“训练”:先是一团琥珀点被红色背景推开,几百次迭代后它们分裂成几股、各自爬向绿色区域。训练到 8 个峰都被覆盖且精确率 ≥ 0.8(默认种子约 1500 次迭代)。
- 把损失切到“minimax(饱和)”,选“2 簇”数据(或按“重置”),按“D 先练 500 步”(只训练判别器、不动生成器),再单步一次:读数里 minimax 梯度不到非饱和梯度的 0.2 倍。箭头也明显变短了:判别器越有把握,原始损失给生成器的信号越弱。
(1) 损失不是进度条:判别器损失停在 \(2\log2\approx1.39\) 附近(这里大约在 1.2 到 1.4 之间)来回摆,既不单调下降,也不说明样本好坏;样本要看图或看精确率/召回率。(2) 生成器从来没见过真数据:它的全部信息都来自判别器的输入梯度(青色箭头)。判别器把“真数据在哪”编码进自己的梯度场,生成器只是顺着这个场往前走。(3) 在“8 峰”上,琥珀点在峰与峰之间常留下细细的“桥”:生成器是一个连续函数,把连通的高斯噪声映射到 8 个分开的峰时,必然有少量样本落在中间。(4) 换成“圆环”(一个连续的环,例如绕圆柱一周的抓取位置):默认种子下约 850 次迭代后精确率和召回率都超过 0.9,右侧两条曲线都收拢到 ½,判别器沦为瞎猜,正如 \(D^*=\tfrac12\) 所预言。
4两种失败:梯度饱和与模式坍缩
原始损失为什么会“饱和”
Goodfellow 等的原始目标里,生成器最小化 \(\hl{mm}{\log(1-D(G(\mathbf z)))}\)。问题出在训练初期:生成样本很差,判别器很容易认出它们,\(D(G(\mathbf z))\approx0\)。此时 \(\log(1-D)\) 对 logit 的导数是 \(-D\approx0\):判别器越有把握,生成器的梯度越小,就在它最需要学习的时候。原论文已经给出了补救:改成最小化 \(\hl{ns}{-\log D(G(\mathbf z))}\),对 logit 的导数是 \(-(1-D)\approx-1\)。两个损失的不动点相同(都希望 \(D(G(\mathbf z))\) 变大),但信号的强弱正好颠倒:原始损失按 \(D\) 加权每个样本,非饱和损失按 \(1-D\) 加权。第三种做法是 WGAN(Arjovsky 等,2017):判别器不再输出概率,而是一个受 1-Lipschitz 约束的“评论家”\(f\),生成器最小化 \(\hl{wgan}{-f(G(\mathbf z))}\)。
下图把三者放在一个能精确求解的例子里比较:真数据是 \(\mathcal N(1.5,\,0.3^2)\),生成器是 \(\mathcal N(\theta,\,0.3^2)\),只有一个参数 \(\theta\)。两个等宽高斯之间的最优判别器 logit 恰好是 \(x\) 的线性函数,所以可以把“判别器强度”\(\beta\) 写成 logit 的倍数:\(\beta=1\) 是最优判别器,\(\beta\) 小一些是“没练好、拿不准”的判别器。对每个 \(\theta\),图中给出生成器损失对 \(\theta\) 的梯度大小(判别器固定)。
- 保持 \(\beta=1\)(最优判别器),把 \(\theta\) 拖到 \(-2\) 或更左(与数据相距 ≥ 3.5):原始损失的梯度跌到 \(10^{-6}\) 以下,而非饱和损失的梯度超过 10。
- \(\theta\) 留在 \(-2\) 或更左,把判别器强度 \(\beta\) 降到 0.1 或以下:原始损失的梯度比同一 \(\theta\) 下 \(\beta=1\) 时大 1000 倍以上(读数给出这个倍数)。一个“拿不准”的判别器反而给出了有用的梯度。
读数里还给出 JS 和 Wasserstein 距离 \(W=|1.5-\theta|\)。随着 \(\theta\) 远离,JS 趋于 \(\log2\) 后就几乎不再变化,它对 \(\theta\) 的导数趋于 0;\(W\) 却始终以斜率 1 增长。这就是 WGAN 的出发点:在两个分布几乎不重叠时(高维里的常态,真实图像只占像素空间里极薄的一层),JS 失去了“还差多远”的信息,而 Wasserstein 距离保留了它。注意非饱和损失的梯度也不是“越大越好”:它随距离线性增长,判别器很尖锐时会给出很大、很吵的梯度,这是 FIG 2 里有时需要较小学习率的原因之一。
模式坍缩:对一个固定判别器的最优回应
GAN 最出名的失败是模式坍缩:生成器只产出数据里的一种或几种模式,例如只会从一个方向去抓杯子。原因藏在目标的顺序里。理论上我们解的是 \(\min_G\max_D V\):对每个 \(G\),判别器先做到最好,生成器再选最好的 \(G\)。可是交替梯度下降里,生成器每一步面对的是一个固定的判别器。而对一个固定的 \(D\),生成器的最优回应是什么?它的损失 \(-\mathbb E_{x\sim p_g}[\log D(x)]\) 对 \(p_g\) 是线性的,线性函数在概率单纯形上的最小值落在顶点:把所有质量放在 \(D\) 最大的那一点。判别器随后发现“这一点全是假货”,把那里的 \(D\) 压低,生成器又整体跳到下一个 \(D\) 最高的地方……这就是模式跳跃。
下图把这个机制剥离出来,用一个可以精确计算的离散版本:抓取器有 8 个接近方向,示教数据 \(p\) 均匀分布在这 8 个方向上;生成器是 8 个方向上的分布 \(q=\operatorname{softmax}(\boldsymbol\theta)\);判别器每隔 \(m\) 步重新算成当前 \(q\) 下的最优判别器 \(D_k=p_k/(p_k+q_k)\),其余时间保持不动;生成器在两次刷新之间用学习率 \(\eta\) 对非饱和损失做梯度下降。
- 先按“重置”,“判别器刷新”选“冻结”,按“运行”:生成器把 95% 以上的概率堆到一个方向上(η = 3 时约 130 步后是方向 3)。继续运行,约 1000 步时它又整体搬到方向 5,冻结的判别器在那里打分最高(\(D_5\approx0.87\)):对固定判别器的最优回应就是它最大值处的一个点质量。这两个方向在数据里都不比别的方向更常见(数据是均匀的)。
- 选“每 30 步”,保持 η = 3,重置后运行:占多数的方向至少换 3 次,生成器在方向之间来回跳,始终没有覆盖全部 8 个方向。
- 选“每步”(判别器始终最优),重置后运行:\(q\) 收敛到均匀分布,JS < 0.001 且每个方向都超过 10%。同样的学习率,只是判别器不再过时。
真实的 GAN 介于这几种情形之间:判别器只走几步、永远“半过时”,生成器每一步又会同时移动所有样本(它是一个共享参数的函数,FIG 4 里的 softmax 也一样)。所以坍缩是否发生取决于 \(\eta\) 与 \(m\) 的乘积这类“生成器在判别器跟上之前能走多远”的量:试试把 η 调到 1,再选“每 30 步”,它会收敛。对策都围绕这个机制:让判别器“看见”一整批样本的多样性(minibatch discrimination,Salimans 等,2016)、让生成器预判判别器的回应(unrolled GAN,Metz 等,2017)、给判别器加梯度惩罚或谱归一化让它的回应更平滑,或者干脆换一个按似然训练、天然要覆盖所有数据的模型(VAE、flow、扩散模型)。
5另一个视角:训练是一场博弈,不是下山
6.3 节的梯度下降有一个总是在下降的目标函数,学习率够小就能收敛。GAN 不是这样:两个玩家沿着同一个函数的相反方向走,联合的“梯度场”可以绕圈,而不是指向一个谷底。Mescheder、Geiger 与 Nowozin(2018)用一个最小的例子把这一点说清楚了,称为 Dirac GAN:真数据是 \(x=0\) 处的一个点,生成器是 \(x=\theta\) 处的一个点,判别器是 \(D(x)=\sigma(\psi x)\),只有一个参数 \(\psi\)。唯一的平衡点是 \(\theta=0,\ \psi=0\)。在平衡点附近,两人的更新近似为
(先看 \(\gamma=0\))。这是一个纯旋转:判别器看到生成器在右边(\(\theta>0\)),就让 \(\psi\) 变负,把右边判成“假”;生成器于是往左走;走过头之后判别器又反过来……线性化矩阵的特征值是 \(\pm\tfrac i2\),纯虚数,没有任何衰减。下图在 \((\theta,\psi)\) 平面上运行真实(非线性)的离散更新,用的是原始的零和损失(非饱和损失在平衡点处的线性化完全相同)。
- 选“同时更新”,γ = 0,从默认起点 \((\theta,\psi)=(1,0)\) 运行:轨迹向外螺旋,离平衡点的距离超过起点的 2 倍(η = 0.1 时约 660 步)。
- 把 R1 系数 γ 调到 0.1 以上(两种更新方式都行),重置后运行:轨迹盘旋着收进平衡点,距离降到起点的 2% 以下。
“交替更新”(判别器先走一步,生成器用更新后的判别器再走一步)也不收敛,只是不再发散:在 η = 0.1 下跑 6000 步,距离始终在起点的 0.99 到 1.02 倍之间,永远绕圈。\(\hl{r1}{\gamma\psi}\) 这一项来自 R1 正则:给判别器加惩罚 \(\tfrac\gamma2\,\mathbb E_{x\sim p_{\text{data}}}\|\nabla_x l(x)\|^2\),即判别器 logit 在真数据上的梯度平方。在 Dirac GAN 里 \(\nabla_xl=\psi\),惩罚就是 \(\tfrac\gamma2\psi^2\),它给旋转加上了阻尼。直觉上,R1 告诉判别器:“在真数据附近别太陡”,到了平衡点,判别器就没有理由偏离 \(\psi=0\)。γ 也不是越大越好:γ = 1 时约 140 步收敛到 2% 以内,γ = 2 反而要约 310 步(过阻尼)。WGAN-GP 的梯度惩罚、谱归一化都属于同一类“约束判别器斜率”的方法。
散度:判别器最优时,生成器在最小化 JS 散度(第 6 节);换一种判别器损失就换一种散度(f-GAN 给出整个 f-散度家族,WGAN 给出 Wasserstein 距离)。 分类:判别器是一个“真 vs 假”的二分类器,\(D^*\) 是贝叶斯最优分类器,它的 logit 正是密度比 \(\log(p_{\text{data}}/p_g)\):这一招(用分类器估计密度比)在 GAIL、AMP 和对比学习(18.3 节)里反复出现。 博弈:训练是寻找两人零和博弈的纳什均衡,梯度方法在这里会绕圈(FIG 5)。 学到的损失:判别器是一个随训练变化的、可微的“感知损失”,替代了逐像素 MSE,这也是它能让图像变清晰的原因。
6再看数学
提示:把鼠标悬停在公式中带底色的符号上,图中对应的元素会被高亮(FIG 1 的三条曲线,FIG 2 的点和箭头,FIG 3 的三条梯度曲线,FIG 5 的切线,FIG 6 的条件切片)。
价值函数
噪声 \(\mathbf z\sim p_z\)(这里是标准高斯),生成器 \(G_\theta\) 把它映射为样本,诱导出分布 \(p_g\);判别器 \(D_\phi(x)\in(0,1)\)。GAN 的目标是一个极小极大问题:
对 \(\phi\) 而言这就是二分类交叉熵取负(真样本标签 1,假样本标签 0,16.1 节),所以“最大化 \(V\)”就是训练一个分类器。生成器只出现在第二项里。
最优判别器与 JS 散度
固定 \(G\),把第二项改写成对 \(p_g\) 的期望:\(V=\int\big[p_{\text{data}}(x)\log D(x)+p_g(x)\log(1-D(x))\big]dx\)。假设 \(D\) 可以是任意函数,就能逐点最大化:对 \(a\log y+b\log(1-y)\) 求导,\(a/y-b/(1-y)=0\) 得 \(y=a/(a+b)\),这就是第 2 节的 \(\hl{dstar}{D^*}\)。代回去:
(在每个对数里乘上再除以 2,得到 \(-\log2\) 两次和两个对 \(m\) 的 KL。)KL 非负且只在两分布相同时为 0(4.11 节),所以 \(\mathrm{JS}\ge0\),等号当且仅当 \(p_g=p_{\text{data}}\):全局最优解唯一,就是生成器完美复制数据分布,此时 \(D^*=\tfrac12\)、\(V=-\log4\)(FIG 1 的第二个任务)。JS 对称、有界;两分布支撑不相交时它恒等于 \(\log2\),对参数的导数为零(FIG 1 的第一个任务、FIG 3)。这一切都假设判别器是“任意函数”且训练到了最优:真实的判别器是一个有限的网络,只走了几步,它近似的是一个被平滑过的 JS。
生成器的梯度:穿过判别器的反向传播
写 \(l_\phi(x)\) 为判别器的 logit,\(D=\sigma(l)\)。生成器损失 \(L_G=\mathbb E_{\mathbf z}[\ell(l_\phi(G_\theta(\mathbf z)))]\),由链式法则(2.2、16.3 节):
\(\ell'(l)\) 是每个样本的一个标量权重;转置的雅可比 \((\partial G/\partial\theta)^\top\) 乘一个向量,就是穿过 \(G\) 的向量-雅可比积(VJP,16.3 节)。实现上就是:判别器做一次前向、一次反向,但只要它对输入的梯度(R101.NN 的 backward 正好返回 \(\partial L/\partial x\)),把判别器自己累积的参数梯度丢掉;再把这个向量当作生成器输出的上游梯度做一次反向传播。两种损失的区别只在标量权重:原始损失乘 \(D\),非饱和损失乘 \(1-D\),FIG 2 的读数同时给出两者。Arjovsky 与 Bottou(2017)进一步指出,判别器最优时非饱和损失的梯度等于 \(\nabla_\theta\big[D_{\mathrm{KL}}(p_g\|p_{\text{data}})-2\,\mathrm{JS}\big]\):其中反向 KL 惩罚“在没有数据的地方放样本”,却几乎不惩罚“漏掉一个模式”(4.11 节的“抓峰”),这是模式坍缩的另一个来源。
训练算法
每次迭代:(1) 判别器做 \(k\) 步:采样一批真样本 \(\{x_i\}\) 和噪声 \(\{\mathbf z_i\}\),沿 \(\nabla_\phi\frac1n\sum_i\big[\log D(x_i)+\log(1-D(G(\mathbf z_i)))\big]\) 上升;(2) 生成器做 1 步:采样新的 \(\{\mathbf z_i\}\),沿 \(-\nabla_\theta\frac1n\sum_i\ell(l(G(\mathbf z_i)))\) 下降。原论文的实验取 \(k=1\),FIG 2 也是。DCGAN(Radford 等,2016)总结的经验,如 Adam 取 \(\beta_1=0.5\)(比默认的 0.9 少一些动量,因为“目标”一直在动),一直沿用至今,本页也这样设。两个网络的学习率可以不同(TTUR,Heusel 等,2017)。
Wasserstein GAN
Wasserstein-1 距离(“推土机距离”)是把一堆土 \(p\) 搬成 \(q\) 的最小平均搬运距离;Kantorovich-Rubinstein 对偶把它写成对所有 1-Lipschitz 函数 \(f\) 取上确界:
WGAN 用一个网络(“评论家”,输出不过 sigmoid)近似这个 \(f\),评论家最大化上式,生成器最小化 \(-\mathbb E_{\mathbf z}[f(G(\mathbf z))]\)。难点是 Lipschitz 约束:原文把权重裁剪到 \([-c,c]\)(粗糙,容量受限),WGAN-GP(Gulrajani 等,2017)改为惩罚 \(\lambda\,\mathbb E_{\hat x}\big(\|\nabla_{\hat x}f(\hat x)\|-1\big)^2\),\(\hat x\) 取在真假样本的连线上;谱归一化(Miyato 等,2018)则直接把每层权重除以它的最大奇异值(1.12 节)。FIG 3 里两个等宽高斯的最优评论家是线性函数 \(f(x)=\pm x\),所以梯度恒为 1,不论分布离得多远。注意梯度惩罚需要“对梯度再求梯度”(二阶反向传播),本页的小工具箱不支持,所以 FIG 2 只用了标准的两种损失。
博弈动力学
把两人的参数拼成 \(\mathbf w=(\phi,\theta)\),同时梯度法就是 \(\mathbf w\leftarrow\mathbf w+\eta\,\mathbf v(\mathbf w)\),\(\mathbf v=(\nabla_\phi V,\,-\nabla_\theta V)\)。在平衡点处,它的收敛性由 \(\mathbf v\) 的雅可比 \(J\) 的特征值 \(\lambda\) 决定:离散更新的放大倍数是 \(|1+\eta\lambda|\)。普通的最小化里 \(J\) 是负的 Hessian,特征值为实数且非正;零和博弈里 \(J\) 有反对称部分,特征值可以是纯虚数,于是 \(|1+\eta\lambda|=\sqrt{1+\eta^2|\lambda|^2}>1\),无论 η 多小都发散,只是慢一些。Dirac GAN 里 \(\lambda=\pm\tfrac i2\),同时更新每步放大 \(\sqrt{1+\eta^2/4}\)(η = 0.1 时 1.00125);交替更新的矩阵行列式为 1(γ = 0 时),特征值落在单位圆上;R1 把 \(J\) 的实部变成 \(-\gamma/2\),从而收敛。
条件 GAN
给两个网络都喂一个条件 \(c\)(类别、图像、机器人观测):\(G(\mathbf z,c)\)、\(D(x,c)\),目标中的期望变成对 \((x,c)\) 的联合期望(Mirza 与 Osindero,2014)。同样的推导给出 \(D^*(x,c)=p_{\text{data}}(x|c)/(p_{\text{data}}(x|c)+p_g(x|c))\),最优解是对每个 \(c\) 都有 \(p_g(\cdot|c)=p_{\text{data}}(\cdot|c)\):一个条件分布的采样器,而不是条件均值。pix2pix(Isola 等,2017)用它做图像到图像的翻译,下一节用它生成多模态动作 \(\hl{cond}{G(\mathbf z,c)}\)。
7机器人中的它:绕开障碍物的两种方式
一个移动机器人(或机械臂末端)要从下方走到上方,中间有一个障碍物,它的横向位置 \(c\) 每次不同。示教者有时从左绕、有时从右绕:障碍物偏右时多半从左绕(概率 \(\sigma(3c)\)),偏左时多半从右绕。示教给出的是经过障碍物那一行时的横向位置 \(a=c\pm0.8\)(加一点噪声)。这是一个典型的多模态条件分布 \(p(a\,|\,c)\),和 19.1 节 FIG 6 里条件 VAE 解决的是同一类任务;这里换成对抗训练,看 GAN 能否同样学出两个分支。下图同时训练两个模型:一个用 MSE 回归 \(a\)(就是 22.1 节的行为克隆),一个条件 GAN,\(G(\mathbf z,c)\) 是 2→24→24→1 的 MLP(1 维噪声加 1 维条件),\(D(a,c)\) 是 2→24→24→1。
- 按“训练”,直到 cGAN 的碰撞率低于 3% 而 MSE 的碰撞率仍高于 30%(默认种子约 800 次迭代)。再把 \(c\) 拖到 0 附近:MSE 的红色路径径直穿过障碍物,cGAN 的路径分成左右两束。
MSE 的最优解是条件均值 \(\mathbb E[a|c]=c+0.8\,(1-2\sigma(3c))\),在 \(|c|<0.42\) 时都落在碰撞带里,所以无论训练多久它在约 42% 的 \(c\) 上都会撞。cGAN 学的是整个条件分布:它在两个分支之间偶尔留下几个“桥”上的样本(FIG 2 里的同一现象),这就是残余的那一点碰撞率。在 \(c=0.5\) 处,数据从左绕的比例是 \(\sigma(1.5)\approx0.82\);默认种子下 cGAN 学到的比例在 0.74 左右(读数实时给出),两个分支都有,但比例只是近似。多模态动作和它对模仿学习的意义,22.1 节和 22.2 节会再系统地比较 MSE、ACT 和 Diffusion Policy。
判别器当奖励:GAIL。Ho 与 Ermon(2016)的生成对抗模仿学习把策略当生成器、把“专家的状态-动作对 vs 策略的状态-动作对”的分类器当判别器,策略用强化学习最大化判别器给出的奖励,不需要手写奖励函数;它和逆强化学习的关系在 20.6 节展开。 判别器当风格奖励:AMP。Peng 等(2021)的对抗运动先验让判别器区分“动作捕捉数据里的状态转移”与“策略产生的状态转移”,把它的输出作为风格奖励,与任务奖励相加,仿真角色便能用自然的步态完成任务;Escontrela 等(2022)把同样的方法用在了四足机器人上,用它代替一堆手工调的步态奖励项。 sim-to-real 图像翻译。GraspGAN(Bousmalis 等,2018)用像素级的 GAN 域适应把仿真图像变得像真实图像,用于训练抓取网络,减少了所需的真实数据;RCAN(James 等,2019)用条件 GAN 把随机化纹理的仿真图像和真实图像都“翻译”到同一个规范化的仿真外观;RL-CycleGAN(Rao 等,2020)把 CycleGAN(Zhu 等,2017)与强化学习结合。 对抗损失作为组件:今天很多图像自编码器和 tokenizer(例如 VQGAN,以及潜在扩散模型使用的自编码器)在重建损失之外加一个基于图像块的判别器损失,让重建更清晰;这类编码器也出现在一些视频生成模型和世界模型里。不过在动作生成本身,扩散模型(19.6 节)和 flow matching(19.7 节)基本已经取代了 GAN,原因正是本节讲的训练稳定性和模式覆盖。
8常见误区
GAN 的两个损失是一场博弈的两边,它们来回摆动是正常的,下降也不代表样本变好(判别器变弱时生成器损失同样会下降)。“\(D\approx\tfrac12\)”只说明判别器分不开,不说明样本覆盖了全部数据:一个坍缩到少数模式、但每个样本都很逼真的生成器,也可能让一个小判别器分不开。要用样本本身评估:看图,算精确率/召回率(FIG 2)或 FID(Heusel 等,2017),对机器人则直接看任务成功率。
理论里判别器“训练到最优”,实践里一个过强、过尖的判别器正是麻烦的来源:用原始损失时梯度饱和(FIG 3),用非饱和损失时梯度又大又吵,而两个分布不重叠时 JS 根本没有方向信息。好的判别器是“平滑地对”的:限制它的斜率(R1、梯度惩罚、谱归一化)、给输入加噪声、不要让它领先太多。反过来,判别器太弱时生成器得不到有用的信号,样本会有明显瑕疵。
坍缩的样本单个看都很好,所以很容易被漏掉。对机器人来说后果很具体:一个只学会“从左边抓”的抓取生成器,在杯子左边被挡住时就无计可施。要显式检查覆盖率:召回率、每个模式的样本比例(FIG 2 的峰数、FIG 4 的柱状图),或在固定的若干条件下看样本的多样性。若覆盖最重要,优先考虑按似然训练的模型(VAE、flow、扩散)。
“学习率调小就会收敛”在 GAN 里不成立(FIG 5:纯虚特征值下同时更新对任何 η 都发散),动量会加剧绕圈(所以 DCGAN 把 Adam 的 \(\beta_1\) 降到 0.5)。实现上的小坑也来自博弈结构:生成器那一步要么冻结判别器参数,要么在反向传播后丢掉它累积的梯度,否则判别器会在生成器的那一步里被朝“帮生成器”的方向更新;判别器那一步里,假样本要从计算图中断开(PyTorch 里的 detach()),否则生成器也会被意外更新。
9小练习
10延伸阅读
- I. Goodfellow, J. Pouget-Abadie, M. Mirza, B. Xu, D. Warde-Farley, S. Ozair, A. Courville & Y. Bengio, Generative Adversarial Nets, NeurIPS 2014 — 原始论文:极小极大目标、最优判别器、JS 散度与非饱和损失
- I. Goodfellow, NIPS 2016 Tutorial: Generative Adversarial Networks, arXiv:1701.00160, 2017 — 作者本人的长篇教程,包括模式坍缩与 min max / max min 的讨论
- A. Radford, L. Metz & S. Chintala, Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks, ICLR 2016 — DCGAN:让卷积 GAN 稳定训练的一组经验规则
- M. Arjovsky & L. Bottou, Towards Principled Methods for Training Generative Adversarial Networks, ICLR 2017 — 支撑不相交、梯度消失与非饱和损失的分析
- M. Arjovsky, S. Chintala & L. Bottou, Wasserstein Generative Adversarial Networks, ICML 2017; I. Gulrajani, F. Ahmed, M. Arjovsky, V. Dumoulin & A. Courville, Improved Training of Wasserstein GANs, NeurIPS 2017 — WGAN 与梯度惩罚
- L. Mescheder, A. Geiger & S. Nowozin, Which Training Methods for GANs do actually Converge?, ICML 2018 — Dirac GAN、博弈的局部收敛与 R1 正则
- M. Mirza & S. Osindero, Conditional Generative Adversarial Nets, arXiv:1411.1784, 2014; P. Isola, J.-Y. Zhu, T. Zhou & A. A. Efros, Image-to-Image Translation with Conditional Adversarial Networks, CVPR 2017 — 条件 GAN 与 pix2pix
- J. Ho & S. Ermon, Generative Adversarial Imitation Learning, NeurIPS 2016 — GAIL:判别器当奖励的模仿学习
- X. B. Peng, Z. Ma, P. Abbeel, S. Levine & A. Kanazawa, AMP: Adversarial Motion Priors for Stylized Physics-Based Character Control, ACM Transactions on Graphics (SIGGRAPH), 2021 — 用判别器做动作风格奖励
- K. Bousmalis et al., Using Simulation and Domain Adaptation to Improve Efficiency of Deep Robotic Grasping, ICRA 2018 — GraspGAN:用 GAN 做 sim-to-real 的像素级域适应
- T. Kynkäänniemi, T. Karras, S. Laine, J. Lehtinen & T. Aila, Improved Precision and Recall Metric for Assessing Generative Models, NeurIPS 2019 — 把“像不像”和“全不全”分开评估(FIG 2 的读数是它的简化版)