Skip to main content

重要性采样(Importance Sampling)详解:从"为什么要有这个东西"讲起

🎯 一句话定位: 重要性采样就是「我没法从目标分布 pp 里采样,只好从另一个容易的分布 qq 里采样,然后给每个样本乘一个修正权重,让最终的期望(平均值)还能算对」的一套技巧。

它离你的 CartPole 代码只有一步之遥:你现在 rollout() 采轨迹用的是当前策略 πθ\pi_{\theta_{旧}},算完梯度就立即更新成 θ\theta_{新},这叫同策略 on-policy。 可是一旦你想「旧策略采到的轨迹能不能复用给更新了好几次的新策略再用?」或者「我想让一个专家/随机策略录的示范数据,也能训练我的当前策略?」——这时候同策略不行了,就得靠重要性采样来「修正分布差」。


〇、先讲一个大白话例子:想算中国人平均身高,却只抽到了北京人

这一节一个公式都不写,你把直觉建立起来,后面的数学其实就是把这句话翻译成符号。

故事背景

你是一个人口调查员,任务是算:

全中国人的平均身高(期望)是多少?

最理想的做法(叫「从目标分布 pp 里采样」):

  • 把 14 亿人编上号,完全随机抽 1 万人,每人测身高,相加 ÷ 10000 → 这就是无偏估计,平均下来一定是真的全国均值。

可是现实打了你一巴掌:公司预算只够你跑一趟北京,你只能在北京街头抽样 1 万人(这叫「从提议分布 qq 里采样」,因为方便、便宜、能拿到)。

北京人身高其实比全国平均整体偏高一点(比如北京的 qq 分布整体右移了几厘米)。

关键问题来了: 如果我就拿着「北京抽的 1 万人」的数据,硬算一个 sum(身高)/10000,会怎么样? 👉 结果肯定偏大,有系统性偏差(Bias)

怎么救?—— 给每个人乘一个「校正系数」再求平均

答案:不是直接把身高求平均,而是给每个人的身高乘一个「他有多大代表性」的权重,再加起来。

直觉:

  • 在北京抽到一个特别矮的人(150cm):这个人在北京分布 qq 里是罕见的(北京矮的少,抽到概率低),但他在全国分布 pp 里其实不罕见(全国矮个子比例比北京高很多); → 说明他的「代表性很高」,他的身高在全国平均值里应该被放大一点权重
  • 在北京抽到一个特别高的人(195cm):这个人在北京分布里挺常见,在全国分布里却挺罕见; → 说明他的「代表性很低」,他的身高在全国平均值里应该被缩小一点权重

这个「校正系数」就是著名的:

w(x)=p(x)q(x)\boxed{ w(x) = \dfrac{p(x)}{q(x)} }
  • p(x)p(x)目标分布里出现一个身高为 xx 的人的真实概率密度(我们关心的全国分布)
  • q(x)q(x)实际采样分布(提议分布)里出现身高 xx 的概率密度(我们实际上抽样的北京分布)
  • 读成:"这个人在目标里有多常见 ÷ 在采样里有多常见"

你再感受一下它的直觉:

  • 如果某个人在 pp 里很常见、在 qq 里很少见 → 分子大、分母小 → w>1w>1放大他的贡献(代表性强)
  • 如果某个人在 pp 里很少见、在 qq 里很常见 → 分子小、分母大 → w<1w<1缩小他的贡献(代表性弱)
  • 如果两者一样常见 → w=1w=1 → 这个人本来就有代表性,不用修正。

好了,重要性采样的全部直觉就这一句话

"从 qq 抽一个样本 xix_i,不要直接用 f(xi)f(x_i),要给它乘权重 w(xi)=p(xi)q(xi)w(x_i)=\frac{p(x_i)}{q(x_i)} 再加起来求平均,结果就等于从 pp 里抽样的期望。"

下面就是把这句大白话写成严谨的数学公式,你会发现每一步都对应着上面故事里的一句话。


