一
先想清楚“直接学策略”是什么意思。在价值方法里,策略是隐式的——你学 ,策略只是“在每个状态选 最大的动作”这个附带操作。而在策略方法里,策略是显式的:用一个带参数 的函数 直接表示“在状态 下选各动作的概率”,这个函数可以就是一个神经网络。
这样做有几个直接的好处。对连续动作,网络可以直接输出一个高斯分布的均值和方差,从中采样出一个实数动作,根本不需要枚举或取 。对需要随机性的任务(比如猜拳,确定性策略必输),策略方法天然输出概率分布。而且策略往往比价值函数更简单、更平滑——有时“该往右走”这件事很好学,但精确估计“往右走值多少钱”反而很难。
问题是:怎么训练它?我们想最大化的是期望回报
{\tau\sim\pi\theta}\big[, G(\tau) ,\big]
其中 是一条按策略 走出来的轨迹, 是这条轨迹的回报。困难在于:回报依赖于环境怎么转移(这部分我们不知道、不可微),而轨迹的分布又依赖于 。怎么对一个“采样分布本身依赖参数”的期望求梯度?
二
1992 年,Ronald Williams 给出了第一个答案——REINFORCE 算法1。他用了一个数学上叫“对数导数技巧”的恒等式,把对采样分布的梯度,转化成了一个可以采样估计的期望。结论极其简洁:
读懂这一行,就读懂了所有策略梯度方法。它说:要让期望回报上升,就朝着 的方向调参数,并用这一步的回报 作权重。直觉上——如果某个动作 带来了高回报( 大且为正),就增大它的对数概率,让以后更可能选它;如果带来了负回报,就压低它的概率。回报的正负和大小,决定了“推”还是“拉”、推多用力。
而且注意:这个式子里没有环境转移的梯度。我们不需要知道环境怎么运作,只需要能采样轨迹、能对策略网络求梯度(这正是反向传播擅长的)。Williams 的原始论文标题朴素得很——《连接主义强化学习的简单统计梯度跟随算法》,并指出这类算法能“与反向传播自然结合”1。这句话在 1992 年还只是个理论提示,三十年后却成了训练每一个大模型对齐阶段的现实。
REINFORCE 有个明显的毛病:方差大。它用一整条轨迹的回报 当权重,而回报受运气影响很大(同一个好动作,可能因为后面运气差而 偏低),学习信号很噪。一个标准的降方差手段是引入基线(baseline):把权重从 换成 ,其中 是对该状态平均回报的估计。减去一个不依赖动作的基线不改变梯度的期望(数学上可证),却能大幅降低方差——它把“这个动作带来的回报”校准成“这个动作比平均好多少”。
三
REINFORCE 是个漂亮的直觉,但它的形式还不够一般。2000 年,Sutton、McAllester、Singh、Mansour 把它提炼成了策略梯度定理(policy gradient theorem)2。这条定理给出了策略梯度的精确、一般形式:
{s,a}\big[, \nabla\theta \log \pi_\theta(a\mid s), \cdot, Q^\pi(s,a) ,\big]
它和 REINFORCE 几乎一样,但把权重从“采样到的整条回报 ”换成了“动作价值 ”。更重要的是这条定理的一个深刻性质:梯度里不含状态分布对 的导数2。改变策略当然会改变你访问到哪些状态,但定理证明,那部分复杂的影响在求梯度时神奇地消失了,你只需关心“在每个状态如何调整动作概率”。这个结果让策略梯度方法有了坚实的理论地基,也允许用函数逼近(神经网络)来表示 。
把“用 (或它的某种估计)当权重”这个思路落实下来,就得到了 actor-critic 架构——强化学习里最有生产力的设计之一。它有两个部件:
- actor(演员):策略网络 ,负责“做动作”,按策略梯度更新。
- critic(评论家):价值网络 或 ,负责“评估动作好坏”,按 TD 误差(第十二章那条心跳)更新,给 actor 提供低方差的权重信号。
通常用的权重不是裸的 ,而是优势函数(advantage)——“这个动作比该状态的平均水平好多少”。优势把价值的绝对高低剥离,只留下相对的好坏,正是降方差的基线思想的精确化。actor 朝 上升,critic 同时学着把 估准,两者互相搀扶着进步。
四
用代码把策略梯度的内核走一遍。配套 code/13_reinforce_policy_gradient.py(纯 numpy)在一个长度为 7 的一维走廊上训练 REINFORCE:智能体从最左格出发,每步选“左”或“右”,走到最右格得 +1,其余每步 −0.05。策略是每个状态一组 softmax logits,参数就是这些 logits。核心更新只有几行:
展开代码 · 13_reinforce_policy_gradient.py
"""
第 13 章配套代码:REINFORCE(Monte-Carlo policy gradient, Williams 1992)。
纯 numpy,环境是一个 1xN 走廊:从最左走到最右得 +1。
策略是 softmax(theta),用策略梯度定理 ∇J = E[∇logπ(a|s) * G] 直接对参数上升。
对比"有 baseline 降方差"前后的学习曲线。
Runnable with: numpy only. python3 13_reinforce_policy_gradient.py
"""
import numpy as np
N = 7 # 走廊长度,状态 0..N-1,目标 N-1
ACTIONS = [-1, +1] # 左 / 右
GAMMA = 0.99
def softmax(z):
z = z - z.max()
e = np.exp(z)
return e / e.sum()
def run_episode(theta, rng, max_steps=50):
"""用当前策略走一局,返回轨迹 (states, actions, rewards)。"""
s = 0
S, A, R = [], [], []
for _ in range(max_steps):
probs = softmax(theta[s]) # 每个状态一组动作 logits
a = rng.choice(2, p=probs)
s_next = min(N - 1, max(0, s + ACTIONS[a]))
r = 1.0 if s_next == N - 1 else -0.05
S.append(s); A.append(a); R.append(r)
s = s_next
if s == N - 1:
break
return S, A, R
def reinforce(episodes=1500, lr=0.1, use_baseline=True, seed=0):
rng = np.random.default_rng(seed)
theta = np.zeros((N, 2)) # 策略参数: 每状态2个动作 logit
baseline = np.zeros(N) # 状态价值的滑动估计(baseline)
curve = []
for ep in range(episodes):
S, A, R = run_episode(theta, rng)
# 计算每步的回报 G_t(从 t 到结束的折扣累计)
G = np.zeros(len(R))
g = 0.0
for t in reversed(range(len(R))):
g = R[t] + GAMMA * g
G[t] = g
# 策略梯度上升: theta[s,a] += lr * (G_t - b(s)) * ∇logπ
for t, (s, a) in enumerate(zip(S, A)):
adv = G[t] - (baseline[s] if use_baseline else 0.0)
probs = softmax(theta[s])
grad = -probs
grad[a] += 1.0 # ∇logπ(a|s) = e_a - softmax
theta[s] += lr * adv * grad
if use_baseline:
baseline[s] += 0.05 * (G[t] - baseline[s])
curve.append(sum(R))
return theta, curve
def report():
print("=== REINFORCE (policy gradient) on 1x%d 走廊 ===" % N)
for use_b in (False, True):
theta, curve = reinforce(use_baseline=use_b)
first = np.mean(curve[:100]); last = np.mean(curve[-100:])
greedy = "".join("→" if softmax(theta[s])[1] > 0.5 else "←" for s in range(N - 1))
tag = "有 baseline" if use_b else "无 baseline"
print(f"\n[{tag}] 平均回报 前100局={first:+.3f} -> 末100局={last:+.3f}")
print(f" 学到的贪婪策略(状态0..{N-2}): {greedy} (全 → = 一路向右最优)")
print("\n结论: 策略梯度直接优化 softmax 策略;baseline 把 G_t 减去 b(s) 降低方差、更快收敛。")
if __name__ == "__main__":
report()
adv = G[t] - (baseline[s] if use_baseline else 0.0) # 优势 = 回报 - 基线
probs = softmax(theta[s])
grad = -probs; grad[a] += 1.0 # ∇logπ(a|s) = e_a - softmax
theta[s] += lr * adv * grad # 策略梯度上升
grad = e_a − softmax 正是 softmax 策略的对数梯度的解析形式:被选中的动作 那一项推高,其余按当前概率压低,再乘上优势作权重。跑出来:
[无 baseline] 平均回报 前100局=+0.501 -> 末100局=+0.736
学到的贪婪策略(状态0..5): →→→→→→ (全 → = 一路向右最优)
[有 baseline] 平均回报 前100局=+0.452 -> 末100局=+0.732
学到的贪婪策略(状态0..5): →→→→→→
两种设置最终都学到了“一路向右”这个最优策略——每个状态都把“右”的概率推到了 0.5 以上。这就是策略梯度最朴素的样子:没有 表、没有取 ,只是把“带来高回报的动作”的概率,一点点推高。在这么小的问题上 baseline 的方差优势看不太出来,但在动作多、轨迹长的真实任务里,优势函数对收敛速度的影响是决定性的。
五
朴素策略梯度有个让人头疼的实践问题:步子迈多大很难定。学习率太小,学得慢;太大,一次更新可能把策略推到一个很差的区域,而且因为后续数据都由这个变差的策略采集,可能再也爬不回来——监督学习里一次坏更新只是损失抖一下,强化学习里一次坏更新会污染之后的全部经验。
2015 年,John Schulman 等人提出 TRPO(Trust Region Policy Optimization,信赖域策略优化)来控制这个步长3。它的思想是:每次更新,在“新策略与旧策略的差异不超过一个信赖域”的约束下,最大化预期改进。差异用 KL 散度衡量:
直觉是:在“离旧策略不太远”的安全范围内,尽量改进。这个约束保证了每一步都是稳健的小改进,不会一脚踏空。TRPO 在连续控制上效果很好,但代价是数学和实现都复杂——那个 KL 约束需要二阶优化(涉及 Fisher 信息矩阵的近似),又重又难调。
为了估计上式里的优势 ,同年 Schulman 等人还提出了 GAE(Generalized Advantage Estimation,广义优势估计)4。它用一个参数 把不同步数的 TD 误差加权求和:
t = \sum{l=0}^{\infty} (\gamma\lambda)^l, \delta_{t+l},\qquad \delta_t = r_t + \gamma V(s_{t+1}) - V(s_t)
在偏差和方差之间插值—— 就是单步 TD(偏差大、方差小), 接近蒙特卡洛(偏差小、方差大),中间值取得平衡。GAE 这个看似不起眼的工具,几乎成了之后所有策略梯度方法估计优势的标配。
六
TRPO 好用但太重。2017 年,Schulman 等人发表了 PPO(Proximal Policy Optimization,近端策略优化),用一个朴素得多的技巧达到了 TRPO 的大部分好处5。
PPO 不再用复杂的 KL 硬约束,而是直接在目标函数里裁剪(clip)。设新旧策略的概率比 ,PPO 最大化:
读这个 :第一项 是普通的策略梯度目标;第二项把概率比 强行限制在 区间( 通常取 0.2)。取两者的较小值,效果是:当某个动作的优势为正、模型想大幅提高它的概率时,一旦概率比超过 ,目标就被截平,再怎么推也没有额外收益——于是策略不会一步迈太远。它用一个一阶可优化(普通梯度下降就能跑)的裁剪目标,复现了 TRPO“小步快走”的稳定性,却简单到几十行就能实现5。
PPO 因为这份“又稳又简单”,迅速成了强化学习的事实标准——从机器人控制到游戏智能体,到处都是它。也正因如此,当 OpenAI 在 2022 年做 RLHF、需要“用奖励模型给的分数去优化语言模型”时,他们顺手拿来的就是 PPO5。第十一章 RLHF 三步流程里的第三步——“用强化学习(PPO)优化语言模型,让它的回答尽量获得奖励模型的高分,同时加 KL 惩罚防止跑偏”——现在可以完全看懂了:那里的“策略”就是语言模型本身(在每个上下文下选下一个 token 的概率分布),“动作”是生成的 token,“奖励”来自奖励模型,“KL 惩罚防止跑偏”正是 PPO/TRPO 那条“别离旧策略太远”的信赖域思想的体现。一个 2017 年为打游戏而生的算法,五年后成了把 GPT-3 变成 ChatGPT 的关键工具。
七
策略梯度这一支还有两个值得一提的分支,它们和 PPO 并列,各自占住了不同的生态位。
A3C(Asynchronous Advantage Actor-Critic,异步优势 actor-critic),2016 年由 Mnih 等人提出6。它不用经验回放,而是开很多个并行的 worker,每个在自己的环境副本里跑,各自计算梯度、异步更新一个共享的全局网络。不同 worker 在不同游戏阶段、采集到的经验天然不相关——用并行性代替了经验回放来去相关。它的同步简化版 A2C 也被广泛使用。
SAC(Soft Actor-Critic,软 actor-critic),2018 年由 Haarnoja 等人提出7。它在最大化奖励之外,额外最大化策略的熵——也就是鼓励策略在能拿到好回报的前提下,尽量保持随机、多样。这个“最大熵”目标带来了更好的探索和鲁棒性,让 SAC 成为连续控制(尤其机器人)领域样本效率最高的算法之一。PPO 是 on-policy(只能用当前策略采的数据),SAC 是 off-policy(能复用历史经验,像 DQN 那样配经验回放),两者在不同场景各擅胜场。
到这里,强化学习的两大算法家族都铺好了:第十二、十三章的价值方法(TD/Q-learning/DQN 系),和这一章的策略方法(REINFORCE/PG 定理/actor-critic/PPO/SAC)。但这两家解决的,主要还是“在一个反应式环境里即时决策”的问题。有一类任务需要的更多——它需要向前搜索、推演对手的应对、在脑中模拟很多步之后再落子。把“学到的价值与策略”和“显式的前瞻搜索”结合起来,是下一章的主题,也是强化学习迄今最耀眼的成就:AlphaGo 一族。
配套的 manim 动画 assets/manim/ch14_policy_gradient.py(PolicyShaping 与 BaselineVariance 两个 Scene)把策略方法的内核演出来:前者把策略画成动作空间上的一个概率分布,按“回报 × 对数概率梯度”更新,拿到正回报的动作概率被推高、负回报的被压低——策略分布被直接塑形;后者展示减去一个 baseline(如状态价值 )如何把“都偏正、彼此难分”的绝对回报,换成“有正有负、围绕 0”的相对优势 ,期望梯度不变但方差大降——这正是 actor-critic 的核心。
本质
策略方法和价值方法的根本分歧,在于“学什么”:价值方法绕个弯,先学每个动作有多好、再从中挑最好的,因而天然只适合可以逐一比较的离散动作;策略方法则跳过这个中间量,直接把策略本身当作要优化的函数,对它的参数做梯度上升。策略梯度定理给出的,是一个看似不可能的东西——如何对一个“采样动作→获得回报”这种含随机性、不可微的过程求梯度;它的答案优雅得近乎朴素:朝着“提高那些带来高回报的动作的概率”的方向走。这把强化学习从“只能处理离散选择”解放到了连续控制的整个世界。而 actor-critic 与 baseline 解决的是它与生俱来的高方差顽疾:用一个学到的价值当参照系,让学习信号从“绝对回报”变成“比预期好还是差”。正是这一支里磨出的 PPO——一个在策略更新上加了信赖域约束、稳到可以无脑用的算法——后来被原样搬去对齐语言模型,成为两条主线交汇的桥。
参考文献
-
Williams, R. J. (1992). Simple Statistical Gradient-Following Algorithms for Connectionist Reinforcement Learning. Machine Learning, 8, 229–256. 首个策略梯度算法 REINFORCE;权重沿期望回报梯度调整 ,无需显式估计梯度,可与反向传播自然结合。PDF:https://link.springer.com/content/pdf/10.1007/BF00992696.pdf ;abs:https://link.springer.com/article/10.1007/BF00992696
-
Sutton, R. S., McAllester, D., Singh, S., & Mansour, Y. (2000). Policy Gradient Methods for Reinforcement Learning with Function Approximation. NIPS 1999/2000. 策略梯度定理 ;梯度不含状态分布对 的导数;可加 baseline 与函数逼近。PDF:https://web.eecs.umich.edu/~baveja/Papers/PolicyGradientNIPS99.pdf ;记录:https://www.cs.utexas.edu/~shivaram/readings/b2hd-SuttonMSM2000.html
-
Schulman, J., Levine, S., Abbeel, P., Jordan, M., & Moritz, P. (2015). Trust Region Policy Optimization. ICML 2015. 用 KL 散度信赖域约束限制每步策略更新幅度,保证单调改进;需二阶优化。arXiv:https://arxiv.org/abs/1502.05477
-
Schulman, J., Moritz, P., Levine, S., Jordan, M., & Abbeel, P. (2015). High-Dimensional Continuous Control Using Generalized Advantage Estimation. 用 加权多步 TD 误差 在偏差-方差间插值;成为策略梯度优势估计标配。arXiv:https://arxiv.org/abs/1506.02438
-
Schulman, J., Wolski, F., Dhariwal, P., Radford, A., & Klimov, O. (2017). Proximal Policy Optimization Algorithms. clip 目标 替代 TRPO 硬约束,一阶可优化、易实现,成事实标准;后被 RLHF(InstructGPT)用作第三步优化器。arXiv:https://arxiv.org/abs/1707.06347
-
Mnih, V., Badia, A. P., Mirza, M., Graves, A., Lillicrap, T., Harley, T., Silver, D., & Kavukcuoglu, K. (2016). Asynchronous Methods for Deep Reinforcement Learning. ICML 2016. A3C:多 worker 并行异步更新共享网络,用并行性代替经验回放去相关。arXiv:https://arxiv.org/abs/1602.01783
-
Haarnoja, T., Zhou, A., Abbeel, P., & Levine, S. (2018). Soft Actor-Critic: Off-Policy Maximum Entropy Deep Reinforcement Learning with a Stochastic Actor. ICML 2018. 最大熵目标(奖励 + 熵),off-policy actor-critic,连续控制样本效率 SOTA。arXiv:https://arxiv.org/abs/1801.01290