Lecture 17 · 离散隐变量模型 · Discrete Latent Variable Models

Deep Generative Models · Lecture 17。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应 Maps to:Stanford CS236 Deep Generative Models(Fall 2023,Stefano Ermon),Lecture 17 · 2023-11-29 · Discrete Latent Variable Models(slides:cs236_lecture17.pdf)。 依据说明:本讲按原课 slides 的主线展开:为什么关心离散(数据与结构本身是离散的)→ 随机优化:重参数化 vs 对数导数技巧(REINFORCE),多臂老虎机的例子 → 离散隐变量模型的变分学习,REINFORCE 的高方差 → 控制变量与基线、NVIL → 走向连续松弛:Gumbel 分布与 Gumbel-max 技巧 → Gumbel-softmax(Concrete)、温度带来的偏差–方差权衡、几何解释 → 推广到排列等组合对象(Plackett–Luce、Gumbel 排序、NeuralSort)。主要依据 Williams(REINFORCE,1992)、Mnih & Gregor(NVIL,2014)、Jang, Gu & Poole(Gumbel-softmax,2017)、Maddison, Mnih & Teh(Concrete,2017)、Grover, Wang, Zweig & Ermon(NeuralSort,2019)、Kool, van Hoof & Welling(Gumbel-top-k,留一法基线,2019)。用可以枚举的离散 VAE(4,096 个码字)精确量出每种估计量的偏差和方差、“q 均匀”的鞍点、NVIL 的方差归一化在 Adam 与闭式 KL 下的副作用、GRPO 式归一化的分析、松弛目标”过于乐观”的度量(解码器从 ŷ 的小数部分偷看的信息)、隐变量个数增加时各方法的表现是本讲义补充的。 配套代码 Code:code/lecture17/(PyTorch;共享模块 discrete.py + 5 个演示脚本,最长的约 75 秒) 预计阅读时间:3 小时(含运行代码)


0. 本讲导航 · How to read this lecture

0.1 学习目标 Learning goals

学完这一讲,你应该能够:

  1. 说出离散隐变量为什么让重参数化失效,并推导对数导数技巧(REINFORCE):∇ϕEqϕ[f(z)]=Eqϕ[f(z)∇ϕlog⁡qϕ(z)]\nabla_\phi\mathbb{E}_{q_\phi}[f(z)] = \mathbb{E}_{q_\phi}[f(z)\nabla_\phi\log q_\phi(z)]。
  2. 用 REINFORCE 写出离散隐变量模型的 ELBO 梯度,说明为什么多出来的 Eq[∇log⁡q]\mathbb{E}_q[\nabla\log q] 项为零。
  3. 理解控制变量:f−a(h−Eh)f - a(h - \mathbb{E}h) 无偏、方差降到 1−ρ21 - \rho^2 倍;把基线、NVIL、留一法都看成控制变量;知道”组平均再除以标准差”(GRPO 式)带来了什么。
  4. 证明 Gumbel-max 技巧,写出 Gumbel-softmax 的定义,解释温度 τ\tau 的偏差–方差权衡和”松弛目标与离散目标不是同一个东西”。
  5. 知道直通估计(straight-through)、温度退火、松弛 ELBO 在 VAE 里的用法和陷阱。
  6. 把同样的思路推广到排列:Plackett–Luce 分布、Gumbel 排序、NeuralSort。

0.2 先修与本讲范围 Prerequisites & scope

默认你已经会 Assumed本讲只给直觉 Previewed only
第 5–6 讲:ELBO、VAE、重参数化、REINFORCE 的初步比较(第 6 讲代码 01)REBAR、RELAX 等更复杂的减方差方法(§4.5 一句话介绍)
第 15 讲:IWAE 作为 log⁡p(x)\log p(x) 的估计强化学习中的策略梯度理论(价值函数、优势函数)
第 1 讲:像素世界(177 个配置 + 翻转噪声)VQ-VAE 等”离散码本”模型的细节(§9)

0.3 本讲地图 Map

§1  为什么关心离散
§2  随机优化:重参数化 vs REINFORCE;多臂老虎机                                ← 代码 01 第 1–2 部分
§3  离散隐变量模型的变分学习;"q 均匀"的鞍点                                   ← 代码 02 第 2 部分
§4  控制变量:基线、NVIL、留一法;GRPO 式归一化                                 ← 代码 01 第 1、3 部分,代码 02 第 1、3 部分
§5  Gumbel 分布与 Gumbel-max 技巧                                              ← 代码 03 第 1 部分
§6  Gumbel-softmax:温度、几何、偏差–方差                                       ← 代码 03 第 2–4 部分
§7  在 VAE 里用松弛:松弛目标 vs 离散 ELBO、直通、退火、隐变量变多               ← 代码 04,代码 02
§8  组合对象:排列、Plackett–Luce、NeuralSort                                  ← 代码 05
§9  2023 年之后
§10–14  小结、常见误区、练习、延伸阅读、下一讲预告

0.4 记号 Notation

符号含义
qϕ(z)q_\phi(z),π=softmax(ϕ)\pi = \mathrm{softmax}(\phi)离散分布(“策略”或变分后验)与它的参数(logits)
f(z)f(z)要最大化期望的函数:奖励、或 VAE 里的学习信号 log⁡pθ(x∣z)\log p_\theta(x \mid z)
s(z)=∇ϕlog⁡qϕ(z)s(z) = \nabla_\phi\log q_\phi(z)得分函数(score function;注意和第 13 讲的 ∇xlog⁡p(x)\nabla_x\log p(x) 不同:这里对参数求导)
bb,b(x)b(x)基线(baseline):常数或依赖输入 xx
g∼Gumbel(0,1)g \sim \mathrm{Gumbel}(0, 1)标准 Gumbel 噪声,g=−log⁡(−log⁡U)g = -\log(-\log U)
τ\tau,y^=softmax((log⁡π+g)/τ)\hat y = \mathrm{softmax}((\log\pi + g)/\tau)温度与 Gumbel-softmax 样本
MM,KK隐变量(符号)的个数、每个符号的类别数;码字共有 KMK^M 个
相对偏差、相对标准差∥Eg^−g∥/∥g∥\Vert\mathbb{E}\hat g - g\Vert/\Vert g\Vert、E∥g^−Eg^∥2/∥g∥\sqrt{\mathbb{E}\Vert\hat g - \mathbb{E}\hat g\Vert^2}/\Vert g\Vert(gg 是精确梯度)

0.5 关于数字 · About the numbers

代码 01、03、05 的问题小到可以精确算出梯度(10 臂老虎机、5 个类别、720 个排列)。代码 02、04 的离散 VAE 用像素世界(第 3 讲的 pixel_data:1 万张训练图、5,000 张测试图,真实分布的熵约 25.5 bit / 图);隐变量是 M=4M = 4 个 8 类的符号,4,096 个码字可以全部枚举,所以 ELBO、log⁡p(x)\log p(x)、编码器的精确梯度都能算出来——这让我们能直接量出每种估计量的偏差和方差。所有数字来自固定种子的单次运行;和预想不同的结果记录在 代码 README 的”关于实验结果”里。


1. 为什么关心离散 · Why discrete?

从第 5 讲到第 16 讲,几乎每一个模型都依赖一件事:对连续变量求梯度。VAE 用重参数化 z=μ+σϵz = \mu + \sigma\epsilon 把梯度传过采样;流模型要求变换可逆、可导;GAN 的生成器要把判别器的梯度传回噪声;得分模型和扩散模型干脆把 ∇xlog⁡p(x)\nabla_x\log p(x) 当成要学的对象。

可是世界上很多东西本来就是离散的:

  • 数据是离散的:文字(token)、DNA 序列、分子图、程序、乐谱。第 3 讲的自回归模型能处理它们,是因为它只需要 p(xi∣x<i)p(x_i \mid x_{<i}) 的 softmax,不需要对 xx 求导。第 18 讲会讨论:扩散模型依赖的”梯度”在离散数据上没有定义,怎么办?
  • 隐变量是离散的:类别(这张图是哪种形状?)、聚类、选择(看图像的哪一块——“硬注意力”)、结构(句法树、图的连边)、离散的码(VQ-VAE 把图像压成一串离散符号,§9)。离散的隐变量往往更可解释,也更适合表示”非此即彼”的结构。
  • 决策是离散的:强化学习里选哪个动作,语言模型生成哪个 token。

这一讲关心的就是:当 zz 离散时,怎样优化 Ez∼qϕ[f(z)]\mathbb{E}_{z \sim q_\phi}[f(z)]?像素世界本身就是一个离散隐变量模型(第 1 讲:177 个配置之一 + 独立翻转),它是这一讲的主要试验场。


2. 随机优化:重参数化 vs REINFORCE · Stochastic optimization

2.1 问题

很多学习问题都长这样:

max⁡ϕ Ez∼qϕ(z)[f(z)].\max_\phi\ \mathbb{E}_{z \sim q_\phi(z)}[f(z)].

