
1. 策略梯度方法进阶解析在强化学习领域策略梯度方法Policy Gradient Methods因其直接优化策略参数的特性而备受关注。作为L9系列的第二部分本文将深入探讨REINFORCE算法的核心机制及其实现细节。与基于价值函数的方法不同策略梯度直接对策略进行参数化通过梯度上升来最大化期望回报。关键提示策略梯度方法的优势在于能自然处理连续动作空间且策略参数化形式灵活但高方差问题始终是需要解决的核心挑战。1.1 REINFORCE算法原理REINFORCE作为最基础的策略梯度算法其梯度估计公式为∇J(θ) E[∇logπ(a|s) * G_t]其中G_t表示从时刻t开始的累积回报。这个看似简单的公式背后蕴含着几个关键设计点无偏性保证梯度估计不依赖值函数近似仅通过策略本身和蒙特卡洛回报计算即时回报敏感G_t包含整个episode的回报信息使梯度更新考虑长期影响对数技巧通过对数导数转换将期望回报最大化问题转化为可优化的目标我在实际实现中发现虽然理论推导清晰但直接应用原始REINFORCE会导致两个典型问题更新方差过大导致训练不稳定样本效率低下需完整episode后才能更新1.2 方差缩减技术针对高方差问题实践中常用以下改进方案1.2.1 基线减法Baseline# 减去状态相关的基线值如状态值函数 advantage G_t - V(s)通过引入不改变梯度期望的基线项可显著降低方差。常见选择移动平均回报简单但有效神经网络拟合的状态值函数需额外网络1.2.2 折扣因子在计算G_t时引入γ∈[0,1)折扣因子G_t Σ γ^(k-t) * r_k # 从kt到episode结束这降低了远期回报的权重在方差与偏差间取得平衡。1.2.3 回报标准化在batch内对回报进行标准化处理advantages (advantages - advantages.mean()) / (advantages.std() 1e-8)这个小技巧能稳定不同episode间的尺度差异。2. 工程实现关键点2.1 策略网络设计典型的策略网络架构需要考虑class PolicyNetwork(nn.Module): def __init__(self, obs_dim, act_dim): super().__init__() self.fc1 nn.Linear(obs_dim, 64) self.fc2 nn.Linear(64, 64) self.fc_mean nn.Linear(64, act_dim) self.fc_std nn.Linear(64, act_dim) # 或设为可训练参数 def forward(self, x): x F.relu(self.fc1(x)) x F.relu(self.fc2(x)) mean self.fc_mean(x) std F.softplus(self.fc_std(x)) # 保证标准差为正 return torch.distributions.Normal(mean, std)注意事项连续动作空间通常假设动作维度独立且服从高斯分布离散动作空间则用softmax输出概率分布标准差参数初始化要谨慎建议初始小值2.2 训练流程优化完整训练循环应包含以下关键步骤数据收集阶段trajectories [] for _ in range(batch_size): state env.reset() done False episode [] while not done: dist policy_net(state) action dist.sample() next_state, reward, done, _ env.step(action) episode.append((state, action, reward)) state next_state # 计算每个步骤的累积回报 returns compute_returns(episode) trajectories.extend(zip(*episode, returns))梯度更新阶段states, actions, _, returns map(torch.stack, zip(*trajectories)) dist policy_net(states) log_probs dist.log_prob(actions) loss -(log_probs * returns).mean() # 负号因为梯度上升 optimizer.zero_grad() loss.backward() optimizer.step()经验之谈在实现中发现使用GPU并行收集多个episode能显著提升数据效率。同时给环境添加合理的随机种子对重现实验结果至关重要。3. 典型问题与调试技巧3.1 训练不稳定问题现象回报曲线剧烈波动策略突然崩溃解决方案添加梯度裁剪torch.nn.utils.clip_grad_norm_减小学习率通常从3e-4开始尝试增大batch size平衡方差与计算成本使用更先进的优化器如Adam3.2 探索不足问题现象策略快速收敛到次优解改进措施# 在动作采样时添加显式探索 action dist.sample() if random.random() epsilon: action env.action_space.sample() # 随机探索或通过调整策略熵loss -(log_probs * returns).mean() - 0.01*dist.entropy().mean()3.3 超参数敏感问题通过网格搜索得到的经验值范围参数推荐范围影响学习率1e-4 ~ 3e-4过大导致震荡折扣因子γ0.9 ~ 0.99接近1考虑更远期回报batch大小8 ~ 256越大方差越小隐层尺寸32 ~ 256复杂任务需要更大容量4. 进阶改进方向4.1 自然策略梯度通过引入Fisher信息矩阵的逆来规范化更新步长# 近似计算自然梯度 F compute_fisher_matrix(policy, trajectories) nat_grad torch.linalg.solve(F, vanilla_grad)这种二阶方法能产生更稳定的更新但计算成本较高。4.2 信任域方法TRPO和PPO等算法通过限制策略更新的幅度来保证稳定性。以PPO为例ratio new_log_probs / old_log_probs surr1 ratio * advantages surr2 torch.clamp(ratio, 1-ε, 1ε) * advantages loss -torch.min(surr1, surr2).mean()其中ε通常取0.1~0.3这种截断机制能防止过大的策略更新。在实际应用中我发现对于连续控制任务PPO通常比原始REINFORCE表现更稳定。但对于离散动作空间或稀疏奖励问题经过精心调参的REINFORCE有时反而能取得更好效果。