强化学习 5.PPO 算法
前言
从零开始学习ai文章系列计划是个人在《动手学深度学习》和《磨菇书》两本书的学习中的个人笔记,文章也会以课本中的章节分开,即每个章节一片笔记。我会尽量的把主要内容以及遇到的难点进行记录与解决,如果哪里有错误的欢迎指正。或者不清晰的可以直接查看原文部分。
《蘑菇书》原文(课本):https://datawhalechina.github.io/easy-rl/#/
(由于有时候公式太多,可能会直接贴图片)
蘑菇书的文章结构不会跟之前《动手学深度学习》按照原文章节进行,个人会适当调节。
1. 重要性采样
在介绍近端策略优化(proximal policy optimization,PPO) 之前,我们先回顾同策略和异策略这两种训练方法的区别。在强化学习里面,要学习的是一个智能体。如果要学习的智能体(更新时生成的action,比如max(a))和与环境交互的智能体(交换生成action,比如ε-贪心探索)是相同的,我们称之为同策略。如果要学习的智能体和与环境交互的智能体不是相同的,我们称之为异策略。
为什么我们会想要考虑异策略?让我们回忆一下策略梯度。策略梯度是同策略的算法,因为在策略梯度中,我们需要一个智能体、一个策略和一个演员。演员去与环境交互搜集数据,搜集很多的轨迹 τ,根据搜集到的数据按照策略梯度的公式更新策略的参数(更新同一个策略网络),所以策略梯度是一个同策略的算法。PPO是策略梯度的变形,它是现在 OpenAI 默认的强化学习算法。
策略梯度的 loss求导如下 \[ \nabla\bar{R_\theta}=\mathbb{E}_{\tau\sim p_\theta(\tau)}[R(\tau)\nabla\log p_\theta(\tau)] \] 问题在于式中的 \(\mathbb{E}_{\tau\sim p_\theta(\tau)}\) 是对策略 \(\pi_\theta\) 采样的轨迹 τ 求期望。一旦更新了参数,从 θ 变成 \(\theta'\) ,概率 pθ(τ) 就不对了,之前采样的数据也不能用了。所以策略梯度是一个会花很多时间来采样数据的算法,其大多数时间都在采样数据。
智能体与环境交互以后,接下来就要更新参数。我们只能更新参数一次,然后就要重新采样数据, 才能再次更新参数。这显然是非常花时间的,所以我们想要从同策略变成异策略,这样就可以用另外一个策略 \(\pi_{\theta'}\) 、另外一个演员 \(\theta'\) 与环境交互(\(\theta'\) 被固定了),用 \(\theta'\) 采样到的数据去训练 θ。假设我们可以用 \(\theta'\) 采样到的数据去训练 θ,我们可以多次使用 \(\theta'\) 采样到的数据,可以多次执行梯度上升(gradient ascent),可以多次更新参数, 都只需要用同一批数据。因为假设 θ 有能力学习另外一个演员 \(\theta'\) 所采样的数据,所以\(\theta'\) 只需采样一次,并采样多一点的数据,让 θ 去更新很多次,这样就会比较有效率。
具体怎么做呢?这就需要介绍重要性采样(importance sampling) 的概念。
对于一个随机变量,我们通常用概率密度函数来刻画该变量的概率分布特性。具体来说,给定随机变量的一个取值,可以根据概率密度函数来计算该值对应的概率(密度)。反过来,也可以根据概率密度函数提供的概率分布信息来生成随机变量的一个取值,这就是采样。
因此,从某种意义上来说,采样是概率密度函数的逆向应用。与根据概率密度函数计算样本点对应的概率值不同,采样过程往往没有那么直接,通常需要根据待采样分布的具体特点来选择合适的采样策略。
假设我们有一个函数 \(f(x)\),要计算从 \(分布p\) 采样 x,再把 x 代入 f ,得到 f(x)。我们该怎么计算 f(x)的期望值呢?假设我们不能对分布 p 做积分,但可以从 \(分布p\) 采样一些数据 \(x_i\) 。把 \(x_i\) 代入 f(x),取它的平均值,就可以近似 f(x) 的期望值。
现在有另外一个问题,假设我们不能从 \(分布p\) 采样数据,只能从另外一个 \(分布q\) 采样数据x,q 可以是任何分布。如果我们从 q 采样 \(x_i\) ,就不能使用式(5.2)。因为式(5.2)是假设 x 都是从 p 采样出来的。

所以我们做一个修正,期望值 \(\mathbb{E}_{x\sim p}[f(x)]\) 展开来就是: \(\int f(x)p(x)dx\) 。
我们对其做如下的变换:

即

这样我们就可以写成对 q 里面所采样出来的 x 取期望值。我们从 q 里面采样 x,再计算 \(f(x)\frac{p(x)}{q(x)}\) ,再取期望值。所以就算我们不能从 p 里面采样数据,但只要能从 q 里面采样数据,就可以计算从 p 采样 x 代入 f 以后的期望值。
因为是从 q 采样数据,所以我们从 q 采样出来的每一笔数据,都需要乘一个重要性权重(importance weight) \(\frac{p(x)}{q(x)}\) 来修正这两个分布的差异。q(x) 可以是任何分布,唯一的限制就是 q(x) 的概率是 0 的时候,p(x) 的概率不为 0,不然会没有定义。假设 q(x) 的概率是 0 的时候,p(x) 的概率也都是 0,p(x) 除以 q(x)是有定义的。所以这个时候我们就可以使用重要性采样,把从 p 采样换成从 q 采样。
举个例子,策略 \(\pi_1\) 第一次生成了轨迹链 \(\tau\) 。我们在更新完网络后,新的策略为 \(\pi_2\) 。
至此位置,\(分布p\) 就是我们的当前网络 \(\pi_2\) ,而旧网络 \(\pi_1\) 则遵从着旧的 \(分布q\) 。
我们使用旧网络生成的轨迹链对新网络进行训练,那么我们需要计算出该轨迹链在 \(分布q\) 中的概率 \(q(\tau)\) 以及 该轨迹链在 \(新分布p\) 中的概率 \(p(\tau)\) ,然后计算我们的目标函数,即总奖励 \(R(\tau)\) 。
根据之前学的,我们能够对轨迹链的概率进行展开
所以比值变成:
求导公式也从原来的:
变成了
与原本相比,使用其他分布的数据,我们需要乘以 \(\frac{p(\tau)}{q(\tau)}\) 这一项。这一项也被称为重要性。
重要性(importance)本质是在衡量:一个样本在目标分布 \(p\) 下“应该被重视的程度”,相对于它在采样分布 \(q\) 下出现的程度。
重要性权重 \(\frac{p}{q}\) 做的事情是:
重新加权样本,让“旧数据看起来像是从新策略采样的”
重要性采样有一些问题。虽然我们可以把 p 换成任何的 q。但是在实现上, p 和 q 的差距不能太大。差距太大,会有一些问题。比如,虽然式(5.3)成立(式(5.3)左边是 f(x) 的期望值,它的分布是 p,式(5.3)右边是 \(f(x)\frac{p(x)}{q(x)}\) 的期望值,它的分布是 q),它们期望是一样的,但是方差不一样,即 \(Var_{x\sim p}[f(x)]\) 和 \(Var_{x\sim q}[f(x)\frac{p(x)}{q(x)}]\) 是不一样的。

我们可以将 \(f(x)\) 和 \(f(x)\frac{p(x)}{q(x)}\) 代入方差的公式 \(Var[x]=E[X^2]-(E[X])^2\) (标准方程公式的变形),得到:


\(Var_{x\sim p}[f(x)]\) 和 \(Var_{x\sim q}[f(x)\frac{p(x)}{q(x)}]\) 的差别在于第一项是不同的。
\(Var_{x\sim q}[f(x)\frac{p(x)}{q(x)}]\) 的第一项多乘了 \(\frac{p(x)}{q(x)}\) ,如果 \(\frac{p(x)}{q(x)}\) 差距很大,\(f(x)\frac{p(x)}{q(x)}\) 的方差就会很大。
所以理论上它们的期望值一样,也就是,我们只要对分布p采样足够多次,对分布q采样足够多次,得到的结果会是一样的。但是如果我们采样的次数不够多,因为它们的方差差距是很大的,所以我们就有可能得到差别非常大的结果。

例如,当 p(x) 和 q(x) 差距很大时,就会有问题。如图 5.1 所示,假设蓝线是 p(x) 的分布,绿线是 q(x) 的分布,红线是 f(x)。(分布即概率密度分布,指的x出现在该处的概率,可以看到绿色点从分布q中采样出来的。而q和p的分布几乎错开,因此两者差距极大。)
如果我们要计算 f(x)的期望值,从分布 p(x) 做采样,显然 \(\mathbb{E}_{x\sim p}[f(x)]\) 是负的。这是因为左边区域 p(x) 的概率很高,所以采样会到这个区域,而 f(x) 在这个区域是负的, 所以理论上这一项算出来会是负的。
接下来我们改成从 q(x) 采样,因为 q(x) 在右边区域的概率比较高,所以如果我们采样的点不够多,可能只会采样到右侧。如果我们只采样到右侧,,可能 \(\mathbb{E}_{x\sim p}[f(x)]\) 是正的。 我们这边采样到这些点,去计算它们的 \(f(x)\frac{p(x)}{q(x)}\) 都是正的。
我们采样到这些点都是正的,取期望值以后也都是正的,这是因为采样的次数不够多。假设我们采样次数很少,只能采样到右边。左边虽然概率很低,但也有可能被采样到。假设我们好不容易采样到左边的点,因为左边的点的p(x) 和 q(x) 是差很多的, 这边 p(x) 很大,q(x) 很小。 f(x) 好不容易终于采样到一个负的,这个负的就会被乘上一个非常大的权重,这样就可以平衡刚才那边一直采样到正的值的情况。最终我们算出这一项的期望值,终究还是负的。
但前提是我们要采样足够多次,这件事情才会发生。但有可能采样次数不够多, \(\mathbb{E}_{x\sim p}[f(x)]\) 与 \(\mathbb{E}_{x\sim p}[f(x)\frac{p(x)}{q(x)}]\) 可能就有很大的差距。这就是重要性采样的问题。
现在要做的就是把重要性采样用在异策略的情况中,把同策略训练的算法改成异策略训练的算法。
怎么改呢?如式(5.4)所示,之前我们用策略 \(\pi_{\theta}\) 与环境交互,采样出轨迹 \(\tau\) ,计算 \(R(\tau)\nabla\log p_{\theta}(\tau)\) 。现在我们不用 \(\pi_{\theta}\) 与环境交互,假设有另外一个策略 \(\pi_{\theta}'\) ,它就是另外一个演员,它的工作是做示范(demonstration)。

\(\theta'\) 的工作是为θ 做示范。它与环境交互,告诉 θ 它与环境交互会发生什么事,借此来训练 θ。我们要训练的是 θ ,\(\theta'\) 只负责做示范,负责与环境交互。
我们现在的 τ 是从 \(\theta'\) 采样出来的,是用 \(\theta'\) 与环境交互。所以采样出来的 τ 是从 \(\theta'\) 采样出来的,这两个分布不一样。但没有关系,假设我们本来是从 p 采样,但发现不能从 p 采样,所以我们不用 θ 与环境交互,可以把 p 换成 q,在后面补上一个重要性权重。同理,我们把 θ 换成 \(\theta'\) 后,要补上一个重要性权重 \(\frac{p(x)}{q(x)}\) 。这个重要性权重就是某一个轨迹 τ 用 θ 算出来的概率除以这个轨迹 τ 用 \(\theta'\) 算出来的概率。这一项是很重要的,因为我们要学习的是演员 θ,而 θ 和 \(\theta'\) 是不太一样的,\(\theta'\) 见到的情形与 θ 见到的情形可能不是一样的,所以中间要有一个修正的项。
实际在做策略梯度的时候,我们并不是给整个轨迹 τ 一样的分数,而是将每一个状态-动作对分开计算。实际更新梯度的过程可写为

我们用演员θ 采样出 \(s_t\) 与 \(a_t\) ,采样出状态-动作的对,我们会计算这个状态-动作对的优势(advantage)\(A^θ(s_t,a_t)\), 就是它有多好。 \(A^θ(s_t,a_t)\) 即用累积奖励减去基线,这一项就是估测出来的。它要估测的是,在状态 \(s_t\) 采取动作 \(a_t\) 是好的还是不好的。接下来在后面乘 \(\nabla\log p_{\theta}(a^n_t|s^n_t)\) ,也就是如果 \(A^θ(s_t,a_t)\) 是正的,就要增大概率;如果是负的,就要减小概率。
我们可以通过重要性采样把同策略变成异策略,从 θ 变成 \(\theta'\)。所以现在 \(s_t\) 、 \(a_t\) 是 \(\theta'\) 与环境交互以后所采样到的数据。 但是训练时,要调整的参数是模型 θ。因为 \(\theta'\) 与 θ 是不同的模型,所以我们要有一个修正的项。这个修正的项,就是用重要性采样的技术,把 \(s_t\) 、 \(a_t\) 用 θ 采样出来的概率除以 \(s_t\) 、 \(a_t\) 用 \(\theta'\) 采样出来的概率。

其中, \(A^θ(s_t,a_t)\) 有一个上标 θ,θ 代表 \(A^θ(s_t,a_t)\) 是演员 θ 与环境交互的时候计算出来的。但是实际上从 θ 换到 θ′ 的时候, \(A^θ(s_t,a_t)\) 应该改成 \(A^{θ'}(s_t,a_t)\) ,为什么呢? \(A(s_t,a_t)\) 这一项是想要估测在某一个状态采取某一个动作,接下来会得到累积奖励的值减去基线的值。我们怎么估计 \(A(s_t,a_t)\) ? 我们在状态 \(s_t\) 采取动作 \(a_t\) ,接下来会得到的奖励的总和,再减去基线就是 \(A(s_t,a_t)\) 。之前是 θ 与环境交互,所以我们观察到的是 θ 可以得到的奖励。但现在是 θ′ 与环境交互,所以我们得到的这个优势是根据 θ′ 所估计出来的优势。但我们现在先不要管那么多,就假设 \(A^θ(s_t,a_t)\) 和 \(A^{θ'}(s_t,a_t)\) 可能是差不多的。
由于奖励是环境决定的,所以我觉得相同轨迹下由奖励计算出来的回报也应该是一样的。
接下来,我们可以拆解 \(p_{\theta}(a_t|s_t)\) 和 \(p_{\theta'}(a_t|s_t)\) ,即

于是我们可得

这里需要做的一件事情是,假设模型是 θ 的时候,我们看到 \(s_t\) 的概率,与模型是 θ′ 的时候,我们看到 \(s_t\) 的概率是一样的,即 \(p_θ(s_t)=p_{θ'}(s_t)\)。因为 \(p_θ(s_t)\) 和 \(p_{θ'}(s_t)\) 是一样的,所以我们可得

在工程实现上,我们根本没法计算 \(p_θ(s_t)\) 。什么是 \(p_θ(s_t)\) ?表示的是:在策略 \(\pi_\theta\) 下,第 t 步到达状态 \(s_t\) 的概率也就是说:所有能在第 t 步走到 \(s_t\) 的轨迹概率的总和。它依赖“所有可能轨迹”。
假如策略只变一点点 ⇒ 状态分布也只变一点点
于是就有了经典近似:\(p_θ(s_t)\approx p_{θ'}(s_t)\)
式(5.5)是梯度,我们可以从下面的公式反推原来的目标函数:

注意,对 θ 求梯度时, \(p_{\theta'}(a_t|s_t)\) 和 \(A^{θ'}(s_t,a_t)\) 都是常数。
所以实际上,当我们使用重要性采样的时候,要去优化的目标函数为

可能你会疑惑,为什么我们之前需要将分布p使用式子 \(\nabla f(x)=f(x)\nabla\log f(x)\) 进行转换,而现在使用原公式即可。其实这主要涉及到采样的问题。
我们一开始对总奖励R的求导如下 \[ \nabla \bar{R}_\theta=\sum_{\tau}R(\tau)\nabla p_{\theta}(\tau) \] 这里 \(\nabla p_{\theta}(\tau)\) 虽然本身可以计算,但求和是对所有可能轨迹穷举,轨迹空间过于巨大,实践中无法枚举。因此我们通过恒等变换将其转化为期望的形式: \[ \nabla \bar{R}_\theta=\mathbb{E}_{\tau\sim p_\theta(\tau)}[R(\tau)\nabla\log p_{\theta}(\tau)] \] 这样,我们就能够通过分布p,采样数据然后开始计算 \(R(\tau)\nabla\log p_{\theta}(\tau)\) 的结果了。
但是对于修改后的异策略方法来说,以下两个方法是等价的 \[ \mathbb{E}_{(s_t,a_t)\sim\pi_{\theta'}}[\frac{p_\theta(a_t|s_t)}{p_{\theta'}(a_t|s_t)}A^{\theta'}(s_t,a_t)\nabla\log p_\theta(a^n_t|s^n_t)]= \mathbb{E}_{(s_t,a_t)\sim\pi_{\theta'}}[\frac{\nabla p_\theta(a_t|s_t)}{p_{\theta'}(a_t|s_t)}A^{\theta'}(s_t,a_t)] \] 因为存在恒等式 \(\nabla f(x)=f(x)\nabla\log f(x)\) ,两式之间只是对 \(p_\theta\) 做了等价变形。此处不需要对 \(\nabla p_\theta\) 单独采样,期望的采样分布始终是 \(\pi_{\theta'}\),所以可以直接使用原始梯度形式而无需转换为 \(\log\) 形式。
2. 近端策略优化
我们可以通过重要性采样把同策略换成异策略,但重要性采样有一个问题:如果 \(p_{\theta}(a_t|s_t)\) 与 \(p_{\theta'}(a_t|s_t)\) 相差太多,即这两个分布相差太多,重要性采样的结果就会不好。 怎么避免它们相差太多呢?这就是PPO要做的事情。

如式(5.6)所示,PPO 需要优化目标函数 \(J^{θ'}(θ)\) 。但是这个目标函数又牵涉到重要性采样。在做重要性采样的时候,\(p_\theta(a_t|s_t)\) 不能与 \(p_{\theta'}(a_t|s_t)\) 相差太多。做示范的模型不能与真正的模型相差太多,相差太多,重要性采样的结果就会不好。我们在训练的时候,应多加一个约束(constrain)。这个约束是 θ 与 θ′ 输出的动作的 KL 散度(KL divergence),这一项用于衡量 θ 与 θ′ 的相似程度。我们希望在训练的过程中,学习出的 θ 与 θ′ 越相似越好。因为如果 θ 与 θ′ 不相似,最后的结果就会不好。
所以在 PPO 里面有两项:一项是优化本来要优化的 \(J^{θ'}(θ)\) ,另一项是一个约束。这个约束就好像正则化(regularization)的项(term) 一样,它所做的就是希望最后学习出的 θ 与 θ′ 相差不大。注意,虽然 PPO 的优化目标涉及到了重要性采样,但其只用到了上一轮策略 θ′ 的数据。
PPO 目标函数中加入了 KL 散度的约束,行为策略 θ′ 和目标策略 θ 非常接近,PPO 的行为策略和目标策略可认为是同一个策略,因此 PPO 是同策略算法。
PPO 有一个前身:信任区域策略优化(trust region policy optimization,TRPO)。TRPO 可表示为

TRPO 与 PPO 不一样的地方是约束所在的位置不一样,PPO 直接把约束放到要优化的式子里面,我们就可以用梯度上升的方法去最大化式(5.6)。
但 TRPO 是把 KL 散度当作约束,它希望 θ 与 θ′ 的 KL 散度小于 δ。如果我们使用的是基于梯度的优化,有约束是很难处理的。TRPO 是很难处理的,因为它把 KL 散度约束当作一个额外的约束,没有放在目标(objective)里面,所以它很难计算。
因此我们一般就使用 PPO,而不使用 TRPO 。PPO 与 TRPO 的性能差不多,但 PPO 在实现上比 TRPO 容易得多。
KL 散度的输入是 θ 与 θ′ 所对应的行为分布,而非参数本身。所谓 θ 与 θ' 之间的距离,并不是参数数值上的距离,而是行为上的距离。具体来说,假设我们有两个演员 θ 和 θ',以及 3 个可选动作 \(a_1, a_2, a_3\) 。给定同一个状态 s,θ 输出的动作分布可能是 (0.7,0.2,0.1),而 θ' 输出的动作分布可能是 (0.3,0.4,0.3)。
KL 散度的计算公式为:
套入刚才的例子,θ 输出分布 p=(0.7,0.2,0.1),θ' 输出分布 q=(0.3,0.4,0.3),则:
0.485 表示在状态 s 下,θ 和 θ' 这两个演员的行为差异程度。KL 散度的值越大,说明两个分布差异越大;越接近 0,说明两个分布越相似。
DKL(p∥q) 的含义是:以 p 为基准,衡量用 q 来近似 p 时的信息损失。公式中每一项的权重是 p(i),所以 p 概率大的地方贡献更大。一般我们以新策略为基准,衡量新策略p 偏离旧策略q 的程度。这样新策略概率大的动作上的差异会被重点惩罚。但实际上也有用DKL(q∥p)的,有些实现甚至取两者的平均(称为 Jensen-Shannon 散度)。
2.1 近端策略优化惩罚
PPO 算法有两个主要的变种:近端策略优化惩罚(PPO-penalty)和近端策略优化裁剪(PPO-clip)。
我们来看一下 PPO1 算法,即近端策略优化惩罚算法。它先初始化一个策略的参数 \(θ^0\) 。在每一个迭代里面,我们用前一个训练的迭代得到的演员的参数 \(θ_k\) 与环境交互,采样到大量状态-动作对。根据 \(θ^k\) 交互的结果,我们估测 \(A^{θ^k}(s_t,a_t)\) 。我们使用 PPO 的优化公式。但与原来的策略梯度不一样,原来的策略梯度只能更新一次参数,更新完以后,我们就要重新采样数据。但是现在不同,我们用 \(θ^k\) 与环境交互,采样到这组数据以后,我们可以让 θ 更新很多次,想办法最大化目标函数,如式(5.7)所示。这里面的 θ 更新很多次也没有关系,因为我们已经有重要性采样,所以这些经验,这些状态-动作对是从 \(θ^k\) 采样出来的也没有关系。θ 可以更新很多次,它与 \(θ^k\) 变得不太一样也没有关系,我们可以照样训练 θ。

在 PPO 的论文里面还有一个自适应KL散度(adaptive KL divergence)。这里会遇到一个问题就,即 β 要设置为多少。这个问题与正则化一样,正则化前面也要乘一个权重,所以 KL 散度前面也要乘一个权重,但 β 要设置为多少呢?
我们有一个动态调整 β 的方法。在这个方法里面,我们先设一个可以接受的 KL 散度的最大值。假设优化完式(5.7)以后,KL 散度的值太大,这就代表后面惩罚的项 \(\beta KL(\theta,\theta^k)\) 没有发挥作用,我们就把 β 增大。另外,我们设一个 KL 散度的最小值。如果优化完式(5.7)以后,KL 散度比最小值还要小,就代表后面这一项的效果太强了,我们怕他只优化后一项,使 θ 与 \(θ^k\) 一样,这不是我们想要的,所以我们要减小β。β 是可以动态调整的,因此我们称之为自适应KL惩罚(adaptive KL penalty)。我们可以总结一下自适应KL惩罚:

近端策略优化惩罚可表示为

2.2 近端策略优化裁剪
如果我们觉得计算 KL 散度很复杂,那么还有一个 PPO2算法,PPO2 即近端策略优化裁剪。近端策略优化裁剪的目标函数里面没有 KL 散度,其要最大化的目标函数为

其中,
- 操作符(operator)min 是在第一项与第二项里面选择比较小的项。
- 第二项前面有一个裁剪(clip)函数,裁剪函数是指,在括号里面有3项,如果第一项小于第二项,那就输出 1−ε;第一项如果大于第三项,那就输出 1+ε。
- ε 是一个超参数,是我们要调整的,可以设置成 0.1 或 0.2 。
假设设置 ε=0.2,我们可得 \(clip(\frac{p_\theta(a_t|s_t)}{p_{\theta^k}(a_t|s_t)},0.8,1.2)\) ,如果 \(\frac{p_\theta(a_t|s_t)}{p_{\theta^k}(a_t|s_t)}\) 算出来小于 0.8,那就输出 0.8;如果算出来大于 1.2,那就输出1.2。
图 5.2 的横轴代表 \(\frac{p_\theta(a_t|s_t)}{p_{\theta^k}(a_t|s_t)}\) ,纵轴代表裁剪函数的输出。

这样的好处就是,我们不会让 \(p_\theta(a_t|s_t)\) 与 \(p_{\theta^k}(a_t|s_t)\) 差距太大。要实现这个其实很简单。
图 5.4 所示为 PPO 与其他算法的比较。优势演员-评论员和优势演员-评论员+信任区域(trust region)算法是基于演员-评论员的方法。PPO 算法是用紫色线表示,图 5.4 中每张子图表示某一个强化学习的任务,在多数情况中,PPO 都是不错的,即使不是最好的,也是第二好的。

为什么需要 kl散度 或者 clip裁剪 来控制原本的PPO呢?
PPO(不论 clip 还是 penalty)本质上就是:
- 不再追求无偏(unbiased)
- 明确引入偏差(bias)
- 换取显著更小的方差(variance),从而让训练“真的能收敛”。
clip 和 penalty 所做的事情没有本质差别,
- 阻止 p/q 爆炸
- 限制单样本的最大影响
- 用偏差换方差与稳定性
只是:
- clip:工程更简单,超参数更少
- penalty:数学更平滑,但 β 难调