VAE 里 qϕq_\phi 是编码器、ff 是 log⁡p(x,z)−log⁡q(z)\log p(x, z) - \log q(z);强化学习里 qϕq_\phi 是策略、ff 是奖励。难点在于:期望的分布本身依赖 ϕ\phi,梯度不能直接搬进期望里。

2.2 回顾:重参数化,以及它为什么在离散时失效

第 6 讲:如果能把采样写成 z=g(ϵ;ϕ)z = g(\epsilon; \phi),ϵ\epsilon 的分布不依赖 ϕ\phi,那么

∇ϕEqϕ[f(z)]=Eϵ[∇zf(g(ϵ;ϕ)) ∇ϕg(ϵ;ϕ)].\nabla_\phi\mathbb{E}_{q_\phi}[f(z)] = \mathbb{E}_\epsilon[\nabla_z f(g(\epsilon; \phi))\,\nabla_\phi g(\epsilon; \phi)].

这需要两件事:zz 是 ϕ\phi 的可导函数,ff 对 zz 可导。离散的 zz 两条都不满足:ϕ\phi 稍微变一点,zz 要么不变(导数为 0),要么跳到另一个值(导数不存在);而 ff 只在离散点上有定义。第 6 讲代码 01 第 3 部分已经看到:PyTorch 认为 argmax 的输出 requires_grad = False——梯度在这里断了。

2.3 对数导数技巧(REINFORCE)

换一个思路:不对样本求导,而对概率求导。设 zz 取有限多个值:

∇ϕEqϕ[f(z)]=∇ϕ∑zqϕ(z)f(z)=∑zf(z)∇ϕqϕ(z)=∑zqϕ(z)f(z)∇ϕlog⁡qϕ(z)=Eqϕ[f(z)∇ϕlog⁡qϕ(z)].\nabla_\phi\mathbb{E}_{q_\phi}[f(z)] = \nabla_\phi\sum_z q_\phi(z)f(z) = \sum_z f(z)\nabla_\phi q_\phi(z) = \sum_z q_\phi(z)f(z)\nabla_\phi\log q_\phi(z) = \mathbb{E}_{q_\phi}[f(z)\nabla_\phi\log q_\phi(z)].

第三个等号用了 ∇q=q∇log⁡q\nabla q = q\nabla\log q——这就是”对数导数技巧”(log-derivative trick),也叫得分函数估计量(score function estimator)、似然比估计量(likelihood ratio)、REINFORCE(Williams 1992)。于是可以用蒙特卡洛估计:

g^=1S∑s=1Sf(z(s)) ∇ϕlog⁡qϕ(z(s)),z(s)∼qϕ.\hat g = \frac1S\sum_{s=1}^S f(z^{(s)})\,\nabla_\phi\log q_\phi(z^{(s)}), \qquad z^{(s)} \sim q_\phi.

为什么它这么通用? 它只要求两件事:能从 qϕq_\phi 采样、log⁡qϕ(z)\log q_\phi(z) 对 ϕ\phi 可导。ff 可以是黑箱——不可导、不连续、甚至只能”做一次实验看结果”。代价是方差:ff 只以”一个数”的形式出现,乘在 ∇log⁡q\nabla\log q 上;它不知道”zz 往哪边变 ff 会变好”,只知道”这次的 zz 得了几分”。

直觉:∇log⁡q(z)\nabla\log q(z) 指向”让 zz 更可能”的方向。REINFORCE 说:把每个样本往”更可能”的方向推,推的力度正比于它的得分。得分高的被推得多、得分低的被推得少,平均下来,概率就从差的 zz 流向好的 zz。

2.4 例子:多臂老虎机

原课 slides 用多臂老虎机(multi-armed bandit)举例:KK 台老虎机,选第 zz 台得到随机奖励;策略 qϕ(z)=softmax(ϕ)zq_\phi(z) = \mathrm{softmax}(\phi)_z;目标是期望奖励 J(ϕ)=∑zπzμzJ(\phi) = \sum_z\pi_z\mu_z。奖励的公式我们不知道,只能”拉一下、看结果”——典型的黑箱 ff。

对 softmax,∇ϕlog⁡πz=ez−π\nabla_\phi\log\pi_z = e_z - \pi(eze_z 是 one-hot),所以单次拉动的 REINFORCE 估计是 r (ez−π)r\,(e_z - \pi)。精确梯度是 ∂J/∂ϕj=πj(μj−J)\partial J/\partial\phi_j = \pi_j(\mu_j - J):比平均水平好的机器,概率被推高。

代码 01 用 10 台中奖概率 0.0–0.9 的机器,在均匀策略 ϕ=0\phi = 0 下比较估计量(2 万次估计):

估计量平均值的方向余弦单次相对标准差拉几次到 10% 误差
不加基线:r ∇log⁡qr\,\nabla\log q0.9996.904,764
奖励整体加 100(不加基线)−0.15810491.1 亿
常数基线 b=Jb = J1.0005.092,594

两件事值得停下来想:

  1. REINFORCE 是无偏的:平均 2 万次以后方向几乎完全对(余弦 0.999)。但单次估计的标准差是真梯度长度的 7 倍——一次估计几乎是噪声。
  2. 奖励整体加一个常数,期望不变,方差爆炸:标准差从 6.9 涨到 1049(约 152 倍,方差约 2.3 万倍),2 万次的平均仍然全是噪声。原因在 §4:Eq[∇log⁡q]=0\mathbb{E}_q[\nabla\log q] = 0,所以加常数 cc 只是给估计量加了一个均值为零、方差为 c2Var(∇log⁡q)c^2\mathrm{Var}(\nabla\log q) 的噪声。

真正去学的时候(代码 01 第 2 部分,学习率 0.1、拉 4,000 次、50 个独立的赌徒),这种方差直接表现为失败:

估计量拉 500 次后的 JJ4,000 次后的 JJ最常选的是最好机器的比例
不加基线0.7930.8790.82
奖励加 100(不加基线)0.3720.4100.10
常数基线 b=Jb = J0.8180.8950.98
滑动平均基线0.8170.8971.00

奖励加 100 时,第一次拉到哪台机器,ϕ\phi 就朝那台机器猛冲(一步的更新量约 0.1×1000.1 \times 100),策略立刻塌缩到一台随机的机器上,再也学不回来——0.10 的”找到最好机器”的比例就是随机猜的水平。方差大在优化里的样子不只是”学得慢”,而是被一次噪声带进死胡同。


3. 离散隐变量模型的变分学习 · Variational learning with discrete latents

3.1 ELBO 的梯度

隐变量模型 pθ(x,z)p_\theta(x, z),zz 离散。ELBO(第 5 讲):

L(x;θ,ϕ)=Eqϕ(z∣x)[log⁡pθ(x,z)−log⁡qϕ(z∣x)⏟fθ,ϕ(z)].\mathcal{L}(x; \theta, \phi) = \mathbb{E}_{q_\phi(z \mid x)}\big[\underbrace{\log p_\theta(x, z) - \log q_\phi(z \mid x)}_{f_{\theta,\phi}(z)}\big].

  • 对 θ\theta:期望的分布不依赖 θ\theta,∇θL=Eq[∇θlog⁡pθ(x,z)]\nabla_\theta\mathcal{L} = \mathbb{E}_q[\nabla_\theta\log p_\theta(x, z)],直接采样估计——和连续的 VAE 一样。
  • 对 ϕ\phi:ff 本身也依赖 ϕ\phi,所以多一项:

∇ϕL=Eq[f ∇ϕlog⁡qϕ]+Eq[∇ϕf]=Eq[f ∇ϕlog⁡qϕ]−Eq[∇ϕlog⁡qϕ]=Eq[f ∇ϕlog⁡qϕ].\nabla_\phi\mathcal{L} = \mathbb{E}_q[f\,\nabla_\phi\log q_\phi] + \mathbb{E}_q[\nabla_\phi f] = \mathbb{E}_q[f\,\nabla_\phi\log q_\phi] - \mathbb{E}_q[\nabla_\phi\log q_\phi] = \mathbb{E}_q[f\,\nabla_\phi\log q_\phi].

最后一步用了 Eq[∇log⁡q]=∑z∇q(z)=∇∑zq(z)=∇1=0\mathbb{E}_q[\nabla\log q] = \sum_z\nabla q(z) = \nabla\sum_z q(z) = \nabla 1 = 0。这个恒等式是整讲的关键,§4 还会反复用到。

能精确算的就精确算。 如果先验和后验都按符号分解(q(z∣x)=∏mq(zm∣x)q(z \mid x) = \prod_m q(z_m \mid x),p(z)=∏mp(zm)p(z) = \prod_m p(z_m)),KL 项 DKL(q(z∣x)∥p(z))D_{\mathrm{KL}}(q(z \mid x)\Vert p(z)) 有闭式解,于是只剩重构项 Eq[log⁡pθ(x∣z)]\mathbb{E}_q[\log p_\theta(x \mid z)] 需要估计,学习信号就是 f=log⁡pθ(x∣z)f = \log p_\theta(x \mid z)。把能精确算的部分精确算,本身就是一种减方差(Rao–Blackwell 化)。代码 discrete.py 的所有方法都这样处理 KL。

