策略梯度定理:第一个“怎么调 π”的推导
前三课定义了 RL 目标 $J(\pi)=\mathbb{E}_{\tau\sim\pi}[G]$,但没回答“怎么调 $\pi$ 使 $J$ 变大”。这课把策略写成带参数 $\theta$ 的函数 $\pi_\theta$,然后完整推导出梯度 $\nabla_\theta J$ 的表达式——它就是 PPO 和 GRPO 共同的数学地基。这是本课程第一个“硬”推导,请慢读。
一、出发:把策略参数化
我们要调的是参数 $\theta$(一个向量),策略是 $\theta$ 的函数:
$$ \pi_\theta(a\mid s) \quad\text{——给定 } s\text{,动作 }a\text{ 的概率,由 }\theta\text{ 决定} $$
典型选择:神经网络输出 logits,softmax 归一化得概率。本课代码演示用一个最简单的 softmax 策略 $\pi_\theta(a)=\mathrm{softmax}(\theta)_a$。
目标改成对 $\theta$ 求梯度。设一条轨迹 $\tau=(s_0,a_0,r_0,s_1,\ldots)$ 的总回报 $R(\tau)=\sum_t \gamma^t r_t$,则:
$$ J(\theta) \;=\; \mathbb{E}_{\tau\sim\pi_\theta}\!\left[\, R(\tau) \,\right] $$
目标是最大化 $J(\theta)$,即沿 $\nabla_\theta J$ 方向更新(梯度上升)。
二、推导:六步到终点
1对期望求梯度,环境与策略分离
把期望展开成对轨迹的积分,$p_\theta(\tau)$ 是轨迹概率:
$$ \nabla_\theta J(\theta) \;=\; \nabla_\theta \int p_\theta(\tau)\, R(\tau)\, d\tau \;=\; \int \nabla_\theta p_\theta(\tau)\, R(\tau)\, d\tau $$
2对数导数技巧(log-derivative trick)
核心恒等式:$\nabla p_\theta(\tau) = p_\theta(\tau)\,\nabla_\theta \log p_\theta(\tau)$。代入上式把 $p$ “凑回”成期望:
$$ \nabla_\theta J(\theta) \;=\; \mathbb{E}_{\tau\sim\pi_\theta}\!\left[\, \nabla_\theta \log p_\theta(\tau)\, R(\tau) \,\right] $$
3展开轨迹概率,环境项消失
轨迹概率 $p_\theta(\tau)=\rho_0(s_0)\prod_t \pi_\theta(a_t\mid s_t)\,P(s_{t+1}\mid s_t,a_t)$。取 log:
$$ \log p_\theta(\tau)=\log\rho_0(s_0)+\sum_t\!\big[\log\pi_\theta(a_t\mid s_t)+\log P(s_{t+1}\mid s_t,a_t)\big] $$
对 $\theta$ 求梯度时,初始分布 $\rho_0$ 和转移 $P$ 都与 $\theta$ 无关,全部消失,只剩策略项:
$$ \nabla_\theta \log p_\theta(\tau) \;=\; \sum_t \nabla_\theta \log \pi_\theta(a_t\mid s_t) $$
于是:
$$ \nabla_\theta J(\theta) \;=\; \mathbb{E}_{\tau\sim\pi_\theta}\!\left[\, \sum_t \nabla_\theta \log \pi_\theta(a_t\mid s_t)\, R(\tau) \,\right] $$
4因果性:丢掉“过去”的奖励(reward-to-go)
第 $t$ 步的动作 $a_t$ 影响 $t$ 及之后的奖励,但影响不到之前的奖励 $r_0,\ldots,r_{t-1}$。而过去奖励与 $a_t$ 无关,乘以 $\nabla\log\pi(a_t)$ 取期望为 0(用上面的恒等式)。所以 $R(\tau)$ 可替换为回报-to-go:
$$ G_t \;=\; \sum_{t'=t}^{T} \gamma^{t'-t}\, r_{t'} $$
得:
$$ \nabla_\theta J(\theta) \;=\; \mathbb{E}_{\tau\sim\pi_\theta}\!\left[\, \sum_t \nabla_\theta \log \pi_\theta(a_t\mid s_t)\, G_t \,\right] $$
5加基线:期望不变,方差大降
对任何不依赖 $a_t$ 的基线 $b(s_t)$,用恒等式 $\mathbb{E}[\nabla\log\pi\cdot b]=0$:
$$ \nabla_\theta J(\theta) \;=\; \mathbb{E}\!\left[\, \sum_t \nabla_\theta \log \pi_\theta(a_t\mid s_t)\,\big(G_t - b(s_t)\big) \,\right] $$
期望不变,但 $G_t$ 的方差很大;减去一个接近 $G_t$ 均值的基线能抵消大部分波动。最优基线是 $b(s_t)=V^\pi(s_t)$(第 3 课的状态价值),此时 $G_t - V^\pi$ 正是优势 $A^\pi$ 的估计:
6装裱:策略梯度定理
$$ \nabla_\theta J(\theta) \;=\; \mathbb{E}_{\tau\sim\pi_\theta}\!\left[\, \sum_t \nabla_\theta \log \pi_\theta(a_t\mid s_t)\; A^\pi(s_t,a_t) \,\right] $$
这就是本课的胜利:用采样就能估计一个不偏的梯度——每一步把“该动作比平均好多少”(优势 $A$)乘上“增大该动作概率的方向”($\nabla\log\pi$),求和取平均。
蒙特卡洛估计(一次轨迹就给出一个无偏估计):
$$ \widehat{\nabla_\theta J} \;=\; \sum_t \nabla_\theta \log \pi_\theta(a_t\mid s_t)\, A_t \quad\Rightarrow\quad \theta \;\leftarrow\; \theta + \alpha\, \widehat{\nabla_\theta J} $$
三、代码演示:让公式真正学会一个任务
下面用本课公式训练一个 3-臂老虎机(真值 $Q=[0.9,0.4,0.1]$,和第 3 课同一个例子)。策略 $\pi_\theta=\mathrm{softmax}(\theta)$,每步按 $\theta\leftarrow\theta+\alpha\,\nabla\log\pi(a)\cdot A$ 更新。预期:$\pi$ 会把概率质量挪到动作1。
| 公式项 | 代码 | 说明 |
|---|---|---|
| $\nabla_\theta\log\pi_\theta(a)$ | ([a==b]-pi[b]) | softmax 解析梯度 |
| $A=Q(a)-V$ | Q[a]-V | 优势,基线 $V=\Sigma\pi Q$ |
| $\theta\leftarrow\theta+\alpha\cdot\widehat{\nabla J}$ | theta[b]+=lr*g[b]*A | 梯度上升 |
本地运行:python lessons/code/0004_policy_gradient_bandit.py(零依赖)。
浏览器里直接训练
点“训练”用上面的公式跑 300 步策略梯度,看 $\pi$ 如何把质量挪到动作1。这是“抽象公式 → 实际学习”的活例子。
四、自测
问题 1:对数导数技巧 $\nabla p = p\,\nabla\log p$ 的最大作用是?
问题 2:为什么减基线 $b(s_t)$ 不改变梯度的期望?
五、推荐资源
本课推导直接对应 Spinning Up · Part 3: Intro to Policy Optimization。其中“Deriving the Simplest Policy Gradient → Expected Grad-Log-Prob Lemma → Don't Let the Past Distract You → Baselines”四节,正是本课的 step 1-2-4-5。强烈建议对照精读一遍,公式与代码逐行印证。
(1) $\nabla p = p\,\nabla\log p$ 这一步怎么来的?(链式法则)
(2) 为什么 $\mathbb{E}[\nabla\log\pi]=0$ 能推出“过去奖励可丢”和“可加基线”两件事?
(3) 你能在浏览器训练里,说出“动作1 概率为何上升”对应的每一项吗?
这是第 4 课。下一课预告:第 5 课 · RLHF 三阶段——把本课的策略梯度放进 LLM:SFT → 奖励模型 → PPO,看 InstructGPT 如何用人类偏好定义那个 $A$。
任何不懂的推导步骤,直接问老师。