这是 P yTorch 实现的近端策略优化-PPO。
PPO 是一种用于强化学习的策略梯度方法。简单的策略梯度方法对每个样本(或一组样本)进行一次梯度更新。对单个样本执行多个梯度步骤会导致问题,因为策略偏差太大,从而产生错误的策略。PPO 允许我们在每个样本中进行多次梯度更新,方法是尽量使策略与用于采样数据的策略保持一致。如果更新后的策略与用于采样数据的策略不接近,则通过削减梯度流来实现此目的。
28import torch
29
30from labml_helpers.module import Module
31from labml_nn.rl.ppo.gae import GAE
以下是 PPO 更新规则的派生方式。
我们希望最大限度地提高保单奖励在哪里,奖励在哪里,是保单,是从保单中抽样的轨迹,是介于两者之间的折扣系数。
所以,
定义折扣未来状态分配,
那么,
重要性抽样来自
然后我们假设和是相似的。我们通过这个假设引入的误差受和之间的 KL 差异的约束。约束策略优化证明了这一点。我还没看过。
34class ClippedPPOLoss(Module):
136 def __init__(self):
137 super().__init__()
139 def forward(self, log_pi: torch.Tensor, sampled_log_pi: torch.Tensor,
140 advantage: torch.Tensor, clip: float) -> torch.Tensor:
比例;这与奖励不同。
143 ratio = torch.exp(log_pi - sampled_log_pi)
该比率被裁剪为接近 1。我们取最小值,以便只有当比率不在和之间时,梯度才会拉向。这保持了 KL 之间的差异和限制。较大的偏差可能导致性能下降;在这种情况下,策略性能会下降且无法恢复,因为我们正在从不良策略中抽样。
使用归一化优势会给政策梯度估计器带来偏差,但它大大减少了方差。
172 clipped_ratio = ratio.clamp(min=1.0 - clip,
173 max=1.0 + clip)
174 policy_reward = torch.min(ratio * advantage,
175 clipped_ratio * advantage)
176
177 self.clip_fraction = (abs((ratio - 1.0)) > clip).to(torch.float).mean()
178
179 return -policy_reward.mean()
182class ClippedValueFunctionLoss(Module):
204 def forward(self, value: torch.Tensor, sampled_value: torch.Tensor, sampled_return: torch.Tensor, clip: float):
205 clipped_value = sampled_value + (value - sampled_value).clamp(min=-clip, max=clip)
206 vf_loss = torch.max((value - sampled_return) ** 2, (clipped_value - sampled_return) ** 2)
207 return 0.5 * vf_loss.mean()