3.2 实验设置:一个可以枚举的离散 VAE

代码 02 的模型 CatVAE:z=(z1,…,z4)z = (z_1, \dots, z_4),每个 zm∈{1,…,8}z_m \in \{1, \dots, 8\};先验均匀;编码器是 MLP,输出 4×84 \times 8 个 logits;解码器是 MLP,输入 4 个 one-hot 拼成的 32 维向量,输出 64 个像素的伯努利 logits。

码字共 84=4,0968^4 = 4{,}096 个,远多于像素世界的 177 个配置,表达能力绰绰有余。4,096 不大,所以:解码器只依赖 zz,4,096 个码字只需要解码一次,所有 (图, 码字) 对的 log⁡p(x∣z)\log p(x \mid z) 是一次矩阵乘法(和第 1 讲 pixel_world.log_lik 一样)。于是 ELBO、log⁡p(x)=log⁡∑zp(z)p(x∣z)\log p(x) = \log\sum_z p(z)p(x \mid z)、以及 ELBO 对编码器参数的精确梯度都能算出来。真实的模型做不到这一点(码字太多,或者解码器还依赖别的东西),但在这里,它让我们能直接量出每种估计量离真相有多远。

3.3 一个鞍点:“q 均匀、解码器忽略 z”

代码 02 第 2 部分从头训练 3,000 步(Adam,学习率 10−310^{-3}),测试集上精确评估(bit / 图;H(q(z∣x))=12H(q(z \mid x)) = 12 bit 表示编码器输出均匀分布):

训练方法−ELBO−log p(x)H(q(z∣x))H(q(z \mid x))
(初始化)64.2764.2311.98
REINFORCE,不加基线35.6235.5011.89
常数基线(滑动平均)35.5535.5311.99
NVIL(§4.3)32.9932.789.97
留一法 S=4S = 4(§4.4)30.8730.557.72
Gumbel-softmax τ=0.5\tau = 0.5(§6)31.0329.967.30

不加基线和常数基线的 REINFORCE,3,000 步后编码器还是均匀分布,解码器只学会了平均图像(各像素独立的模型约 35.6 bit / 图)。这是一个鞍点,形成的逻辑是一个闭环:

q 均匀⇒z 和 x 无关⇒解码器忽略 z⇒f=log⁡p(x∣z) 几乎不随 z 变⇒重构项的真梯度几乎为零.q \text{ 均匀} \Rightarrow z \text{ 和 } x \text{ 无关} \Rightarrow \text{解码器忽略 } z \Rightarrow f = \log p(x \mid z) \text{ 几乎不随 } z \text{ 变} \Rightarrow \text{重构项的真梯度几乎为零}.

与此同时,闭式的 KL 项一直在把 qq 拉向均匀先验。精确梯度能慢慢爬出来(一开始用单个 64 类变量做实验时,精确梯度也花了约 1,500 步,见代码 README 第 1 条),但单样本估计量的噪声把那一点微弱的信号淹没了。输入相关的基线(NVIL)和多样本的留一法噪声小,能爬出来;Gumbel-softmax 爬得最快——原因在 §7.1。

这个现象不是玩具特有的。 离散隐变量模型(以及第 6 讲的”后验坍缩”)都容易卡在”隐变量没被使用”的状态。实践中的对策包括:更好的估计量、KL 预热(不过在这里它反而让情况更糟,见代码 README 第 2 条)、用确定性的编码器预训练、或者像 VQ-VAE 那样干脆不用 KL(§9)。


4. 控制变量:基线、NVIL 与留一法 · Control variates

4.1 一般形式

想估计 E[f]\mathbb{E}[f]。如果有另一个随机变量 hh,它的均值 E[h]\mathbb{E}[h] 已知,就可以用

f^=f−a (h−E[h]).\hat f = f - a\,(h - \mathbb{E}[h]).

对任何系数 aa 都无偏。方差 Var(f)−2a Cov(f,h)+a2Var(h)\mathrm{Var}(f) - 2a\,\mathrm{Cov}(f, h) + a^2\mathrm{Var}(h) 在

a∗=Cov(f,h)Var(h)a^* = \frac{\mathrm{Cov}(f, h)}{\mathrm{Var}(h)}

处最小,最小值是 Var(f)(1−ρ2)\mathrm{Var}(f)(1 - \rho^2),ρ\rho 是 ff 和 hh 的相关系数。控制变量和 ff 越相关越有用。

4.2 基线就是控制变量

对 REINFORCE,取 h=∇ϕlog⁡qϕ(z)h = \nabla_\phi\log q_\phi(z)——它的均值已知,就是 0(§3.1 的恒等式)。于是

g^=(f(z)−b) ∇ϕlog⁡qϕ(z)\hat g = (f(z) - b)\,\nabla_\phi\log q_\phi(z)

对任何不依赖 zz 的 bb 都无偏。bb 叫基线(baseline)。直觉:f−bf - b 的正负表示”这次比平时好还是差”;不减基线时,即使是很差的 zz(奖励为正的话)也会被推高,只是推得少一点——REINFORCE 要靠”推多推少”的差别来分辨好坏,噪声自然大。

代码 01 第 3 部分验证了一般形式(ϕ=5μ\phi = 5\mu 的策略,REINFORCE 的第 3 个坐标 f=r sjf = r\,s_j、h=sjh = s_j):a=0a = 0(不加基线)方差 0.189;a=1a = 1 方差降到 0.231 倍;a=a∗=0.803a = a^* = 0.803 方差降到 0.182 倍,正好等于理论的 1−ρ2=0.1821 - \rho^2 = 0.182。这里的 a∗a^* 就是这个坐标的最优基线 bj∗=E[r sj2]/E[sj2]b_j^* = \mathbb{E}[r\,s_j^2]/\mathbb{E}[s_j^2]——不是平均奖励,而是”以 sj2s_j^2 为权重的奖励加权平均”。实践中用平均奖励(或它的滑动平均)就已经很接近最优:代码 01 里,均匀策略下精确的 JJ 当基线的标准差 5.09,逐坐标最优基线 4.32,滑动平均基线 5.23。

4.3 输入相关的基线:NVIL

在 VAE 里,学习信号 f=log⁡p(x∣z)f = \log p(x \mid z) 的大小主要取决于 xx:有的图容易(−20 nat),有的难(−40 nat)。这部分变化和 zz 无关,却被整个乘进了 ∇log⁡q\nabla\log q。常数基线去不掉它;需要一个依赖 xx 的基线 b(x)b(x)。只要 bb 不依赖当前的 zz,Eq[b(x)∇log⁡q(z∣x)]=b(x)⋅0=0\mathbb{E}_q[b(x)\nabla\log q(z \mid x)] = b(x)\cdot 0 = 0,估计仍然无偏。

NVIL(Neural Variational Inference and Learning,Mnih & Gregor 2014)的做法:

  1. 中心化:学习信号减去 c+Bψ(x)c + B_\psi(x),cc 是滑动平均,BψB_\psi 是一个小网络,训练它最小化 Eq[(f−c−Bψ(x))2]\mathbb{E}_q[(f - c - B_\psi(x))^2]——也就是让它预测”这张图大概能得几分”。最优的 Bψ(x)+cB_\psi(x) + c 是 Eq[f∣x]\mathbb{E}_q[f \mid x]。
  2. 方差归一化:再除以 f−bf - b 的滑动标准差(让学习率自适应)。
  3. 局部学习信号:多层隐变量时,每一层用只和它有关的那部分信号(这里只有一层,用不到)。

代码 02 第 1 部分在两个检查点上,用 100 张测试图、每种估计量重复 300 次,和枚举得到的精确梯度比较编码器梯度:

估计量刚初始化:相对标准差训练过 1,000 步:相对标准差训练过:和精确梯度的余弦
REINFORCE,不加基线171.664.30.003
常数基线0.7213.670.069
理想的输入相关基线 b(x)=Eq[f∣x]b(x) = \mathbb{E}_q[f \mid x]0.433.820.253
NVIL:学到的 c+Bψ(x)c + B_\psi(x)0.446.170.155
留一法 S=2S = 20.443.710.250
留一法 S=4S = 40.252.140.409

(所有这些估计量的偏差都在噪声底以内。)刚初始化时不同的图的 Eq[f∣x]\mathbb{E}_q[f \mid x] 几乎一样(标准差 0.15 nat),常数基线就够了;训练一段以后图与图的差别变大(标准差约 4.6 nat),输入相关的基线比常数基线好 3.6 倍。NVIL 的基线网络(固定模型训练 1,000 步)去掉了其中一大半,离理想还有距离。

一个和优化器有关的教训。 第一版代码照原论文做了方差归一化,结果 NVIL 比常数基线还差。原因是:KL 项是闭式算的、没有被归一化;只把学习信号除以一个大于 1 的数,等于调低了重构项相对 KL 项的权重,训练初期编码器被推向均匀分布(代码 02 第 3 部分”NVIL + 方差归一化”一行:H(q)H(q) 从检查点的 10.62 升到 11.23 bit)。而原论文配合普通 SGD 使用时,归一化的作用是自适应学习率;Adam 本来就对梯度的整体缩放不敏感,这个好处也就没有了。减方差的技巧和优化器、和目标里其他项的处理方式是耦合的。

