1. TRPO算法概述
信任区域策略优化(Trust Region Policy Optimization, TRPO)是2015年提出的一种基于策略梯度的强化学习算法。它通过引入信任区域的概念,解决了传统策略梯度方法在深度神经网络训练中容易出现的策略更新不稳定问题。TRPO的核心思想是在每次策略更新时,限制新旧策略之间的KL散度不超过某个阈值,从而确保策略性能的单调提升。
在实际应用中,我发现TRPO特别适合那些需要稳定训练的场景,比如机器人控制和连续动作空间的任务。相比普通的策略梯度方法,TRPO的训练曲线更加平滑,不容易出现性能突然崩溃的情况。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. TRPO的数学推导
2.1 策略优化目标
在策略梯度方法中,我们希望最大化期望回报η(π)。对于新策略π'和旧策略π,可以推导出它们的目标函数关系:
η(π') = η(π) + E_{s∼ρπ',a∼π'}[Aπ(s,a)]
其中Aπ(s,a)是优势函数。通过重要性采样,可以将其转化为仅使用旧策略π采样的数据:
η(π') ≈ η(π) + E_{s∼ρπ,a∼π}[ (π'(a|s)/π(a|s)) * Aπ(s,a) ]
2.2 信任区域约束
直接优化上述目标可能导致策略更新过大,因此TRPO引入了KL散度约束:
max_θ E_{s∼ρπ,a∼π}[ (π_θ(a|s)/π(a|s)) * Aπ(s,a) ]
s.t. E_{s∼ρπ}[KL(π(·|s)||π_θ(·|s))] ≤ δ
这个约束确保新策略不会偏离旧策略太远,从而保持训练的稳定性。
2.3 共轭梯度法求解
由于直接求解带约束的优化问题计算量很大,TRPO使用共轭梯度法近似求解。具体步骤包括:
- 计算目标函数的梯度g
- 计算Fisher信息矩阵-向量积Hv
- 用共轭梯度法求解H^{-1}g
- 计算最优更新步长
在实际实现中,我发现共轭梯度法的迭代次数不需要太多,通常10次左右就能得到不错的近似解。这大大降低了计算开销。
3. TRPO算法实现细节
3.1 网络结构设计
TRPO通常使用两个网络:策略网络和价值网络。策略网络输出动作分布,价值网络评估状态价值。
python复制class PolicyNet(torch.nn.Module):
def __init__(self, state_dim, hidden_dim, action_dim):
super(PolicyNet, self).__init__()
self.fc1 = torch.nn.Linear(state_dim, hidden_dim)
self.fc2 = torch.nn.Linear(hidden_dim, action_dim)
def forward(self, x):
x = F.relu(self.fc1(x))
return F.softmax(self.fc2(x), dim=1)
class ValueNet(torch.nn.Module):
def __init__(self, state_dim, hidden_dim):
super(ValueNet, self).__init__()
self.fc1 = torch.nn.Linear(state_dim, hidden_dim)
self.fc2 = torch.nn.Linear(hidden_dim, 1)
def forward(self, x):
x = F.relu(self.fc1(x))
return self.fc2(x)
3.2 关键实现步骤
- 采样阶段:使用当前策略与环境交互收集数据
- 优势估计:使用GAE(Generalized Advantage Estimation)计算优势函数
- 策略更新:通过共轭梯度法计算策略更新方向
- 线性搜索:找到满足KL约束的最大步长
python复制def conjugate_gradient(self, grad, states, old_action_dists):
x = torch.zeros_like(grad)
r = grad.clone()
p = grad.clone()
rdotr = torch.dot(r, r)
for i in range(10): # 共轭梯度主循环
Hp = self.hessian_matrix_vector_product(states, old_action_dists, p)
alpha = rdotr / torch.dot(p, Hp)
x += alpha * p
r -= alpha * Hp
new_rdotr = torch.dot(r, r)
if new_rdotr < 1e-10:
break
beta = new_rdotr / rdotr
p = r + beta * p
rdotr = new_rdotr
return x
4. TRPO在连续动作空间的应用
对于连续动作空间的任务,需要对策略网络进行修改,使其输出高斯分布的均值和标准差:
python复制class PolicyNetContinuous(torch.nn.Module):
def __init__(self, state_dim, hidden_dim, action_dim):
super(PolicyNetContinuous, self).__init__()
self.fc1 = torch.nn.Linear(state_dim, hidden_dim)
self.fc_mu = torch.nn.Linear(hidden_dim, action_dim)
self.fc_std = torch.nn.Linear(hidden_dim, action_dim)
def forward(self, x):
x = F.relu(self.fc1(x))
mu = 2.0 * torch.tanh(self.fc_mu(x))
std = F.softplus(self.fc_std(x))
return mu, std # 高斯分布的均值和标准差
5. 实际应用中的调参经验
5.1 关键超参数设置
- KL约束阈值(kl_constraint):通常设置在0.001到0.01之间。值太小会导致收敛慢,太大则可能失去约束效果。
- 折扣因子(gamma):离散任务建议0.95-0.99,连续任务可以稍低如0.9。
- GAE参数(lmbda):一般取0.9-0.95,平衡偏差和方差。
5.2 训练技巧
- 批量大小:TRPO需要较大的批量(至少几千个时间步)才能获得稳定的优势估计。
- 学习率:只需要设置价值网络的学习率,策略网络通过TRPO自动更新。
- 归一化奖励:对连续任务,奖励归一化可以显著提高训练稳定性。
在倒立摆任务中,我发现将奖励除以8能使训练更加稳定。这是因为该环境的奖励范围较大,直接使用原始奖励会导致梯度幅度变化剧烈。
6. 常见问题与解决方案
6.1 训练不稳定
问题现象:回报曲线波动大,偶尔出现性能骤降。
解决方案:
- 减小KL约束阈值
- 增加批量大小
- 检查优势估计的计算是否正确
6.2 收敛速度慢
问题现象:训练多轮后性能提升不明显。
解决方案:
- 适当增大KL约束阈值
- 调整GAE参数λ
- 检查网络结构是否足够表达
6.3 数值不稳定
问题现象:出现NaN或inf值。
解决方案:
- 在计算KL散度和概率比时添加小常数(如1e-8)
- 对策略网络的输出进行裁剪
- 使用double精度浮点数
7. TRPO与其他算法的比较
- vs 普通策略梯度:TRPO通过信任区域约束保证了单调提升,训练更稳定。
- vs PPO:PPO是TRPO的改进,使用裁剪替代KL约束,实现更简单但理论保证较弱。
- vs DDPG:TRPO是on-policy算法,更适合模拟环境;DDPG是off-policy,更适合真实机器人学习。
在实际项目中,我通常会先尝试PPO,如果发现训练不稳定再切换到TRPO。对于需要严格保证训练稳定性的关键应用,TRPO仍然是更好的选择。
