REINFORCE
用完整轨迹回报作为策略梯度权重的 Monte Carlo 算法。
学习目标
- 用完整 episode 回报构造最直接的 Monte Carlo 策略梯度。
- 独立复核“优势符号决定同一动作的更新方向”的输入、计算和解释。
- REINFORCE 使用采样回报,actor-critic 常用 bootstrap 优势。
为什么重要
用完整 episode 回报构造最直接的 Monte Carlo 策略梯度。
学习前需要掌握
背景与问题
最简单的策略优化可以先跑完一局,计算每个动作之后实际得到的回报,再增加高回报动作的对数概率。这样无需学习后继价值网络,但整局随机结果会给早期动作带来很大的梯度波动。
概念定义
REINFORCE 是基于采样回报的 score-function 策略梯度方法。每个时间步可使用从该步起的 return-to-go,配合只依赖状态的基线降低方差。它使用完整回报作为学习信号,标准 episodic 形式不在回报目标中 bootstrap。
直观理解
一局结束后复盘,而不是每走一步就用评论家的猜测补足未来。复盘能利用真实结果,但一次幸运胜利仍可能让无关动作得到过多奖励。
核心原理
return-to-go 排除动作之前已经发生的奖励,因为当前动作不能改变过去。在折扣目标下,外部时间权重与回报定义要保持一致;不同实现的采样约定应说明,不能只抄一个损失就宣称严格相同。
优化器通常最小化负的 log_prob×advantage;漏掉负号会反向惩罚好动作。基线只改变梯度信号的中心,不应在同一个 actor 项中变成可任意追逐的目标。
下方例子用固定种子采一个离散动作,显示优势加熵项的梯度。它只证明概率分布和梯度路径可计算,不包含真实环境采样、完整 episode 累积或多轮训练表现。
数学表达
REINFORCE 更新
轨迹回报加权对数概率梯度。
变量含义
G_t从时刻 t 开始的折扣累计回报。R_{t+1}执行动作后收到的下一步奖励。γ折扣因子,通常位于 [0,1)。
计算步骤
- 1优势为 2−1.2=0.8。
- 2策略上升增量为 0.1×0.8×0.4=0.032。
- 3若基线为 2.5,优势变成 −0.5,同一 score 方向的增量为 −0.02。
代码对应位置
示例 1REINFORCE:轨迹回报乘对数概率:展示概率策略、轨迹回报、baseline 与熵奖励如何进入损失。
变量解释
| 变量 | 含义 |
|---|---|
G_t | 从时刻 t 开始的折扣累计回报。 |
R_{t+1} | 执行动作后收到的下一步奖励。 |
γ | 折扣因子,通常位于 [0,1)。 |
完整数值示例
优势符号决定同一动作的更新方向
已知条件
- 一次完整轨迹回报为 2,状态基线为 1.2。
- 该动作概率的 score 梯度为 0.4,学习率 0.1。
计算步骤
- 优势为 2−1.2=0.8。
- 策略上升增量为 0.1×0.8×0.4=0.032。
- 若基线为 2.5,优势变成 −0.5,同一 score 方向的增量为 −0.02。
计算结果
相同正回报在不同基线下可高于或低于预期,梯度方向由优势符号决定。
处理前后对比
- REINFORCE 使用采样回报,actor-critic 常用 bootstrap 优势。
- 下方可运行例还加入小熵奖励,它是探索正则,不是额外环境回报。
计算与实现步骤
- 采样 episode
- 计算每步 G
- 减 baseline
- 计算 policy loss
- 更新
代码实现
示例 1
REINFORCE:轨迹回报乘对数概率
example_01.py用途:展示概率策略、轨迹回报、baseline 与熵奖励如何进入损失。
import torch
from torch.distributions import Categorical
torch.manual_seed(7)
logits = torch.tensor([0.2, -0.1], requires_grad=True)
policy = Categorical(logits=logits)
action = policy.sample()
log_prob = policy.log_prob(action)
entropy = policy.entropy()
trajectory_return = torch.tensor(2.0)
baseline = torch.tensor(1.2)
advantage = trajectory_return - baseline
loss = -(log_prob * advantage + 0.01 * entropy)
loss.backward()
print('action:', action.item())
print('probabilities:', policy.probs.detach())
print('gradient:', logits.grad)代码解析
解析始终位于完整代码下方,并按实际代码段逐项对应。
输入数据与任务
展示概率策略、轨迹回报、baseline 与熵奖励如何进入损失。
loss- 当前预测与目标之间的损失值。
gradient- 损失对参数的局部变化率。
Step 1 · 1–2 行
导入当前步骤需要的数值计算、预处理、模型或评价工具。依赖集中写在代码开头,便于复现。
import torch
from torch.distributions import CategoricalStep 2 · 4–17 行
计算损失对参数的梯度,对应数学表达中的 ∇J;梯度只给出局部变化方向。
torch.manual_seed(7)
logits = torch.tensor([0.2, -0.1], requires_grad=True)
policy = Categorical(logits=logits)
action = policy.sample()
log_prob = policy.log_prob(action)
entropy = policy.entropy()
trajectory_return = torch.tensor(2.0)
baseline = torch.tensor(1.2)
advantage = trajectory_return - baseline
loss = -(log_prob * advantage + 0.01 * entropy)
loss.backward()
print('action:', action.item())
print('probabilities:', policy.probs.detach())
print('gradient:', logits.grad)代码与数学原理
参数更新由当前梯度与学习率共同决定。
平方误差代码对应均方损失。
预期输出或运行结果
action: 0 probabilities: tensor([0.5744, 0.4256]) gradient: tensor([-0.3397, 0.3397])
常见错误 · 3 条
- 对最小化优化器使用正 log_prob×return,方向写反。
- 把整局总奖励用于所有时刻却不说明高方差问题。
- 将学习基线说成使 REINFORCE 变成了 bootstrap 回报。
实际应用
- 序贯决策
- 控制与资源分配
常见错误
- 对最小化优化器使用正 log_prob×return,方向写反。
- 把整局总奖励用于所有时刻却不说明高方差问题。
- 将学习基线说成使 REINFORCE 变成了 bootstrap 回报。
扩展内容说明
本页数值均为解释机制的构造案例,不能解读为真实训练或基准性能。定义和适用条件参见 Sutton 与 Barto《Reinforcement Learning: An Introduction》(第 13 章)。
算法属性与数据边界
失败模式、风险与性能
失败模式
- 对最小化优化器使用正 log_prob×return,方向写反。
- 把整局总奖励用于所有时刻却不说明高方差问题。
- 将学习基线说成使 REINFORCE 变成了 bootstrap 回报。
风险
- 奖励函数与真实目标不一致会诱发奖励黑客。
- 部署策略的行动权限必须由环境和应用层约束。
性能考虑
- 样本效率、墙钟时间和显存占用需要分别报告。
- 应使用多个随机种子、置信区间和固定评测策略。
常见问题
加入状态价值基线后仍算 REINFORCE 吗?
可以。若 actor 的目标仍使用完整 Monte Carlo 回报减去状态基线,它仍属于基于回报的策略梯度;是否 bootstrap 要看目标具体构造。
网页是否会训练模型?
不会。所有图表使用固定种子或解析公式在浏览器本地计算,不执行页面中的示例代码。
推荐学习资料
参考库不会生成虚假资源或无效外部链接。