4.4 留一法基线

不想训练基线网络?对每个 xx 抽 SS 个样本 z(1),…,z(S)z^{(1)}, \dots, z^{(S)},第 ss 个样本的基线用另外 S−1S - 1 个样本的平均:

g^=1S∑s(f(z(s))−1S−1∑s′≠sf(z(s′)))∇log⁡q(z(s)).\hat g = \frac1S\sum_s\Big(f(z^{(s)}) - \frac{1}{S-1}\sum_{s' \neq s}f(z^{(s')})\Big)\nabla\log q(z^{(s)}).

基线和第 ss 个样本独立,所以无偏;它又自动依赖 xx(同一张图的样本),所以起到了输入相关基线的作用。Kool, van Hoof & Welling(2019)的标题很形象:Buy 4 REINFORCE samples, get a baseline for free! 代价是每张图要算 SS 次 ff;按样本数算,它比”已知 Ef\mathbb{E}f“的理想基线贵 S/(S−1)S/(S-1) 倍(代码 01:S=2S = 2 时贵一倍,r1−r2r_1 - r_2 的方差是 r−Jr - J 的两倍)。VIMCO(Mnih & Rezende 2016)把同样的想法用在多样本的 IWAE 目标上。

4.5 组平均、再除以标准差:GRPO 式的归一化

大语言模型的强化学习(§9)常用”组平均(含自己)当基线,再除以组内标准差”。代码 01 第 1 部分把它和留一法放在一起(均匀策略,S=4S = 4):

估计量平均值的方向余弦平均值的长度比单次相对标准差拉几次到 10%
留一法1.0000.992.963,516
组平均(含自己)1.0000.742.223,572
组平均再除以组标准差1.0001.614.813,584
  • 组平均(含自己)恰好等于留一法乘 (S−1)/S(S - 1)/S:fs−fˉ=S−1S(fs−fˉ−s)f_s - \bar f = \frac{S-1}{S}(f_s - \bar f_{-s})。方向不变、长度缩小 25%,信噪比和留一法完全一样——这种”偏差”只是缩放,等于换了学习率。
  • 再除以组标准差:方向仍然基本对,长度被放大(0/1 奖励的组内标准差不到 1),在同样的学习率下步子更大(代码 01 第 2 部分里它前期学得更快)。组内奖励全相同时梯度为 0。它不再是严格的缩放:难度不同的问题被乘以不同的系数,对整体目标来说是有偏的——Liu et al.(2025)把这称为 GRPO 的”难度偏差”,并建议去掉这一步。

更复杂的减方差方法(本讲不展开):REBAR(Tucker et al. 2017)和 RELAX(Grathwohl et al. 2018)用 Gumbel-softmax 松弛(§6)构造控制变量,得到无偏且低方差的估计;ARM(Yin & Zhou 2019)利用对偶采样。


5. Gumbel 分布与 Gumbel-max 技巧 · The Gumbel-max trick

5.1 动机:能不能把离散采样也”重参数化”?

重参数化的本质是把采样写成”确定的函数 + 与参数无关的噪声”。对类别分布 Categorical(π)\mathrm{Categorical}(\pi),有一个漂亮的写法。

5.2 Gumbel 分布

标准 Gumbel 分布的累积分布函数 F(g)=exp⁡(−e−g)F(g) = \exp(-e^{-g}),用逆变换采样:g=−log⁡(−log⁡U)g = -\log(-\log U),U∼Uniform(0,1)U \sim \mathrm{Uniform}(0, 1)。它是”许多独立变量的最大值”的极限分布(极值理论),均值是欧拉常数 γ≈0.5772\gamma \approx 0.5772,方差 π2/6\pi^2/6。代码 03 第 1 部分用 100 万个样本核对:均值 0.5755,方差 1.6420。

它最重要的性质是在取最大值下封闭:若 ui∼Gumbel(μi,1)u_i \sim \mathrm{Gumbel}(\mu_i, 1) 独立,则 max⁡iui∼Gumbel(log⁡∑ieμi,1)\max_i u_i \sim \mathrm{Gumbel}(\log\sum_i e^{\mu_i}, 1)。代码里 10 个标准 Gumbel 的最大值均值 2.8797,正好是 γ+log⁡10=2.8798\gamma + \log 10 = 2.8798,方差不变。

5.3 Gumbel-max 技巧

z=arg⁡max⁡i (log⁡πi+gi),gi∼iidGumbel(0,1)⟹P(z=k)=πk.z = \arg\max_i\,(\log\pi_i + g_i), \quad g_i \stackrel{\text{iid}}{\sim} \mathrm{Gumbel}(0, 1) \quad\Longrightarrow\quad P(z = k) = \pi_k.

一行推导:令 ui=log⁡πi+giu_i = \log\pi_i + g_i,它的分布函数是 Fi(u)=exp⁡(−πie−u)F_i(u) = \exp(-\pi_ie^{-u}),密度 fi(u)=πie−uexp⁡(−πie−u)f_i(u) = \pi_ie^{-u}\exp(-\pi_ie^{-u})。

P(z=k)=∫fk(u)∏i≠kFi(u) du=∫πke−uexp⁡(−e−u∑iπi)du=πk∑iπi=πk.P(z = k) = \int f_k(u)\prod_{i \neq k}F_i(u)\,du = \int\pi_ke^{-u}\exp\Big(-e^{-u}\sum_i\pi_i\Big)du = \frac{\pi_k}{\sum_i\pi_i} = \pi_k.

(最后一步令 t=e−ut = e^{-u}。)代码 03 第 1 部分的检验(100 万次,π=(0.05,0.10,0.20,0.25,0.40)\pi = (0.05, 0.10, 0.20, 0.25, 0.40)):Gumbel 噪声的卡方统计量 5.0(自由度 4,一致);换成标准高斯噪声,卡方统计量 5 万,频率明显偏离 π\pi——噪声的分布不能随便换。另一个推论:最大值本身和”哪一类胜出”独立(无论哪一类胜出,最大值的均值都约为 0.577),这是 §8 排列采样的基础。

可惜 argmax 不可导。 Gumbel-max 把离散采样写成了 π\pi 的确定函数,但这个函数是分段常数,梯度处处为 0。下一步自然是:把 argmax 换成一个光滑的近似。


6. Gumbel-softmax:连续松弛 · The Gumbel-softmax (Concrete) relaxation

6.1 定义

Jang, Gu & Poole(2017)和 Maddison, Mnih & Teh(2017,叫它 Concrete 分布)同时提出:

y^=softmax(log⁡π+gτ),gi∼iidGumbel(0,1).\hat y = \mathrm{softmax}\Big(\frac{\log\pi + g}{\tau}\Big), \qquad g_i \stackrel{\text{iid}}{\sim}\mathrm{Gumbel}(0, 1).

y^\hat y 是单纯形上的一个点(各分量非负、和为 1),是 log⁡π\log\pi 的可导函数——可以像第 6 讲那样重参数化,用路径梯度 ∇ϕf(y^(ϕ,g))\nabla_\phi f(\hat y(\phi, g))。温度 τ\tau 控制它有多像离散:

  • τ→0\tau \to 0:softmax 变成 argmax,y^\hat y 变成 one-hot,恰好是 Gumbel-max 的样本;
  • τ→∞\tau \to \infty:y^→(1/K,…,1/K)\hat y \to (1/K, \dots, 1/K),和 π\pi、和噪声都无关。

Maddison et al. 给出了 y^\hat y 的密度(练习 6 会用到):

pπ,τ(y)=(K−1)! τK−1∏k=1Kπkyk−τ−1∑iπiyi−τ.p_{\pi,\tau}(y) = (K - 1)!\,\tau^{K-1}\prod_{k=1}^K\frac{\pi_ky_k^{-\tau-1}}{\sum_i\pi_iy_i^{-\tau}}.

6.2 几何:单纯形上的样本

代码 03 第 2 部分在三类单纯形上画出了样本(π=(0.2,0.3,0.5)\pi = (0.2, 0.3, 0.5);三个顶点是 one-hot;三个温度共用同一组噪声):

τ\tau最大分量的平均最大分量 > 0.99 的比例E[y^]\mathbb{E}[\hat y]argmax(y^\hat y) 的频率
0.10.9570.733(0.200, 0.299, 0.500)(0.200, 0.299, 0.501)
10.6650.011(0.237, 0.315, 0.448)(0.200, 0.299, 0.501)
50.4140.000(0.305, 0.330, 0.365)(0.200, 0.299, 0.501)

