近端策略优化-PPO

这是近端策略优化-PPO 的 P yTorch 实现。

PPO 是一种用于强化学习的策略梯度方法。简单的策略梯度方法对每个样本(或一组样本)进行一次梯度更新。对单个样本执行多个梯度步骤会导致问题,因为策略偏差太大,从而产生了糟糕的策略。PPO 允许我们尝试使策略接近用于采样数据的策略,从而为每个样本执行多次梯度更新。如果更新的策略与用于采样数据的策略不接近,则通过剪切梯度流来实现此目的。

你可以在这里找到一个使用它的实验。该实验使用广义优势估计

Open In ColabView Run

29import torch
30
31from labml_helpers.module import Module
32from labml_nn.rl.ppo.gae import GAE

PPO 损失

以下是 PPO 更新规则的派生方式。

我们希望最大限度地提高保单奖励在哪里奖励在哪里,是保单,是从保单中抽样的轨迹,是介于两者之间的折扣系数

所以,

定义折扣未来状态分配,

那么,

重要性抽样来自

然后我们假设是相似的。我们通过这个假设引入的误差受和之间的 KL 差异的约束约束策略优化证明了这一点。我还没看过。

35class ClippedPPOLoss(Module):
137    def __init__(self):
138        super().__init__()
140    def forward(self, log_pi: torch.Tensor, sampled_log_pi: torch.Tensor,
141                advantage: torch.Tensor, clip: float) -> torch.Tensor:

比例这与奖励不同

144        ratio = torch.exp(log_pi - sampled_log_pi)

削减保单比率

该比率被裁剪为接近 1。我们取最小值,以便只有当比率不在和之间时,梯度才会拉。这保持了 KL 之间的差异限制。较大的偏差可能导致性能下降;在这种情况下,策略性能会下降且无法恢复,因为我们正在从不良策略中抽样。

使用归一化优势会给政策梯度估计器带来偏差,但它大大减少了方差。

173        clipped_ratio = ratio.clamp(min=1.0 - clip,
174                                    max=1.0 + clip)
175        policy_reward = torch.min(ratio * advantage,
176                                  clipped_ratio * advantage)
177
178        self.clip_fraction = (abs((ratio - 1.0)) > clip).to(torch.float).mean()
179
180        return -policy_reward.mean()

削减值函数损失

同样,我们也裁剪值函数的更新。

裁剪可确保值函数不会明显偏离

183class ClippedValueFunctionLoss(Module):
205    def forward(self, value: torch.Tensor, sampled_value: torch.Tensor, sampled_return: torch.Tensor, clip: float):
206        clipped_value = sampled_value + (value - sampled_value).clamp(min=-clip, max=clip)
207        vf_loss = torch.max((value - sampled_return) ** 2, (clipped_value - sampled_return) ** 2)
208        return 0.5 * vf_loss.mean()