一、问题的正式提法:我想算 pp 分布下 f(X)f(X) 的期望,但是抽不到 pp

1.1 我们真正想算的东西("目标期望")

我们有一个目标随机变量 XX,它服从分布 p(x)p(x)。我们想求一个函数 f(x)f(x) 在这个分布下的平均值(期望):

EXp[f(X)]=xp(x)f(x)dx(目标期望)\mathbb{E}_{X \sim p}[f(X)] = \int_x p(x)\, f(x)\, dx \tag{目标期望}

如果我们能直接从 pp 里抽 NN 个样本 x1,,xNpx_1, \dots, x_N \sim p,那就太爽了,直接样本平均就行:

EXp[f(X)]1Ni=1Nf(xi)(样本平均(无偏差))\mathbb{E}_{X \sim p}[f(X)] \approx \dfrac{1}{N}\sum_{i=1}^{N} f(x_i) \tag{样本平均(无偏差)}

1.2 现实:抽不到 pp,只能抽到另一个分布 qq

什么时候我们抽不到 pp?在强化学习里这是家常便饭,举三个你以后一定遇到的场景:

场景目标分布 pp想从它抽提议分布 qq只能从它抽
🎮 离策略(off-policy)训练:想训练新策略 πθ\pi_{\theta_{新}},但轨迹是旧策略 πθ\pi_{\theta_{旧}} 跑出来的新策略的轨迹分布 πθ(τ)\pi_{\theta_{新}}(\tau)旧策略的轨迹分布 πθ(τ)\pi_{\theta_{旧}}(\tau)
📖 模仿学习:专家录了一堆示范,想训练我的当前策略我的当前策略 πθ(τ)\pi_\theta(\tau)专家策略 πexpert(τ)\pi_{\text{expert}}(\tau)
🗄️ 经验回放(DQN / Replay Buffer):我把之前很多步的 (s,a,r,s)(s,a,r,s') 都放缓冲区里存着,想拿出来训练当前策略当前策略的 (s,a)(s,a) 联合分布过去一堆老策略混合的 (s,a)(s,a) 联合分布

这就是"为什么会出现重要性采样"的根本原因:

"想算的分布 pp 拿不到样本,只能拿到另一个分布 qq 的样本,需要用数学把它还原回来。"


二、核心公式推导:一步到位,就靠"乘个 1"的 trick

重要性采样的数学推导短到离谱,你高中数学就能看懂。我们的目标是:

把「对 p(x)p(x) 积分」改写成「对 q(x)q(x) 积分」,这样就能用 qq 的样本来算。

只需要一个小学代数的技巧:在积分里面乘以 q(x)q(x)\frac{q(x)}{q(x)}(它等于 1,不改变值)

EXp[f(X)]=xp(x)f(x)dx=xp(x)q(x)重要性权重 w(x)f(x)q(x)dx\mathbb{E}_{X \sim p}[f(X)] = \int_x p(x)\, f(x)\, dx = \int_x \underbrace{\dfrac{p(x)}{q(x)}}_{\text{重要性权重 } w(x)} \cdot f(x)\, q(x)\, dx

最后那个式子正好就是「随机变量 w(X)f(X)w(X) \cdot f(X)qq 分布下的期望」:

EXp[f(X)]=EXq ⁣[p(X)q(X)f(X)](IS 核心恒等式)\boxed{ \mathbb{E}_{X \sim p}[f(X)] = \mathbb{E}_{X \sim q}\!\left[\,\dfrac{p(X)}{q(X)}\, f(X)\,\right] } \tag{IS 核心恒等式}

这就是重要性采样全部的理论基础,一行就证完了

2.1 怎么用它?—— Monte Carlo 抽样版

把右边的期望,用从 qq 里抽出来的 NN 个样本 x1,,xNqx_1, \dots, x_N \sim q 做样本平均:

EXp[f(X)]  μ^IS  =  1Ni=1N p(xi)q(xi)wif(xi)(IS 蒙特卡洛估计器)\boxed{ \mathbb{E}_{X \sim p}[f(X)] \ \approx \ \widehat{\mu}_{\text{IS}} \;=\; \dfrac{1}{N}\sum_{i=1}^{N} \ \underbrace{\dfrac{p(x_i)}{q(x_i)}}_{w_i} \cdot f(x_i) } \tag{IS 蒙特卡洛估计器}

2.2 一个最重要的性质:它是无偏的

这个估计器对不对?我们来证一下它的期望正好是目标值(也就是「平均下来一定对」):

Ex1,,xNq ⁣[μ^IS]=1Ni=1NEXq ⁣[p(X)q(X)f(X)]=1NNEXp[f(X)]=EXp[f(X)]\mathbb{E}_{x_1,\dots,x_N \sim q}\!\left[\,\widehat{\mu}_{\text{IS}}\,\right] = \dfrac{1}{N}\sum_{i=1}^{N} \mathbb{E}_{X \sim q}\!\left[\,\dfrac{p(X)}{q(X)} f(X)\,\right] = \dfrac{1}{N} \cdot N \cdot \mathbb{E}_{X \sim p}[f(X)] = \mathbb{E}_{X \sim p}[f(X)]

就这么简单:只要你抽 xix_i 时,xix_iqq 里有概率(即 q(xi)>0q(x_i) > 0),并且 p(xi)>0p(x_i) > 0 的任何 xix_i 也必须在 qq 里有概率(这个条件叫「qq 的支撑集包含 pp 的支撑集」,大白话就是「pp 可能出现的样本,qq 也能抽到」),这个估计器就一定无偏。

🚨 必须满足的前提(缺一不可)

x,p(x)>0    q(x)>0(支撑集包含条件)\forall x,\quad p(x) > 0 \implies q(x) > 0 \tag{支撑集包含条件}

人话翻译:凡是目标分布 pp 可能产生的任何样本 xx,采样分布 qq 也必须能抽到它(至少概率要大于 00,哪怕 10810^{-8} 也行,不能是绝对 0)。

要是不满足,会发生什么?—— 某个样本 xix_ipp 里出现了,但是在 qq 里根本抽不到,那这一项的权重就会变成:

w(xi)=p(xi)0=w(x_i) = \dfrac{p(x_i)}{0} = \infty

整个估计直接被这一项拉到无穷大,直接炸掉。

💡 强化学习里这句话对应的一条工程铁律旧策略 πθ\pi_{\theta_{\text{旧}}} 绝对不能在任何状态下把某个动作的概率置成硬 0。

举个 CartPole 的例子:你旧策略在某个状态下「永远只会向右推」,向左推的概率是实打实的 00(比如你用 argmax 选动作或者对 Softmax 做了硬截断)。 之后新策略 πθ\pi_{\theta_{\text{新}}} 学到在这个状态下「应该向左推」,想复用这批旧数据训练时,重要性权重就会变成:

πθ(as)πθ(as)=某个正数0=\dfrac{\pi_{\theta_{\text{新}}}(a_{\text{左}} \mid s)}{\pi_{\theta_{\text{旧}}}(a_{\text{左}} \mid s)} = \dfrac{\text{某个正数}}{0} = \infty

梯度直接爆炸,训练全毁。

这就是为什么所有策略梯度算法里,策略网络的最后一层一定要用 Softmax,而且输出概率再小也只会趋近于 00(至少是 10810^{-8} 量级),永远不会出现硬 00 —— 本质就是为了满足上面这个「支撑集包含条件」


三、再讲一个极其简单的数值例子:你亲手算一遍就全记住了

这一节你自己跟着算 30 秒,比看 10 页推导还管用。

设定

  • 目标分布 pp:两枚硬币公平正反面,p()=0.5, p()=0.5p(正)=0.5,\ p(反)=0.5
  • 提议分布 qq:两枚硬币被做了手脚,出正的概率只有 0.2,出反的概率 0.8(很偏)
  • 我们想算的函数 f(x)f(x)
    • f()=100f(正) = 100
    • f()=0f(反) = 0

手算真值(不抽样,直接数学算)

EXp[f(X)]=0.5×100+0.5×0=50\mathbb{E}_{X \sim p}[f(X)] = 0.5 \times 100 + 0.5 \times 0 = 50

所以正确答案一定是 50

我们假装不知道 pp,只能从 qq 里抽 10 次

假设我实际从 qq 里抽了 10 次(按概率 0.2 / 0.8 抽的),抽到:

  • 2 次正面8 次反面(很符合 q 分布的预期)

❌ 错的做法:直接算样本平均(不加权重)

错误估计=110(100+1002 次正面+0++08 次反面)=20010=20\text{错误估计} = \frac{1}{10}\left(\underbrace{100+100}_{2\text{ 次正面}} + \underbrace{0+\cdots+0}_{8\text{ 次反面}}\right) = \frac{200}{10} = 20

结果 20,比真值 50 小了一倍半!——这就是因为我们用了一个"正面严重偏少"的分布去抽样,却没校正。

✅ 对的做法:重要性采样,每个样本先乘权重 wi=p/qw_i = p/q

先算两种结果的权重:

  • w()=p()q()=0.50.2=2.5w(正) = \frac{p(正)}{q(正)} = \frac{0.5}{0.2} = 2.5
  • w()=p()q()=0.50.8=0.625w(反) = \frac{p(反)}{q(反)} = \frac{0.5}{0.8} = 0.625

然后按 IS 公式加起来:

μ^IS=110(2.5×100+2.5×1002 次正面+0.625×0++0.625×08 次反面)=50010=50\widehat{\mu}_{\text{IS}} = \frac{1}{10}\Big( \underbrace{2.5 \times 100 + 2.5 \times 100}_{2\text{ 次正面}} + \underbrace{0.625 \times 0 + \cdots + 0.625 \times 0}_{8\text{ 次反面}} \Big) = \frac{500}{10} = \mathbf{50}

正好等于真值!

你看这 2 次正面,每个都被乘了 2.5 的权重——因为 q 分布里"正面"被抽得太少了(只抽到 2 次,真实 p 里应该抽到 5 次),所以每 1 次正面样本就要代表原来的 2.5 次,权重就是 2.5。反面被抽得太多,权重就小于 1。

这就是重要性采样名字里「重要性」这三个字的来源:

每个样本对目标期望的"真实贡献重要程度",和它在采样分布 q 里出现的频率不一定一样,所以要乘以 p/qp/q 这个权重,把它的重要性纠正回来。


四、重要性采样的「致命弱点」:方差巨大 & 极端权重

重要性采样听起来太爽了,不管你是啥分布,我都能换一个分布抽,然后乘个权重就对了?

——听起来像天上掉馅饼,所以它一定有代价。代价就是:方差可能炸到你怀疑人生。

4.1 直觉:你全靠几个「罕见样本」撑起来,能不抖吗?

回到刚才那个硬币例子:

  • 正面在 pp 里概率 0.5,在 qq 里只有 0.2
  • 权重 w()=2.5w(正) = 2.5,看起来还好;
  • 但如果我把 q()q(正) 改成 0.0001(就是说 q 里几乎抽不到正面),那么:
w()=0.50.0001=5000w(正) = \frac{0.5}{0.0001} = 5000

这意味着什么?——我可能抽 10000 个样本才遇到 1 次正面,这 1 次正面的 1 个样本就要代表 5000 个样本的贡献!

  • 如果我这次运气好,抽到了 1 次正面 → 估计值会一下冲上天
  • 如果我这次运气差,10000 次里一次正面都没抽到 → 估计值直接等于 0,和真值 50 差十万八千里。

这就叫「方差爆炸」——虽然「平均下来」这个估计器是无偏的(E[μ^]=50\mathbb{E}[\hat\mu]=50),但你单次拿一批样本算出来的结果,波动能从 0 到几百万,根本没法用

4.2 数学上怎么看方差爆炸(一句话)

IS 估计器的方差公式是(你不用记,看结论就行):

Varxq ⁣[w(X)f(X)]=Eq ⁣[w(X)2f(X)2](Ep[f(X)])2\mathrm{Var}_{x \sim q}\!\left[\,w(X) f(X)\,\right] = \mathbb{E}_q\!\left[\,w(X)^2 f(X)^2\,\right] - \big(\mathbb{E}_p[f(X)]\big)^2

注意到了吗?——权重 w(x)w(x) 是「平方」的。只要有的样本权重特别大,方差就会被它的平方成倍放大。

业界有一句非常有名的吐槽:

「重要性采样在论文里永远成立,在工程里永远因为方差太大用不了。」

所以不要以为学到 IS 就解决了 off-policy,真正的强化学习算法(PPO、SAC、Importance Sampling with ESS 等)90% 的精力都是在解决「IS 的方差太大怎么压」。


五、救星 1:归一化重要性采样(WIS / Weighted Importance Sampling)

5.1 一个非常讨厌的现实:很多时候我们p(x)p(x) 自己都只知道差个常数倍

举个贝叶斯的常见情况(你以后看 RL 的贝叶斯算法、能量模型一定会遇到):

  • 我们想从「后验分布 p(θD)=p(Dθ)p(θ)p(D)p(\theta \mid D) = \frac{p(D \mid \theta) p(\theta)}{p(D)}」里抽样本,
  • 分母那个「证据 p(D)p(D)」是一个极其难算的积分(有时根本算不出来),
  • 所以我们只能写出 p~(θ)=p(Dθ)p(θ)\tilde p(\theta) = p(D \mid \theta) p(\theta),其中 p(θD)=p~(θ)Zp(\theta \mid D) = \frac{\tilde p(\theta)}{Z}而归一化常数 Z=p(D)Z = p(D) 未知

这时候分子分母都有一个未知的 ZZ,但它们能约掉。于是有人发明了:

5.2 WIS 的公式(「权重归一化版」)

μ^WIS=i=1Nwif(xi)i=1Nwi,其中 wi=p(xi)q(xi)(WIS 归一化估计器)\boxed{ \widehat{\mu}_{\text{WIS}} = \frac{\sum_{i=1}^{N} w_i\, f(x_i)}{\sum_{i=1}^{N} w_i}, \qquad \text{其中 } w_i = \frac{p(x_i)}{q(x_i)} } \tag{WIS 归一化估计器}

你对比一下普通 IS:

  • 普通 IS:sum(w_i * f_i) / N (权重平均用的是样本数 N
  • WIS:sum(w_i * f_i) / sum(w_i) (权重平均用的是权重和本身

5.3 WIS 直觉:权重和本来就应该是 N

当你从 qq 抽了 NN 个样本,在「理想状况」下 wi=N\sum w_i = N(因为每个权重平均是 1),但现实里抽样有随机误差,wi\sum w_i 经常不等于 N。WIS 的做法就是强制让权重和等于 1(归一化之后),把「归一化常数未知」的问题抵消掉。

5.4 代价:WIS 是有偏的,但是方差小很多

  • WIS 不保证「期望等于真值」,是有偏估计;
  • 但它在工程中比普通 IS 稳定太多,因为它自动把极端大的权重给压缩了(你一个 wi=10000w_i=10000,但分母里也有这个 1000010000,相当于你再大也得被别的权重平均一下)。

⚠️ RL 算法里一个小知识点: 其实我们平时在 REINFORCE 的 θJ\nabla_\theta J 估计器里,一般用的还是普通 IS(非归一化),因为策略梯度本身就是期望为 0 的无偏估计,换成 WIS 会引入偏差。但是对于离策略策略评估(比如要估计 VπV_{\pi_{新}},却用旧策略的数据),WIS 几乎是标配。


六、救星 2:限制 ppqq 不要差太远(策略比限制 / PPO 裁剪)

刚才我们说了,IS 方差炸的根本原因就是某些样本权重特别大。那怎么让权重不要太大?

一句话答案:别让 ppqq 差太远。

6.1 为什么 RL 里我们会遇到「p 和 q 差太远」?

在策略梯度里:

  • p=πθ(as)p = \pi_{\theta_{新}}(a \mid s)(现在刚更新完 θ 的策略,是我们想训练的目标)
  • q=πθ(as)q = \pi_{\theta_{旧}}(a \mid s)(刚才采数据时用的旧策略)
  • 重要性权重就是大名鼎鼎的:
ρt(atst)=πθ(atst)πθ(atst)(RL 状态-动作级重要性比率)\boxed{ \rho_t(a_t \mid s_t) = \dfrac{\pi_{\theta_{\text{新}}}(a_t \mid s_t)}{\pi_{\theta_{\text{旧}}}(a_t \mid s_t)} } \tag{RL 状态-动作级重要性比率}
  • 如果我一次梯度步太大,θ\theta_{新} 飞出去老远 → 这个比值 ρt\rho_t 在某些 (s,a)(s,a) 上变成 10、100、甚至 10000 → 方差直接炸。
  • 那怎么办?立法限制「新策略和旧策略的重要性比率,不许超出 [1-ε, 1+ε] 这个范围」

这就是 PPO(Proximal Policy Optimization,近邻策略优化)干的核心事,也正是你读完《基线原理》和《重要性采样》之后下一个要学的算法

PPO 裁剪目标(Clipped Surrogate Objective)就是:

LCLIP(θ)=Et ⁣[ min( ρt(θ)A^t, clip(ρt(θ),1ε,1+ε)A^t ) ](PPO 裁剪目标)L^{\text{CLIP}}(\theta) = \mathbb{E}_t\!\left[\ \min\Big(\ \rho_t(\theta)\, \hat A_t,\ \operatorname{clip}(\rho_t(\theta), 1-\varepsilon, 1+\varepsilon)\, \hat A_t\ \Big)\ \right] \tag{PPO 裁剪目标}

大白话翻译这行公式:

  • 如果 A^t>0\hat A_t > 0(这个动作是好动作,我想让它概率变大)→ 但也不许你把 ρt\rho_t 拉到 1+ε1+\varepsilon 以上,再多就封顶了;
  • 如果 A^t<0\hat A_t < 0(这个动作是坏动作,我想让它概率变小)→ 但也不许你把 ρt\rho_t 压到 1ε1-\varepsilon 以下,再少就封底了;
  • min 取两者的更保守那一个(悲观估计),防止更新过猛。

🎯 所以:PPO 的裁剪机制本质上就是「强行压制重要性采样的极端权重,换来方差可控」——这是重要性采样在实际强化学习中最著名的一次落地。


七、在强化学习里,重要性采样到底被用到了哪些地方?

这里给你一张全景地图,把「轨迹级、步级、策略评估、策略梯度」四种常见形态一次讲完。

7.1 应用一:离策略的策略梯度(从「旧策略轨迹」训练「新策略」)

你现在的 CartPole Agent.update()同策略的:数据是刚 rollout 的,策略和更新用的是同一个,所以不用 IS。

但如果你想把 300 个 step 之前 rollout 的轨迹全部存起来,现在拿出来反复训练(这叫数据复用,可以大大降低采样成本),你就得用 IS 修正。

  • 同策略(你现在的):
    θJ(θ)=Eτπθ ⁣[ t=0Tθlogπθ(AtSt)Gt ]\nabla_\theta J(\theta) = \mathbb{E}_{\tau \sim \pi_\theta}\!\left[\ \sum_{t=0}^{T} \nabla_\theta \log \pi_\theta(A_t \mid S_t)\, G_t\ \right]
  • 离策略(旧策略 β\beta 采样,新策略 πθ\pi_\theta 训练) + 轨迹级 IS
θJ(θ)=Eτβ ⁣[ P(τ;πθ)P(τ;β)轨迹级重要性权重 w(τ)t=0Tθlogπθ(AtSt)Gt ](off-policy 轨迹级 IS)\nabla_\theta J(\theta) = \mathbb{E}_{\tau \sim \beta}\!\left[\ \underbrace{\frac{P(\tau ; \pi_\theta)}{P(\tau ; \beta)}}_{\text{轨迹级重要性权重 } w(\tau)} \cdot \sum_{t=0}^{T} \nabla_\theta \log \pi_\theta(A_t \mid S_t)\, G_t\ \right] \tag{off-policy 轨迹级 IS}

这个 w(τ)w(\tau) 其实非常好算,因为轨迹就是一串 (s0,a0,,sT)(s_0,a_0,\dots,s_T),每一步都是乘起来的,转移概率都约掉之后只剩策略乘积的比值:

P(τ;πθ)P(τ;β)=t=0T1πθ(atst)β(atst)\frac{P(\tau ; \pi_\theta)}{P(\tau ; \beta)} = \prod_{t=0}^{T-1} \frac{\pi_\theta(a_t \mid s_t)}{\beta(a_t \mid s_t)}

但是要注意:轨迹级权重是 t\prod_{t},乘了 T 个小于 1 或大于 1 的数,会指数爆炸或指数消失。 所以工程里几乎不会用"全轨迹级 IS",而是用下面的「步级 IS + 因果性」。

7.2 应用二:步级 IS + 因果性(PPO 的实际做法)

每一步各自乘以「这一步之前的乘积」(只到 t,不到 T,避免乘 T 项指数爆炸),这是所有离策略策略梯度算法的标准做法:

θJ(θ)=Eτβ ⁣[ t=0T (k=0tπθ(aksk)β(aksk))截止到 t 的累计比率 ρ0:tθlogπθ(atst)A^t ](步级 IS + 因果策略梯度)\boxed{ \nabla_\theta J(\theta) = \mathbb{E}_{\tau \sim \beta}\!\left[\ \sum_{t=0}^{T}\ \underbrace{\left(\prod_{k=0}^{t} \frac{\pi_\theta(a_k \mid s_k)}{\beta(a_k \mid s_k)}\right)}_{\text{截止到 } t \text{ 的累计比率 } \rho_{0:t}} \cdot \nabla_\theta \log \pi_\theta(a_t \mid s_t)\, \hat A_t\ \right] } \tag{步级 IS + 因果策略梯度}

这就是 PPO、V-trace、IMPALA 这些工业级离策略算法在背后用的公式。

7.3 应用三:离策略策略评估 OPE(Offline RL 最核心的问题)

你有一批历史数据(比如已经下线的机器人/广告系统过去一年的决策日志),现在想在不上线测试的前提下,预测:「如果我换一个新策略 πe\pi_e 去跑,回报会变成多少?」

这个问题叫 Off-Policy Evaluation(OPE),它的核心公式就是 IS:

J(πe)=Eτβ ⁣[ P(τ;πe)P(τ;β)G(τ) ]J(\pi_e) = \mathbb{E}_{\tau \sim \beta}\!\left[\ \frac{P(\tau ; \pi_e)}{P(\tau ; \beta)}\, G(\tau)\ \right]

然后用 WIS 压方差(否则历史数据和新策略稍微差一点就没法用了)。Offline RL 领域绝大多数论文,本质上都是在发明更稳的「IS 权重截断 / 权重正则化 / Doubly Robust 双重稳健」方法


八、回到 CartPole:你的「批均值基线」和「重要性采样」是亲戚!

读到这你可能会想:你现在的 CartPole baseline 代码里,不是「减了一个基线 bb」吗?它和重要性采样到底有啥关系?

——答案:它们都是在干「让梯度估计更稳定」这件事,但是手段不一样,并且以后你会把它们合起来用。

方法解决的问题手段
基线 bb(你 CartPole baseline 里那个 avg_reward梯度估计的「方差太大」(整局回报 G 波动大)在目标函数里做减法:把 G(τ)G(\tau) 换成 (G(τ)b)(G(\tau) - b),期望不变,方差下降
重要性采样(本讲)「分布变了,样本来自另一个分布」导致估计有偏在目标函数里做乘法:每个样本乘权重 p/qp/q,把分布纠正回来,保证无偏
两者一起用(PPO 的实际形态)分布不一样 + 方差还大 → 要两个都用wi(Gib)=ππ(GiV(si))w_i \cdot (G_i - b) = \frac{\pi_{新}}{\pi_{旧}} \cdot (G_i - V(s_i)),最后再 PPO clip 一下 wiw_i

所以学习顺序就是你现在文档的顺序(完全顺的):

REINFORCE(同策略,没基线)
↓ 讲完后你写了 cartpole_reinforce_v1.py
加入基线(减 avg_reward 或减 V(s_t) Critic)
↓ 讲完后你写了 baseline 版本(减批均值)
加入重要性采样(旧数据给新策略用,乘权重 π_new/π_old)

加入 PPO clip(限制权重别太大,方差可控)

你现在就差最后一步了(PPO),前面的地基都铺好了。


九、常见坑总结(直接避坑)

  1. 坑:忘了支撑集条件,qq 抽不到某些 xx → 除 0 或直接偏差巨大
    • 避:Softmax 输出永远 > 0;策略绝对不要加 argmax 式「确定选动作」采样;旧策略别把任何动作概率锁死。
  2. 坑:ppqq 差太远 → 方差爆炸,估计器每一次跑出来都不一样,完全不可信
    • 避:PPO clip,或者「更新几步就重新采样(on-policy/near-on-policy)」,或者 WIS。
  3. 坑:把普通 IS 用在「权重和分布极差的情况」,结果被一两个样本牵着鼻子走
    • 避:监控权重的 ESS(有效样本数)ESS=(wi)2wi2\text{ESS} = \frac{(\sum w_i)^2}{\sum w_i^2} 如果 ESS 比 N 小很多(比如 ESS < N/10),就说明你的权重大部分被几个极端大的占据了,这一批样本扔了重采,或者 clip 一下权重再算。
  4. 坑:把 WIS 用在策略梯度(需要无偏)
    • 避:策略梯度里的 IS 比率用「普通 IS」,策略评估 OPE 里用「WIS + Doubly Robust」。

十、一页纸总结

问题答案
为什么出现?想从 pp 抽抽不到,只能从另一个方便的 qq
核心公式?Ep[f]=Eq ⁣[pqf]\mathbb{E}_p[f] = \mathbb{E}_q\!\left[\frac{p}{q} f\right]
权重叫什么?重要性权重 w=p/qw = p/q(目标概率 ÷ 采样概率)
优点?只要 pp 的支撑集包含在 qq 里,就是「无偏」的,平均下来一定对
代价?权重会平方地放大方差,p 和 q 稍微一远就炸
两大解药?① WIS(权重归一化,换偏差换方差)
② 限制 p/q 不要太离谱(PPO clip / TRPO 约束)
在 RL 里什么时候用?离策略训练 / 经验回放复用 / OPE 离线评估 / PPO 的新旧策略比率 ρt\rho_t

你现在理解了重要性采样,再去看 PPO 的 ρt(θ)\rho_t(\theta) 会有「啊,原来就是它!」的感觉——PPO 就是在重要性采样外面包了一层「安全护栏 clip」,让工程上能用。