文字画的密度图里,τ=0.1\tau = 0.1 的样本几乎全贴在三个顶点上;τ=5\tau = 5 的样本挤在单纯形中心附近一小团。表格揭示了松弛的两面:

  • argmax(y^\hat y) 的分布在任何温度下都恰好是 π\pi(softmax 不改变谁最大)。离散的信息一直都在。
  • 但 E[y^]≠π\mathbb{E}[\hat y] \neq \pi,τ\tau 越大越偏向均匀。用 y^\hat y 代替 one-hot,哪怕目标是线性的 E[c⊤z]\mathbb{E}[c^\top z],期望也变了。这就是松弛的偏差的根源:我们优化的是 Eg[f(y^)]\mathbb{E}_g[f(\hat y)],而不是 Ez∼π[f(z)]\mathbb{E}_{z \sim \pi}[f(z)]。

6.3 偏差–方差权衡

代码 03 第 3 部分:5 个类别,f(z)=(cz−1.6)2f(z) = (c_z - 1.6)^2,c=(0,1,2,3,4)c = (0, 1, 2, 3, 4),精确梯度已知。5 万次估计:

估计量相对偏差单次相对标准差100 次平均后的相对误差
Gumbel-softmax τ=0.05\tau = 0.050.0768.530.86
τ=0.2\tau = 0.20.2113.860.44
τ=1\tau = 10.7460.980.75
τ=5\tau = 50.9700.070.97
直通 Gumbel τ=1\tau = 10.6702.300.71
REINFORCE + 留一法(S=2S = 2)0.0112.380.24
  • τ\tau 小,偏差小、方差大:softmax 很陡,梯度 ∝1/τ\propto 1/\tau,只有落在”决策边界”附近的噪声才产生大梯度,其余几乎为零——均值慢慢变对,单次估计越来越不稳定。
  • τ\tau 大,方差小、偏差大:τ=5\tau = 5 的估计几乎是常数,但方向基本不对(相对误差约 1,和”猜梯度为零”差不多)。
  • 偏差不会被平均掉,方差会。 把 100 次估计平均(一个小批量、或者连续很多步的更新都相当于平均),误差 偏差2+标准差2/100\sqrt{\text{偏差}^2 + \text{标准差}^2/100} 在中等温度(τ≈0.2\tau \approx 0.2)最小。最好的温度取决于你能平均多少次。
  • 在这个只有 5 个类别、ff 很简单的问题上,REINFORCE + 留一法反而最准(代码 README 第 5 条:原以为松弛会全面占优)。松弛的优势在 ff 复杂、维数高的时候——例如一个神经网络解码器(§7)。

6.4 偏差的后果:收敛到错误的离散解

代码 03 第 4 部分真的去最小化 Ez∼π[f(z)]\mathbb{E}_{z \sim \pi}[f(z)](各类别的 ff = 2.56, 0.36, 0.16, 1.96, 5.76,离散最优是把全部概率放在第 2 类):

梯度最后的 Eπ[f]\mathbb{E}_\pi[f](最优 0.16)π\pi(第 2 类)Eπ[c]\mathbb{E}_\pi[c]
精确梯度0.1600.9992.00
Gumbel τ=0.1\tau = 0.10.1690.9851.99
Gumbel τ=1\tau = 10.2150.7371.74
Gumbel,τ\tau 从 2 退火到 0.10.1660.9721.97
直通 τ=1\tau = 10.2480.6251.62
REINFORCE + 留一法0.1620.9972.00

τ\tau 大时,松弛的目标近似是 f(Ey^)=(c⊤y^−1.6)2f(\mathbb{E}\hat y) = (c^\top\hat y - 1.6)^2,只要”平均的 cc“等于 1.6 就是零——于是它学到一个把概率分散在第 1、2 类之间的 π\pi(Eπ[c]\mathbb{E}_\pi[c] 被拉向 1.6)。按离散的 zz 算,这个解明显更差。松弛的目标和真正的目标有不同的最优解。 低温或退火(Jang et al. 的做法:从高温开始、逐渐降温)能找到正确的解。


7. 在 VAE 里用松弛 · Relaxations in a discrete VAE

7.1 怎么用

把编码器的样本换成 y^=softmax((logits(x)+g)/τ)\hat y = \mathrm{softmax}((\text{logits}(x) + g)/\tau),解码器的输入从 one-hot 变成 y^\hat y:整条路可导,编码器和解码器一起用路径梯度训练。KL 项有两种处理:

  • Jang et al.:KL 仍然按离散的 q(z∣x)q(z \mid x) 和 p(z)p(z) 闭式计算,只有重构项用松弛样本(本讲的代码这样做);
  • Maddison et al.:用 Concrete 密度(§6.1)计算松弛变量之间的 KL,得到”松弛模型”的一个严格的 ELBO。

测试时用真正的离散 zz。为什么 §3.3 里 Gumbel 能最快爬出鞍点?因为 y^\hat y 是 logits 的连续函数:哪怕 qq 几乎均匀,y^\hat y 也带着一点关于 xx 的信息,解码器可以利用它、再把梯度沿着这条路径传回编码器。REINFORCE 没有这条”信息通道”,它只能等 ff 自己显出差别。

7.2 松弛目标”过于乐观”:解码器在偷看

这条信息通道也是问题的来源。代码 04 第 1 部分扫温度(从头训练 3,000 步)。“松弛目标”是训练时真正优化的量,“偷看”是同一个噪声样本下 log⁡p(x∣y^)−log⁡p(x∣onehot(arg⁡max⁡y^))\log p(x \mid \hat y) - \log p(x \mid \text{onehot}(\arg\max\hat y))——给解码器看松弛的 y^\hat y 比只看它对应的离散 zz 好多少:

训练方法松弛目标−ELBO(离散)偷看的信息−log p(x)
Gumbel τ=0.1\tau = 0.132.1132.290.1831.84
Gumbel τ=0.25\tau = 0.2530.6731.180.5130.57
Gumbel τ=0.5\tau = 0.529.0231.262.3329.82
Gumbel τ=1\tau = 125.9435.829.8731.68
Gumbel τ=2\tau = 224.5142.7418.2636.30
Gumbel,τ\tau 从 2 退火到 0.2530.3631.531.1630.38
直通 τ=0.5\tau = 0.532.8432.840.0032.48

(单位 bit / 图。)τ=2\tau = 2 时松弛目标是 24.5 bit——比真实分布的熵(25.5)还低,这在离散模型里是不可能的:解码器把 y^\hat y 的小数部分当成了一个额外的连续信道,偷看了 18 bit 的信息。测试时只给 one-hot,这些信息就没有了,离散的 −ELBO 高达 42.7。训练和测试在优化不同的东西。

τ\tau 太小(0.1)偷看得少,但梯度方差大、学得慢;τ=0.25\tau = 0.25–0.5 最好。从高温退火到 0.25 的结果介于两者之间,没有超过最好的固定温度(代码 README 第 6 条)——退火的价值在于不必事先知道哪个温度合适。

7.3 直通估计 · Straight-through

直通 Gumbel(straight-through Gumbel-softmax;Bengio et al. 2013 的直通思想):前向传播用 onehot(arg⁡max⁡y^)\text{onehot}(\arg\max\hat y),反向传播假装用的是 y^\hat y。代码里就一行:y_hard - y.detach() + y。

  • 优点:解码器只看到 one-hot,没有”偷看”(上表最后一行:松弛目标 = 离散 ELBO,偷看 = 0);测试时和训练时一致。
  • 缺点:梯度是”借来的”——它是另一个函数的梯度,有偏,而且偏差不随训练消失。在代码 02、03、04 里它都不如合适温度的 Gumbel-softmax。

直通的思想在 VQ-VAE(§9)里被大规模使用:量化操作的前向是”选最近的码字”,反向直接把梯度复制给量化之前的向量。

7.4 隐变量变多:不能枚举的时候

M=8M = 8 个 8 类的符号有 88≈1,6778^8 \approx 1{,}677 万个码字,不能枚举了,只能用重要性采样(IWAE,第 5、15 讲)估计 log⁡p(x)\log p(x)。代码 04 第 2 部分先在能枚举的 M=4M = 4 模型上检查:精确 −ELBO 31.44、精确 −log p 30.32;IWAE kk = 1 / 30 / 300 给出 31.33 / 30.34 / 30.32——k=300k = 300 已经和精确值相同。然后比较 M=8M = 8(300 张测试图):

训练方法(M=8M = 8)IWAE k=1k = 1(≈ −ELBO)k=300k = 300(≈ −log p)H(q(z∣x))H(q(z \mid x))(均匀 = 24)
REINFORCE + NVIL35.5135.4923.99
留一法 S=4S = 432.3432.0220.57
Gumbel τ=0.5\tau = 0.532.2831.2920.32
直通 τ=0.5\tau = 0.533.3532.9622.35

同样 3,000 步,每种方法都比 M=4M = 4 时差约 1.5 bit(码更长、参数更多)。NVIL 在 M=4M = 4 时能爬出鞍点,M=8M = 8 时爬不出来:单样本 REINFORCE 的学习信号是同一个 ff 乘以 8 个符号的得分之和,每个符号分到的”功劳”更难分辨,噪声随 MM 增长。原以为 Gumbel 受 MM 的影响会比留一法小得多,数据不支持(代码 README 第 7 条):两者都差了约 1.5 bit,Gumbel τ=0.5\tau = 0.5 仍然最好。

