REINFORCE 算法直觉

REINFORCE 算法

标准 REINFORCE 方法属于最基础的基于策略的强化学习算法,也叫 Monte Carlo Policy Gradient。基于策略的强化学习算法,核心是直接学习“应该怎么选动作”,直接学习一个策略:\(π(a∣s)\) (在状态 \(s\) 下,选择动作 \(a\) 的概率是多少)。
训练目标是让高回报动作的概率变大,让低回报动作的概率变小。


REINFORCE 算法类型

Monte Carlo

Reinforce 方法需要等智能体按照当前策略跑完一整局 episode 再开始优化。

on-policy 在线策略

标准的 Reinforce 方法需要在每一局优化后直接用当前策略采样下一局数据,训练过程中直接优化策略函数,属于在线策略。

Policy-based 基于策略

基于策略的(policy-based) 强化学习算法通过输出每个动作被选择的概率,根据目标函数调整概率分布以实现优化策略的目的。标准的 Reinforce算法用每一步的回报 \(G_t\) 去调整当时动作的概率。属于“直接优化策略”。


算法直觉

Policy-based 方法输出动作概率:\([0,1]\) 之间,和为1。

# 前向传播,得到 logits(原始输出)
logits = policy_net(dummy_state)

# 用 softmax 转成概率分布
probs = F.softmax(logits, dim=-1)

# 按概率采样一个动作
action = torch.multinomial(probs, num_samples=1).item()

采样

用当前策略网络玩一局。

记录每一步\(logπ_θ(a_t∣s_t)\)

Policy_nerwork 输入状态 \(s_t\) ,输出动作概率 \(π_θ(a∣s_t)\),然后按概率采样动作 \(a_t\),记录 \(logπ_θ(a_t∣s_t)\)

# 前向传播,得到动作概率
logits = policy_net(state_tensor)       # shape: [1, 2]
probs = F.softmax(logits, dim=-1)

# 按概率采样动作torch.multinomial: 按给定概率采样
action = torch.multinomial(probs, num_samples=1).item()

# 记录log
log_prob = torch.log(probs[0, action])

记录环境返回奖励 \(r_t\)

根据所选动作与环境交互记录当下奖励。

next_state, reward, terminated, truncated, _ = env.step(action)

储存

    # ---- 记录数据(关键!先不更新网络)----
    log_probs.append(log_prob)      # 记录这个动作的 log 概率
    rewards.append(reward)          # 记录这一步的奖励

用完一条轨迹就会丢弃

优化

一局结束后,计算每一步的累计回报

等一个episode跑完,把整条轨迹存下来,然后从后往前计算每一步的回报:

\[G_t = r_t + \gamma r_{t+1} + \gamma^2 r_{t+2} + \cdots \]

returns = []
G = 0

# 从后往前算(倒推)
for r in reversed(rewards):
    G = r + gamma * G
    returns.insert(0, G)
  
# 归一化:减去均值,除以标准差,减小方差,让训练更稳定
returns = (returns - returns.mean()) / (returns.std() + 1e-9)

构造loss:

\[L(\theta) = - \sum_{t=0}^{T} \log \pi_\theta(a_t \mid s_t) G_t \]

因为 loss 前面有负号,所以“最小化 loss”实际等价于“最大化回报加权后的动作概率”

更新逻辑可以理解为:

  1. 如果某个动作之后带来了高 return (\(G_t\) 大):增加这个动作在该状态下被选中的概率
  2. 如果某个动作之后带来了低 return (\(G_t\) 小):降低这个动作在该状态下被选中的概率
    loss = -(log_probs_tensor * returns).sum()
    
        # ---- 反向传播三步 ----
    optimizer.zero_grad()   # 清空上一步的梯度
    loss.backward()         # 反向传播,计算梯度
    optimizer.step()        # 用梯度更新网络参数

REINFORCE可以加baseline。加了baseline后 优化目标变为

\[L(\theta) = - \sum_{t=0}^{T} \log \pi_\theta(a_t \mid s_t) (G_t - b(s_t)) \]

REINFORCE 的主要问题

训练方差很大,因为它依赖完整 episode 的 return;一局结果好坏可能受很多随机因素影响,所以更新不稳定、样本效率较低。后来 Actor-Critic 就是在 REINFORCE 的基础上加入 Critic,用价值函数提供更稳定的更新信号。

  1. 方差大(Variance)用整局回报来评价每个动作,噪声很大- 同一局里,早期动作和晚期动作共享同一个总回报 - 导致梯度估计不稳定,训练波动大
  2. 信用分配问题(Credit Assignment)一局赢了500分,但可能只有最后几步是关键 - REINFORCE 给所有步骤同样的回报,不够精细
posted @ 2026-06-10 21:31  离心律  阅读(2)  评论(0)    收藏  举报