3.3 Policy Gradient、Actor-Critic 与安全评估:优化回报也会优化奖励漏洞
Q 表越来越大,机器人还需要输出连续转向角。你改为直接学习动作分布,却发现同一策略有时快速到达、有时跌入陷阱,梯度方向剧烈波动。更麻烦的是,它学会在终点附近反复触发奖励,而不是结束任务。
Policy optimization 可以处理随机和连续动作,却不会自动理解意图。估计方差、动作约束和奖励漏洞都要进入算法设计。
本课目标
- 推导 REINFORCE 的 log-derivative 更新;
- 用 baseline/advantage 降低方差;
- 理解 actor-critic 的 bootstrap 权衡;
- 设计独立评估、离线检查与安全约束。
1. 直接优化参数化策略
令策略为 $\pi_\theta(a\mid s)$,目标:
$$ J(\theta)=E_{\tau\sim\pi_\theta}[G_0]. $$
Policy gradient 的基本形式:
$$ \nabla_\theta J(\theta)=E[ G_t\nabla_\theta\log\pi_\theta(A_t\mid S_t)]. $$
REINFORCE 采完整 trajectory,用 sampled return 作为权重。对正回报动作增加 log probability,对负回报降低。
2. 修正旧稿中的梯度方向
Softmax 线性策略对所选动作的 log-probability 梯度是:
$$ \nabla_W\log\pi(a\mid s) =s,(onehot(a)-\pi(\cdot\mid s))^T. $$
import numpy as np
class LinearReinforce:
def __init__(self, feature_dim, n_actions, gamma, lr, seed=0):
self.w = np.zeros((feature_dim, n_actions))
self.gamma = gamma
self.lr = lr
self.rng = np.random.default_rng(seed)
def probabilities(self, features):
logits = features @ self.w
logits -= logits.max()
exp = np.exp(logits)
return exp / exp.sum()
def act(self, features):
p = self.probabilities(features)
return int(self.rng.choice(len(p), p=p))
def update(self, trajectory):
returns = np.empty(len(trajectory))
running = 0.0
for t in reversed(range(len(trajectory))):
_, _, reward = trajectory[t]
running = reward + self.gamma * running
returns[t] = running
baseline = returns.mean()
for (features, action, _), g in zip(trajectory, returns):
p = self.probabilities(features)
grad_logits = -p
grad_logits[action] += 1.0
self.w += self.lr * (g - baseline) * np.outer(
features, grad_logits
)旧代码使用 probs - onehot 却做 gradient ascent,正回报反而降低所选动作概率;还引用未定义的 self.gamma。教学代码必须能说明符号和维度。
这里用同轨迹均值 baseline 仅作示意,实际 baseline 设计要避免不当依赖动作并考虑 bias/variance。
3. Baseline 不改变期望梯度的条件
从 return 减去只依赖状态、不依赖所选动作的 baseline:
$$ (G_t-b(S_t))\nabla\log\pi(A_t\mid S_t), $$
在标准条件下不改变期望梯度,却可降低方差。若 $b\approx V^\pi$,差值可视作 advantage 估计。
Return normalization、reward scaling 会改变优化数值;是否保持目标需具体分析,不能和合法 baseline 混为一谈。
4. Actor-Critic
- actor:策略 $\pi_\theta$;
- critic:估计 $V_w$ 或 $Q_w$;
- TD error:
$$ \delta_t=R_{t+1}+\gamma V_w(S_{t+1})-V_w(S_t). $$
用 $\delta_t$ 近似 advantage 更新 actor,能在线学习且方差更低,但 critic 的 bootstrap bias 会进入策略更新。
n-step/GAE 在 bias 与 variance 间调节。选择参数要通过多 seed 和独立评估,不是“lambda 越大越准确”。
5. 连续动作需要概率分布与边界
常见策略输出 Gaussian 的均值和标准差,再采样动作。需要注意:
- 标准差保持正值并限制数值范围;
- 动作有界时 tanh squashing 会改变 log-probability,需要 Jacobian correction;
- 探索噪声必须符合设备安全范围;
- 不同维度相关性可能不能用独立 Gaussian 表达;
- 部署用均值动作与训练采样策略不是同一分布。
“Policy Gradient 天然处理连续动作”只表示易于参数化,不表示约束和训练稳定性自动解决。
6. Trust region 与 clipped objective
大策略更新会使新旧轨迹分布差异太大,导致估计失真。TRPO/PPO 等方法限制策略变化。Clipping 是稳定手段,不保证每次性能单调提升,也不能弥补错误 advantage 或数据实现。
监控 approximate KL、clip fraction、entropy、value loss、explained variance 和梯度范数,并用真实回报确认。
7. Offline RL 的分布外动作
只用历史日志训练时,策略不能安全尝试新动作。若 learned Q 对数据中少见动作过估计,策略会利用外推错误。
需要:
- 明确 behavior policy 与 action propensity(若可得);
- 覆盖/重叠诊断;
- 保守价值或策略约束;
- off-policy evaluation 的假设和区间;
- 模拟器/小流量上线与安全门;
- 不把普通监督学习验证分数当策略价值。
缺乏关键动作覆盖时,数据无法回答新策略后果,算法不能创造反事实证据。
8. 安全与约束决策
真实机器人不能靠跌落一千次学习。可使用:
- simulator 与 domain randomization;
- action shield/规则约束;
- constrained MDP 与 cost budget;
- safe set 和 fallback controller;
- 分阶段扩大状态/动作范围;
- 人工审批高风险动作;
- kill switch 和事件回放。
把事故设置为巨大负奖励不一定足够:探索时仍可能发生,函数近似也可能低估小概率灾难。
9. 评估协议
固定策略快照,不在评估 episode 探索/学习
多个训练 seed 与独立环境 seed
平均、分位数、失败率和最坏场景
训练分布内、分布外和扰动场景
奖励组成与真实任务指标分别报告
约束违反、干预和 fallback 次数
与规则、随机和现有策略基线比较
上线前定义停止与回滚条件在线 A/B 仍是干预,需考虑单位、溢出、依从和安全暴露。
常见误区
- Policy Gradient 不需要 value function:纯 REINFORCE 可不用,但 actor-critic 依赖 critic。
- baseline 会改变优化目标:合法 action-independent baseline 主要降方差。
- 奖励上升就任务变好:智能体可能利用 proxy 漏洞。
- 离线日志足够大就能评估任意策略:缺乏动作覆盖时不可识别。
练习
- 手推 softmax log-policy gradient,找出旧代码符号错误。
- 比较无 baseline、常数 baseline 与 learned value baseline 的方差。
- 为有界连续动作实现 squashed distribution 的 log-probability 校正。
- 为机器人设计 cost constraint、shield、fallback 和上线门禁。
小结
Policy gradient 把动作概率变成可优化对象,actor-critic 用价值估计降低方差。越直接地优化长期回报,越需要审查 reward、覆盖和安全边界,因为算法会认真利用你留下的每个漏洞。
下一章进入监督学习基础:数据不再由在线策略持续产生,但切分、标签和评估同样决定模型学到什么。