7.5 小结:怎么选

REINFORCE + 基线Gumbel-softmax直通
偏差无有,随 τ\tau 增大有(梯度是借来的)
方差大,靠基线 / 多样本压低小,随 τ\tau 减小而增大中等
对 ff 的要求只要能算值(黑箱也行)ff 要在单纯形内部有定义、可导同左
适合奖励不可导(强化学习、BLEU 分数……)、需要无偏(理论保证)ff 是神经网络、维数高必须让下游看到离散值

8. 组合对象:排列 · Beyond categorical: permutations

原课最后把同样的思路推广到组合对象。例子:给 nn 篇文档排名,排名(排列 σ\sigma)本身是一个离散隐变量,有 n!n! 种取值。

8.1 Plackett–Luce 分布与 Gumbel 排序

Plackett–Luce(PL)分布:每个物品有分数 si>0s_i > 0,第一名按 si/∑ss_i/\sum s 选,第二名在剩下的里面按同样的比例选,依此类推:

P(σ)=∏i=1nsσi∑j≥isσj.P(\sigma) = \prod_{i=1}^n\frac{s_{\sigma_i}}{\sum_{j \geq i}s_{\sigma_j}}.

Gumbel 技巧的推广:给每个 log⁡si\log s_i 加独立的 Gumbel 噪声,从大到小排序,得到的排列恰好服从 PL 分布。第一名就是 Gumbel-max;而”最大值与 argmax 独立”(§5.3)让剩下的物品又是一个同样形式的问题。代码 05 第 1 部分(n=4n = 4、s=(1,2,3,4)s = (1, 2, 3, 4)、40 万次):24 个排列的频率和 PL 公式的卡方统计量 21.5(自由度 23,一致)。

只取前 kk 名就是”按权重不放回地抽 kk 个”(Gumbel-top-k,Kool et al. 2019)。注意”进入前 2”的概率不是 2si/∑s2s_i/\sum s:代码里四个物品进入前 2 的概率是 0.23、0.44、0.61、0.72,不放回抽样把概率摊平了。子集采样的连续松弛(Xie & Ermon 2019)就建立在它上面。

8.2 NeuralSort:松弛排序

排序算子不可导。NeuralSort(Grover, Wang, Zweig & Ermon 2019)利用一个恒等式:第 ii 大的元素是

arg⁡max⁡j[(n+1−2i) sj−∑k∣sj−sk∣],\arg\max_j\big[(n + 1 - 2i)\,s_j - \textstyle\sum_k|s_j - s_k|\big],

把 argmax 换成 softmax(温度 τ\tau),得到一个 n×nn \times n 的行随机矩阵 P^\hat P,第 ii 行是”排在第 ii 位的是哪个物品”的分布。和 Gumbel-softmax 把 argmax 换成 softmax 是同一个想法;配合 Gumbel 噪声(s~=log⁡s+g\tilde s = \log s + g),就得到 PL 分布的可重参数化松弛。

代码 05 第 2 部分:τ=0.01\tau = 0.01 时 P^\hat P 就是真正的置换矩阵;τ=1\tau = 1 时每行和真置换矩阵的平均差 0.56,“松弛的第一名”(P^s)1=0.999(\hat Ps)_1 = 0.999(真的最大值 1.2,被拉向平均)。按行取 argmax 和温度无关,总能还原真排序。每一行和为 1,但列和不为 1(τ=1\tau = 1 时最多偏离 0.19)——同一个物品可能被”分到”多于一个位置,这是 NeuralSort 的已知缺点。

8.3 学一个排序

代码 05 第 3 部分:6 个物品、相关度 (3, 0, 2, 1, 0, 2.5),最大化期望 DCG(最优 6.008),720 个排列可以枚举出精确梯度:

估计量相对偏差相对标准差优化 1,500 步后的 E[DCG]\mathbb{E}[\mathrm{DCG}]排对的比例
REINFORCE + 留一法0.0202.975.9891.00
Gumbel + NeuralSort τ=0.2\tau = 0.20.0413.805.9841.00
Gumbel + NeuralSort τ=1\tau = 10.1152.455.9941.00
Gumbel + NeuralSort τ=5\tau = 50.4541.175.8940.50

和类别变量完全是同一个图景:REINFORCE 无偏;松弛的偏差随温度升高、方差随温度降低。温度太高时目标变成”糊掉的排序”的 DCG,一半的运行最后排错了。n=20n = 20 时排列有 2.4×10182.4 \times 10^{18} 个,枚举只在玩具规模可行——这正是需要这些估计量的原因。


9. 2023 年之后 · Since 2023

  • REINFORCE 的复兴:大语言模型的强化学习。 语言模型生成的每个 token 是离散的,奖励(人类偏好、答案是否正确)是黑箱——这正是 §2 的设定。Ahmadian et al.(ACL 2024)指出,对 RLHF 来说 PPO 的很多复杂性不必要,REINFORCE + 留一法基线(RLOO,就是 §4.4)就足够好。DeepSeekMath(Shao et al. 2024)提出的 GRPO 用组内平均当基线、再除以组内标准差(§4.5),后来被 DeepSeek-R1(2025)等推理模型的训练采用;Liu et al.(2025,Dr. GRPO)分析了除以标准差和按长度归一化带来的偏差。
  • 离散码本成为生成模型的”分词器”。 VQ-VAE(van den Oord et al. 2017)用直通估计(§7.3)训练离散码本,VQGAN(Esser et al. 2021)加上对抗损失;图像和视频被压成离散 token 序列,再用自回归或掩码 Transformer 生成(MaskGIT 2022、Parti 2022、LlamaGen 2024 等)。FSQ(Mentzer et al., ICLR 2024)用逐维取整代替码本查找,同样靠直通估计训练,避免了码本”坍缩”。音频编解码器(SoundStream、EnCodec)也是这条路线。
  • 推理链作为离散隐变量。 把语言模型的”思考过程”看成离散隐变量 zz、把答案看成 xx,最大化 log⁡∑zp(z)p(x∣z)\log\sum_z p(z)p(x \mid z)——其变分或 EM 式的训练(例如 Hoffman et al., NeurIPS 2023 的 TRICE)正是本讲的问题:zz 的空间巨大、离散、只能采样。
  • 离散数据上的扩散模型。 离散的数据(文本)不能用 ∇xlog⁡p\nabla_x\log p,但可以用”概率比”代替梯度——第 18 讲。

10. 小结 · Summary

  1. 离散让重参数化失效:zz 不是 ϕ\phi 的可导函数,ff 也只在离散点上有定义。
  2. REINFORCE:∇Eq[f]=Eq[f ∇log⁡q]\nabla\mathbb{E}_q[f] = \mathbb{E}_q[f\,\nabla\log q],无偏、通用(ff 可以是黑箱),方差大;对奖励的零点敏感(加 100,标准差涨约 150 倍)。
  3. 控制变量:f−a(h−Eh)f - a(h - \mathbb{E}h) 无偏,方差降到 1−ρ21 - \rho^2;基线是 h=∇log⁡qh = \nabla\log q 时的控制变量。常数基线 → 输入相关的基线(NVIL)→ 留一法,一级比一级更贴近”这个 xx 的平均水平”。
  4. 离散 VAE 的鞍点:“q 均匀 ⇒ 解码器忽略 z ⇒ 信号消失”,单样本 REINFORCE 爬不出来;减方差的技巧要和优化器(Adam)、闭式 KL 的处理方式一起考虑。
  5. Gumbel-max:argmax(log π + Gumbel) ~ Categorical(π)。Gumbel-softmax:把 argmax 换成 softmax(·/τ),可重参数化;argmax 的分布不变,但 E[y^]≠π\mathbb{E}[\hat y] \neq \pi。
  6. 温度的偏差–方差权衡:τ\tau 小偏差小、方差大;τ\tau 大反之;最好的 τ\tau 取决于能平均多少次。偏差可以让优化收敛到错误的离散解。
  7. VAE 里的松弛:解码器会从 y^\hat y 的小数部分”偷看”信息,松弛目标过于乐观(τ=2\tau = 2 时偷看 18 bit);直通估计没有偷看,但梯度有偏。
  8. 排列:Gumbel 排序 = Plackett–Luce 采样;NeuralSort 是排序的松弛;同样的偏差–方差图景。

