4. 策略梯度方法入门
在强化学习的核心问题中,智能体需要通过与环境的交互来学习一个最优策略。值函数方法(如Q-learning)通过估计状态或状态-动作对的价值来间接推导策略,而策略梯度方法则直接对策略本身进行参数化,并通过梯度上升来优化策略参数。这种方法在处理高维或连续动作空间、以及需要随机策略的场景中展现出显著优势。本章将系统讲解策略参数化的基本形式、策略梯度目标函数的推导逻辑、经典的REINFORCE算法实现,以及如何通过引入基线(Baseline)来降低梯度估计的方差,从而提升训练的稳定性和收敛速度。
上图展示了策略梯度方法从策略参数化到目标函数、再到REINFORCE算法与基线减方差的完整链路。下面我们将逐一拆解每个环节的数学原理、实现细节与工程注意事项。
4.1 策略参数化:从表格到函数逼近
核心原理:在表格型方法中,策略以查找表形式存储,每个状态对应一个动作概率分布。但当状态空间或动作空间连续时,表格无法覆盖所有情况。策略参数化使用一个带参数 θ 的函数来近似策略,即 π_θ(a|s) = P(a|s; θ)。对于离散动作空间,常用 Softmax 函数将动作偏好值(logits)转换为概率分布;对于连续动作空间,则常用高斯分布,其中均值由神经网络输出,方差可以是固定值或可学习参数。
判断方法与操作流程:选择策略参数化形式时,需根据动作空间类型决定。离散动作使用 Softmax 策略,连续动作使用高斯策略。参数化网络通常包含两层或三层全连接网络,输出层激活函数根据分布类型选择(Softmax 或线性输出均值)。
# 离散动作策略网络示例(PyTorch风格)
import torch.nn as nn
class PolicyNet(nn.Module):
def __init__(self, state_dim, action_dim, hidden=64):
super().__init__()
self.fc1 = nn.Linear(state_dim, hidden)
self.fc2 = nn.Linear(hidden, action_dim)
def forward(self, s):
x = torch.relu(self.fc1(s))
logits = self.fc2(x)
return torch.softmax(logits, dim=-1)
4.2 策略梯度目标函数与策略梯度定理
核心原理:策略梯度方法的目标是最大化期望累积回报。定义目标函数 J(θ) = E_τ ~ π_θ [R(τ)],其中 τ 表示一条完整轨迹,R(τ) 为轨迹总回报。直接对 J(θ) 求梯度会遇到困难,因为期望中的概率分布依赖于参数 θ。策略梯度定理给出了一个巧妙的变换:
∇θ J(θ) = E_τ [ Σ_t ∇θ log π_θ(a_t|s_t) · R(τ) ]
这个公式将梯度转化为对对数概率梯度的加权求和,权重为轨迹总回报。该定理的推导基于对数导数技巧,是REINFORCE算法的数学基础。
判断方法与操作流程:在实际实现中,我们通过蒙特卡洛采样来近似期望。每轮采样多条轨迹,计算每条轨迹的回报,然后对每个时间步计算 ∇θ log π_θ(a_t|s_t) 并乘以回报,最后求平均作为梯度估计。
| 目标函数形式 | 适用场景 | 梯度表达式 |
|---|---|---|
| 轨迹总回报 | 回合制任务(如游戏、导航) | ∇θ log π_θ(a_t|s_t) · R(τ) |
| 折扣回报 | 持续任务(如机器人控制) | ∇θ log π_θ(a_t|s_t) · Σ γ^k r_{t+k} |
| 优势函数 | 结合值函数估计 | ∇θ log π_θ(a_t|s_t) · A(s_t, a_t) |
4.3 REINFORCE算法:蒙特卡洛策略梯度
核心原理:REINFORCE(Williams, 1992)是最基础的策略梯度算法。它使用完整轨迹的回报作为梯度权重,直接对策略参数进行梯度上升。算法流程如下:
- 初始化策略参数 θ
- 循环:使用当前策略 π_θ 采样一条完整轨迹 τ = (s_0, a_0, r_1, ..., s_{T-1}, a_{T-1}, r_T)
- 计算每个时间步的累积回报 G_t = Σ_{k=0}^{T-t} γ^k r_{t+k+1}
- 计算梯度:∇θ J(θ) ≈ Σ_t G_t · ∇θ log π_θ(a_t|s_t)
- 更新参数:θ ← θ + α · ∇θ J(θ)
案例拆解:CartPole 平衡控制
以 Gym 的 CartPole-v1 为例,状态为 4 维连续向量(位置、速度、角度、角速度),动作空间为 2 个离散动作(左/右)。我们使用一个两层策略网络,学习率 α=0.01,折扣因子 γ=0.99。初始时,策略随机,小车无法保持平衡,每回合平均回报约 20。经过 500 次迭代后,策略逐渐学会在杆子倾斜时向相反方向施加力,平均回报提升至 200(达到环境最大步数)。
关键实现细节:
- 回报归一化:将 G_t 减去均值并除以标准差,可以显著提升稳定性
- 使用 Adam 优化器替代 SGD,自适应调整学习率
- 每轮采样多条轨迹(如 10 条)取平均梯度,降低方差
4.4 基线减方差:让梯度更稳定
核心原理:观察 REINFORCE 的梯度公式,我们可以减去一个与动作无关的基线函数 b(s_t),得到:
∇θ J(θ) = E[ Σ_t (G_t - b(s_t)) · ∇θ log π_θ(a_t|s_t) ]
由于 Σ_a ∇θ π_θ(a|s) = 0,可以证明减去基线不会改变梯度的期望值,但能显著降低方差。最常用的基线是状态价值函数 V(s_t),它表示从状态 s_t 出发的期望回报。此时 (G_t - V(s_t)) 即为优势函数 A(s_t, a_t) 的蒙特卡洛估计,表示当前动作相对于平均水平的优势。
操作流程:引入基线后,需要额外维护一个价值网络 V_φ(s) 来估计状态价值。训练过程变为双网络结构:策略网络 π_θ 和价值网络 V_φ 交替更新。价值网络通过回归损失(如均方误差)学习预测回报:
# 价值网络更新
value_loss = MSE(V_φ(s_t), G_t)
φ ← φ - β · ∇φ value_loss
案例拆解:带基线的 REINFORCE 在 CartPole 上的对比
我们设计对比实验:同一环境下,分别运行原始 REINFORCE 和带基线版本。两者使用相同的策略网络结构和超参数(学习率 0.01,批大小 10)。结果显示:
| 指标 | 原始 REINFORCE | 带基线 REINFORCE |
|---|---|---|
| 达到 200 分所需迭代次数 | 约 800 次 | 约 350 次 |
| 训练曲线波动幅度 | ±60 | ±20 |
| 最终收敛稳定性 | 偶尔回退 | 稳定保持 |
分析原因:基线 V(s_t) 捕捉了状态本身的难度差异。例如,当杆子接近垂直时,V(s) 较高,此时即使 G_t 较大,减去基线后优势值也不会过大;反之,当杆子即将倾倒时,V(s) 较低,G_t 较小,减去基线后优势值变为负值,促使策略调整。这种机制让梯度信号更集中于“相对好”或“相对差”的动作,而非回报。
4.5 常见误区与工程调优建议
误区一:忽略回报归一化。即使有基线,不同批次间的回报尺度仍可能变化。建议对优势值进行标准化处理(减均值除标准差),这相当于自适应调整学习率。
误区二:策略网络与价值网络共享特征层时更新不同步。若共享底层,需注意两个任务的梯度尺度差异。策略梯度通常较小,价值损失较大,可能导致策略更新被淹没。解决方案是使用两个独立网络,或对价值损失乘以较小的权重系数。
误区三:学习率设置不当。策略梯度方法对学习率敏感。学习率过大会导致策略突变,过小则收敛缓慢。建议使用 Adam 优化器,初始学习率设置在 1e-3 到 3e-4 之间,并根据训练曲线动态调整。
误区四:忽视探索与利用的平衡。策略梯度方法天然具备随机探索能力,但若策略快速收敛到确定性行为,探索会不足。可引入熵正则化项,在目标函数中加入 β · H(π_θ(·|s)),鼓励策略保持随机性。
总结复盘:策略梯度方法的核心在于直接优化策略参数,其优势在于处理连续动作空间和随机策略。REINFORCE 作为基础算法,虽然简单但方差大;引入基线是降低方差的关键改进。在实际工程中,建议按以下步骤推进:先实现基础 REINFORCE 验证环境交互正确性,再加入基线观察方差变化,最后根据任务特性调整网络结构和超参数。策略梯度方法为后续的 Actor-Critic 算法(如 A2C、PPO)奠定了理论基础,理解本章内容将帮助你更顺畅地掌握更高级的算法。