这是近端策略优化-PPO 的 P yTorch 实现。
PPO 是一种用于强化学习的策略梯度方法。简单的策略梯度方法对每个样本(或一组样本)进行一次梯度更新。对单个样本执行多个梯度步骤会导致问题,因为策略偏差太大,从而产生了糟糕的策略。PPO 允许我们尝试使策略接近用于采样数据的策略,从而为每个样本执行多次梯度更新。如果更新的策略与用于采样数据的策略不接近,则通过剪切梯度流来实现此目的。
29import torch
30
31from labml_helpers.module import Module
32from labml_nn.rl.ppo.gae import GAE以下是 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()