11. 常见误区 · Common pitfalls

  1. “离散变量没法求梯度,所以离散隐变量模型不能用梯度训练。” REINFORCE 给出的是期望对参数的精确梯度的无偏估计;不可导的是样本,不是期望(§2.3)。
  2. “基线会让估计有偏。” 只要基线不依赖当前样本 zz(可以依赖 xx、可以依赖其他样本),E[b ∇log⁡q]=0\mathbb{E}[b\,\nabla\log q] = 0,就无偏(§4.2)。用包括自己在内的组平均当基线才会引入(纯缩放的)偏差(§4.5)。
  3. “REINFORCE 的方差大,是因为样本太少。” 更主要的原因是学习信号的”零点”和”与 zz 无关的部分”(§2.4、§4.3);一个好基线比十倍的样本还有效。
  4. “Gumbel-softmax 是离散分布的重参数化。” Gumbel-max 才是精确的离散采样;Gumbel-softmax 是另一个(连续)分布,优化它得到的是有偏的梯度(§6.2)。
  5. “温度越低越好,因为越接近离散。” 偏差小了,方差却按 1/τ1/\tau 增长;要看能平均多少次(§6.3)。
  6. “训练时的松弛 ELBO 就是模型的 ELBO。” 解码器会利用 y^\hat y 的小数部分;必须用离散的 zz 评估(§7.2:τ=2\tau = 2 时差 18 bit)。
  7. “直通估计是无偏的,因为前向用的是真正的离散值。” 前向的值无偏,反向的梯度是借来的、有偏(§7.3)。
  8. “方差归一化总是有用的。” 在 Adam 下它几乎只改变各项的相对权重;如果 KL 是闭式算的、没被归一化,它会把编码器推向均匀(§4.3)。

12. 练习 · Exercises

练习 1(对数导数技巧的前提) (a) 推导 ∇ϕEqϕ[fϕ(z)]=Eq[fϕ∇log⁡qϕ]+Eq[∇ϕfϕ]\nabla_\phi\mathbb{E}_{q_\phi}[f_\phi(z)] = \mathbb{E}_q[f_\phi\nabla\log q_\phi] + \mathbb{E}_q[\nabla_\phi f_\phi]。(b) 对 ELBO 的学习信号 fϕ=log⁡p(x,z)−log⁡qϕ(z∣x)f_\phi = \log p(x, z) - \log q_\phi(z \mid x),证明第二项为零。

参考答案

(a) ∇∑zqf=∑z(∇q)f+∑zq∇f\nabla\sum_z q f = \sum_z(\nabla q)f + \sum_z q\nabla f,第一项用 ∇q=q∇log⁡q\nabla q = q\nabla\log q。(b) ∇ϕfϕ=−∇ϕlog⁡qϕ\nabla_\phi f_\phi = -\nabla_\phi\log q_\phi,Eq[∇log⁡q]=∑z∇q=∇∑zq=0\mathbb{E}_q[\nabla\log q] = \sum_z\nabla q = \nabla\sum_z q = 0。注意:这只在期望里成立;单个样本的 ∇log⁡q\nabla\log q 不为零,把它留在估计量里只会增加方差。

练习 2(多臂老虎机的精确梯度) 对 q=softmax(ϕ)q = \mathrm{softmax}(\phi)、J=∑zπzμzJ = \sum_z\pi_z\mu_z,证明 ∂J/∂ϕj=πj(μj−J)\partial J/\partial\phi_j = \pi_j(\mu_j - J),并验证它等于 Eq[μz(ez−π)j]\mathbb{E}_q[\mu_z(e_z - \pi)_j]。

参考答案

∂πz/∂ϕj=πz(δzj−πj)\partial\pi_z/\partial\phi_j = \pi_z(\delta_{zj} - \pi_j),所以 ∂J/∂ϕj=∑zμzπz(δzj−πj)=πjμj−πjJ\partial J/\partial\phi_j = \sum_z\mu_z\pi_z(\delta_{zj} - \pi_j) = \pi_j\mu_j - \pi_jJ。另一边 Eq[μz(δzj−πj)]=πjμj−πjJ\mathbb{E}_q[\mu_z(\delta_{zj} - \pi_j)] = \pi_j\mu_j - \pi_jJ,相同。代码 01 的 exact_grad 就是这个公式。

练习 3(最优常数基线) 对标量参数,求使 Var[(f−b)s]\mathrm{Var}[(f - b)s] 最小的 bb(s=∂log⁡q/∂ϕs = \partial\log q/\partial\phi)。它什么时候等于 E[f]\mathbb{E}[f]?

参考答案

Var=E[(f−b)2s2]−(E[fs])2\mathrm{Var} = \mathbb{E}[(f - b)^2s^2] - (\mathbb{E}[fs])^2(因为 E[bs]=0\mathbb{E}[bs] = 0,均值与 bb 无关)。对 bb 求导:−2E[(f−b)s2]=0⇒b∗=E[fs2]/E[s2]-2\mathbb{E}[(f - b)s^2] = 0 \Rightarrow b^* = \mathbb{E}[fs^2]/\mathbb{E}[s^2]。当 ff 与 s2s^2 不相关时 b∗=E[f]b^* = \mathbb{E}[f]。代码 01 第 3 部分:bj∗=0.803b_j^* = 0.803,和控制变量公式的 a∗a^* 一致。

练习 4(组平均 vs 留一法) 证明 fs−1S∑s′fs′=S−1S(fs−1S−1∑s′≠sfs′)f_s - \frac1S\sum_{s'}f_{s'} = \frac{S-1}{S}\big(f_s - \frac{1}{S-1}\sum_{s' \neq s}f_{s'}\big),并说明为什么”组平均(含自己)“的估计量期望是真梯度的 (S−1)/S(S-1)/S 倍。

参考答案

右边展开:S−1Sfs−1S∑s′≠sfs′=fs−1Sfs−1S∑s′≠sfs′\frac{S-1}{S}f_s - \frac1S\sum_{s'\neq s}f_{s'} = f_s - \frac1S f_s - \frac1S\sum_{s' \neq s}f_{s'} = 左边。留一法无偏,乘常数 (S−1)/S(S-1)/S 后期望也乘这个常数。代码 01 的”长度比”一列 0.74–0.75 就是 3/43/4。

练习 5(Gumbel-max 与 log-sum-exp) (a) 证明 max⁡i(log⁡πi+gi)∼Gumbel(log⁡∑iπi,1)\max_i(\log\pi_i + g_i) \sim \mathrm{Gumbel}(\log\sum_i\pi_i, 1)。(b) 由此说明 E[max⁡i(xi+gi)]=log⁡∑iexi+γ\mathbb{E}[\max_i(x_i + g_i)] = \log\sum_ie^{x_i} + \gamma——“Gumbel 噪声下的 max 是 log-sum-exp 的随机版本”。

参考答案

(a) P(max⁡≤u)=∏iFi(u)=exp⁡(−e−u∑iπi)=exp⁡(−e−(u−log⁡∑π))P(\max \leq u) = \prod_iF_i(u) = \exp(-e^{-u}\sum_i\pi_i) = \exp(-e^{-(u - \log\sum\pi)}),正是位置参数 log⁡∑π\log\sum\pi 的 Gumbel 分布函数。(b) Gumbel(μ,1)(\mu, 1) 的均值是 μ+γ\mu + \gamma。这也说明了为什么 softmax 是 argmax 的”光滑版本”:log-sum-exp 是 max 的光滑版本,它的梯度就是 softmax。

练习 6(Concrete 的密度,K=2K = 2) K=2K = 2 时 y^1=σ((log⁡π1−log⁡π2+g1−g2)/τ)\hat y_1 = \sigma((\log\pi_1 - \log\pi_2 + g_1 - g_2)/\tau),g1−g2g_1 - g_2 服从标准 logistic 分布。由此推出 y^1\hat y_1 的密度,并和 §6.1 的公式核对。

参考答案

令 α=π1/π2\alpha = \pi_1/\pi_2,L=g1−g2L = g_1 - g_2 的分布函数 σ(l)\sigma(l)。y^1=σ((log⁡α+L)/τ)\hat y_1 = \sigma((\log\alpha + L)/\tau),即 L=τ logit(y)−log⁡αL = \tau\,\mathrm{logit}(y) - \log\alpha。p(y)=σ′(L) dLdy=σ(L)(1−σ(L))⋅τy(1−y)p(y) = \sigma'(L)\,\frac{dL}{dy} = \sigma(L)(1 - \sigma(L))\cdot\frac{\tau}{y(1-y)}。σ(L)=α−1yτ(1−y)−τ1+α−1yτ(1−y)−τ\sigma(L) = \frac{\alpha^{-1}y^\tau(1-y)^{-\tau}}{1 + \alpha^{-1}y^\tau(1-y)^{-\tau}},化简得 p(y)=ταy−τ−1(1−y)−τ−1(αy−τ+(1−y)−τ)2p(y) = \frac{\tau\alpha y^{-\tau-1}(1-y)^{-\tau-1}}{(\alpha y^{-\tau} + (1-y)^{-\tau})^2},和 §6.1 的公式(K=2K = 2,(K−1)!=1(K-1)! = 1)一致。

练习 7(松弛的偏差,线性目标) 设 f(z)=c⊤zf(z) = c^\top z 是线性的。证明 REINFORCE 的期望梯度和 Gumbel-softmax 的期望梯度分别是 ∇ϕc⊤π\nabla_\phi c^\top\pi 和 ∇ϕc⊤Eg[y^]\nabla_\phi c^\top\mathbb{E}_g[\hat y],并用代码 03 第 2 部分的表格说明后者在 τ=1\tau = 1 时为什么不对。

参考答案

Ez∼π[c⊤z]=c⊤π\mathbb{E}_{z\sim\pi}[c^\top z] = c^\top\pi,REINFORCE 无偏地估计它的梯度。Gumbel-softmax 优化的是 Eg[c⊤y^]=c⊤Eg[y^]\mathbb{E}_g[c^\top\hat y] = c^\top\mathbb{E}_g[\hat y]。表格显示 τ=1\tau = 1 时 E[y^]=(0.237,0.315,0.448)≠π=(0.2,0.3,0.5)\mathbb{E}[\hat y] = (0.237, 0.315, 0.448) \neq \pi = (0.2, 0.3, 0.5):被拉向均匀分布,所以函数 ϕ↦E[y^]\phi \mapsto \mathbb{E}[\hat y] 和 ϕ↦π\phi \mapsto \pi 不同,梯度也不同。只有 τ→0\tau \to 0 时两者一致。

练习 8(解码器为什么能”偷看”) K=2K = 2、M=1M = 1 时,解码器的输入是 y^=(y^1,1−y^1)\hat y = (\hat y_1, 1 - \hat y_1)。证明 y^1\hat y_1 是 logit1(x)−logit2(x)+(g1−g2)\text{logit}_1(x) - \text{logit}_2(x) + (g_1 - g_2) 的单调函数,并说明:在 τ\tau 不太小时,它携带了离散的 z=1[y^1>0.5]z = \mathbb{1}[\hat y_1 > 0.5] 所没有的、关于 xx 的连续信息。这和 §7.2 表格里”偷看”一列随 τ\tau 增大有什么关系?

参考答案

y^1=σ((Δ(x)+L)/τ)\hat y_1 = \sigma((\Delta(x) + L)/\tau),Δ=logit1−logit2\Delta = \text{logit}_1 - \text{logit}_2,是 Δ+L\Delta + L 的单调函数,所以解码器从 y^1\hat y_1 能还原 Δ(x)+L\Delta(x) + L——一个连续的、带噪声的关于 xx 的量;而离散的 zz 只告诉它 Δ+L\Delta + L 的符号(1 bit)。τ\tau 大时 y^1\hat y_1 远离 0、1,这个连续量容易被解码器读出(偷看得多);τ→0\tau \to 0 时 y^1\hat y_1 饱和在 0 或 1,只剩符号。表格里偷看的信息从 τ=0.1\tau = 0.1 的 0.18 bit 涨到 τ=2\tau = 2 的 18 bit。

练习 9(Plackett–Luce 的第二名) 在 PL 分布下,求”物品 jj 排第二”的概率,并对 s=(1,2,3,4)s = (1, 2, 3, 4) 的物品 4 算出数值。用它核对代码 05 第 1 部分”物品 4 进入前 2”的概率 0.7159。

参考答案

第一名是 ii 的概率 si/Ss_i/S(S=∑sS = \sum s),之后在剩下的物品里选,剩余总分是 S−siS - s_i:P(σ2=j)=∑i≠jsiS⋅sjS−siP(\sigma_2 = j) = \sum_{i \neq j}\frac{s_i}{S}\cdot\frac{s_j}{S - s_i}。物品 4(S=10S = 10):110⋅49+210⋅48+310⋅47=0.0444+0.1000+0.1714=0.3159\frac{1}{10}\cdot\frac49 + \frac{2}{10}\cdot\frac48 + \frac{3}{10}\cdot\frac47 = 0.0444 + 0.1000 + 0.1714 = 0.3159。进入前 2 = 排第一(4/10=0.44/10 = 0.4)+ 排第二(0.3159)= 0.7159,和代码一致。容易犯的错误是把分母写成 S−sjS - s_j 或忘了它随第一名变化。

练习 10(REINFORCE 用于 LLM) 把一个语言模型对提示 cc 生成的回答 y=(y1,…,yT)y = (y_1, \dots, y_T) 看成离散的”隐变量”,奖励 R(c,y)R(c, y) 是黑箱。(a) 写出 ∇θEy∼pθ(⋅∣c)[R]\nabla_\theta\mathbb{E}_{y \sim p_\theta(\cdot\mid c)}[R] 的 REINFORCE 形式,说明 ∇log⁡pθ(y∣c)\nabla\log p_\theta(y \mid c) 怎样分解到每个 token。(b) 对同一个提示采样 SS 个回答,写出 RLOO 的估计量。(c) 为什么基线可以依赖提示 cc,却不能依赖回答 yy?

参考答案

(a) Ey[R(c,y)∇log⁡pθ(y∣c)]\mathbb{E}_y[R(c, y)\nabla\log p_\theta(y \mid c)],log⁡pθ(y∣c)=∑tlog⁡pθ(yt∣c,y<t)\log p_\theta(y \mid c) = \sum_t\log p_\theta(y_t \mid c, y_{<t})——每个 token 的 log-softmax 梯度之和(第 3 讲的自回归分解)。(b) 1S∑s(Rs−1S−1∑s′≠sRs′)∇log⁡pθ(y(s)∣c)\frac1S\sum_s(R_s - \frac{1}{S-1}\sum_{s'\neq s}R_{s'})\nabla\log p_\theta(y^{(s)} \mid c)。(c) Ey[b(c)∇log⁡p(y∣c)]=b(c)⋅0=0\mathbb{E}_{y}[b(c)\nabla\log p(y \mid c)] = b(c)\cdot 0 = 0;若 bb 依赖 yy,这一项不再为零,估计有偏。提示 cc 在这里扮演 VAE 里 xx 的角色,b(c)b(c) 就是 NVIL 的输入相关基线(PPO 的价值函数是它的推广)。


13. 延伸阅读 · Further reading

REINFORCE 与控制变量

  • Williams, Simple Statistical Gradient-Following Algorithms for Connectionist Reinforcement Learning, Machine Learning 1992
  • Mnih & Gregor, Neural Variational Inference and Learning in Belief Networks, ICML 2014(NVIL)
  • Mnih & Rezende, Variational Inference for Monte Carlo Objectives, ICML 2016(VIMCO)
  • Kool, van Hoof & Welling, Buy 4 REINFORCE Samples, Get a Baseline for Free!, ICLR 2019 Workshop
  • Mohamed, Rosca, Figurnov & Mnih, Monte Carlo Gradient Estimation in Machine Learning, JMLR 2020(综述)
  • Tucker et al., REBAR, NeurIPS 2017;Grathwohl et al., Backpropagation through the Void(RELAX), ICLR 2018;Yin & Zhou, ARM, ICLR 2019

连续松弛

  • Jang, Gu & Poole, Categorical Reparameterization with Gumbel-Softmax, ICLR 2017
  • Maddison, Mnih & Teh, The Concrete Distribution, ICLR 2017
  • Bengio, Léonard & Courville, Estimating or Propagating Gradients Through Stochastic Neurons for Conditional Computation, 2013(直通估计)
  • Huijben, Kool, Paulus & van Sloun, A Review of the Gumbel-max Trick and its Extensions for Discrete Stochasticity in Machine Learning, TPAMI 2022

组合对象

  • Grover, Wang, Zweig & Ermon, Stochastic Optimization of Sorting Networks via Continuous Relaxations, ICLR 2019(NeuralSort)
  • Kool, van Hoof & Welling, Stochastic Beams and Where to Find Them: The Gumbel-Top-k Trick, ICML 2019
  • Xie & Ermon, Reparameterizable Subset Sampling via Continuous Relaxations, IJCAI 2019

2023 年之后

  • Ahmadian et al., Back to Basics: Revisiting REINFORCE Style Optimization for Learning from Human Feedback in LLMs, ACL 2024
  • Shao et al., DeepSeekMath, 2024(GRPO);Liu et al., Understanding R1-Zero-Like Training: A Critical Perspective, 2025
  • van den Oord, Vinyals & Kavukcuoglu, Neural Discrete Representation Learning(VQ-VAE), NeurIPS 2017;Mentzer et al., Finite Scalar Quantization: VQ-VAE Made Simple, ICLR 2024
  • Hoffman et al., Training Chain-of-Thought via Latent-Variable Inference, NeurIPS 2023

14. 下一讲预告 · Next lecture

这一讲处理的是离散的隐变量;数据本身(像素世界的 0/1 像素)用的是自回归或伯努利似然。最后一讲(原课 Lecture 18,客座讲者 Aaron Lou,Diffusion Models for Discrete Data)回到第 16 讲的扩散模型,问:数据是离散的(文本)时,扩散模型依赖的得分 ∇xlog⁡p(x)\nabla_x\log p(x) 没有定义——怎么办?

  • 具体得分(concrete score):用概率比 p(y)/p(x)p(y)/p(x) 代替梯度,只看”相邻”的状态;
  • 得分熵(score entropy)损失,以及它的去噪版本;
  • 连续时间马尔可夫链:均匀转移与吸收(掩码)转移,反向过程由概率比给出;
  • 采样(一次改多个 token)、提示补全与填空、似然的上界与困惑度——和自回归模型比较。
← 返回课程目录