文章目录
On policy 与 Off policy
在讲解PPO算法前,我们需要明白On/Off policy的概念:
- On-policy:用当前的Agent生成经验,并且用于更新这个Agent。即Agent一边和环境互动,一边学习
- Off-policy:用其他的Agent生成经验,用于更新当前Agent。即Agent是学习其他的Agent的互动经验
之前所学习的Policy Gradient方法就是On-policy的,它的缺点就是每次更新都需要等Agent环境做互动,更新完之后,前一次互动经验又不能用了。这导致了Policy Gradient算法训练很耗时,时间都花在收集数据上。所以我们如果能将Policy Gradient变成Off-policy的算法,那之前互动的数据可以重复使用,大大提升了训练效率。
Importance Sampling
为了解决这个问题,我们先引入重要性采样的概念(Importance Sampling)。假设现在有一个
f
(
x
)
f(x)
f(x)函数,
x
x
x从分布
p
p
p采样,代入到
f
(
x
)
f(x)
f(x)函数里。现在我们需要求它的期望值,即
E
x
∼
p
[
f
(
x
)
]
E_{x \sim p}[f(x)]
Ex∼p[f(x)]。在没有办法对分布
p
p
p做积分的前提下,我们可以从分布
p
p
p里面采样几个
x
x
x,然后代入到
f
(
x
)
f(x)
f(x),求和然后取平均,这就近似这个期望值了。
E
x
∼
p
[
f
(
x
)
]
≈
1
N
∑
i
=
1
N
f
(
x
i
)
E_{x \sim p}[f(x)] \approx \frac{1}{N}\sum_{i=1}^N f(x^i)
Ex∼p[f(x)]≈N1i=1∑Nf(xi)
假设我们现在不知道分布
p
p
p长什么样(模拟Off-policy的情况),要怎么算期望值呢?我们引入一个分布
q
q
q(这个是已知的条件),它可以是任何分布,我们先不管它是怎么样的分布。
我们从分布
q
q
q采样出来的
x
x
x没办法直接丢到
p
(
x
)
p(x)
p(x)计算,所以我们现在需要做一个修正,分布
q
q
q的采样可以用来计算期望值。求期望值可以用它的概率密度函数表示:
E
x
∼
p
[
f
(
x
)
]
=
∫
f
(
x
)
p
(
x
)
d
x
E_{x \sim p}[f(x)] = \int f(x)p(x) dx
Ex∼p[f(x)]=∫f(x)p(x)dx
上下同乘
q
(
x
)
q(x)
q(x)
E
x
∼
p
[
f
(
x
)
]
=
∫
f
(
x
)
p
(
x
)
q
(
x
)
q
(
x
)
d
x
E_{x \sim p}[f(x)] = \int f(x) \frac{p(x)}{q(x)} q(x) dx
Ex∼p[f(x)]=∫f(x)q(x)p(x)q(x)dx
将
f
(
x
)
p
(
x
)
q
(
x
)
f(x) \frac{p(x)}{q(x)}
f(x)q(x)p(x)看成原来的
f
(
x
)
f(x)
f(x),这样我们就可以写成从分布
q
q
q中采样的期望公式了:
E
x
∼
q
[
f
(
x
)
p
(
x
)
q
(
x
)
]
=
∫
f
(
x
)
p
(
x
)
q
(
x
)
q
(
x
)
d
x
E_{x \sim q}[f(x) \frac{p(x)}{q(x)}] = \int f(x) \frac{p(x)}{q(x)} q(x) dx
Ex∼q[f(x)q(x)p(x)]=∫f(x)q(x)p(x)q(x)dx
那么
p
(
x
)
q
(
x
)
\frac{p(x)}{q(x)}
q(x)p(x)这一项就是额外乘上去的,我们将其视作是一个weight,用来修正
q
(
x
)
q(x)
q(x)和
p
(
x
)
p(x)
p(x)的差异。分布
q
q
q可以是任意的分布,但也有一个前提,不能
q
(
x
)
q(x)
q(x)几率为0的时候,
p
(
x
)
p(x)
p(x)不为0,这样会没有定义。
Issue of Importance Sampling
虽然我们说 q ( x ) q(x) q(x)可以是任意的分布,但在实际优化的过程中,还是不能和 p ( x ) p(x) p(x)差太多。尤其是它们算方差的时候,影响会比较大。如下图所示,其方差不一样就体现在第一项中,后者比前者多了一个 p ( x ) q ( x ) \frac{p(x)}{q(x)} q(x)p(x),如果分布 p p p和 q q q差太大的话,随机变量的方差就会差很多。这时,如果采样的样本数不够多的话,那么数值上的差别就会比较大。
可以用下面这个例子简单说明一下,如果两个分布差很多的时候,会有什么情况。其中绿线是指
q
(
x
)
q(x)
q(x),蓝线是指
p
(
x
)
p(x)
p(x),红线是指
f
(
x
)
f(x)
f(x)。假设纵轴代表的是概率,
p
(
x
)
p(x)
p(x)在左边被sample到的概率很高,
q
(
x
)
q(x)
q(x)在右边被sample到的概率很高。
如果sample次数比较少,都只采样到正的情况,
E
x
∼
p
[
f
(
x
)
]
E_{x \sim p}[f(x)]
Ex∼p[f(x)]计算出来可能是正值。
如果说sample次数比较多的情况下,有几率采样到左边的情况,即使次数很少,但它
p
(
x
)
q
(
x
)
\frac{p(x)}{q(x)}
q(x)p(x)算出来的weight比较大,
E
x
∼
p
[
f
(
x
)
]
E_{x \sim p}[f(x)]
Ex∼p[f(x)]计算出来就可能是负值。所以足够多的采样才能保证两个期望是差不多的。但sample次数不够多的情况下,左式和右式就会差很多。那么这也是Importance Sampling的一个问题所在。
From On-policy to off-policy
将重要性采样的思想迁移到Policy Gradient中去,即我们要更新的模型是参数是 θ \theta θ,我们上一次采样的数据是用参数 θ ′ \theta' θ′采样而来的。这时候可以将 θ \theta θ视作 p ( x ) p(x) p(x), θ ′ \theta' θ′视作 q ( x ) q(x) q(x)。从而使得上一个action采样出来的数据可以重复使用。同时由于 θ \theta θ与 θ ′ \theta' θ′在优化前后(只要学习率不是很大,或者同一样本优化次数不是很多)其实是差不多的,分布上也不会差太多。
我们回到之前的update Policy Gradient的公式(用
θ
\theta
θ这个actor去sample出
s
t
,
a
t
s_t,a_t
st,at,计算Advantage这项有多好,log项为发生的概率,如果为Advantage正,log项需要增加,如果Advantage为负的,log项需要减少):
E
(
s
t
,
a
t
)
∼
π
θ
[
A
θ
(
s
t
,
a
t
)
∇
l
o
g
p
θ
(
a
t
n
∣
s
t
n
)
]
E_{(s_t,a_t) \sim \pi_\theta}[A^\theta(s_t,a_t)\nabla logp_\theta(a_t^n|s_t^n)]
E(st,at)∼πθ[Aθ(st,at)∇logpθ(atn∣stn)]
引入
θ
′
\theta'
θ′,这里值得注意的是,假设
A
θ
(
s
t
,
a
t
)
A^\theta(s_t,a_t)
Aθ(st,at)和
A
θ
′
(
s
t
,
a
t
)
A^{\theta'}(s_t,a_t)
Aθ′(st,at)是差不多的,理论上是要用
A
θ
′
(
s
t
,
a
t
)
A^{\theta'}(s_t,a_t)
Aθ′(st,at)计算
E
(
s
t
,
a
t
)
∼
π
θ
′
[
P
θ
(
s
t
,
a
t
)
P
θ
′
(
s
t
,
a
t
)
A
θ
(
s
t
,
a
t
)
∇
l
o
g
p
θ
(
a
t
n
∣
s
t
n
)
]
E_{(s_t,a_t) \sim \pi_{\theta'}}[\frac{P_\theta(s_t,a_t)}{P_{\theta'}(s_t,a_t)} A^\theta(s_t,a_t) \nabla logp_\theta(a_t^n|s_t^n)]
E(st,at)∼πθ′[Pθ′(st,at)Pθ(st,at)Aθ(st,at)∇logpθ(atn∣stn)]
进一步分解
P
θ
(
s
t
,
a
t
)
P_\theta(s_t,a_t)
Pθ(st,at)为
p
θ
(
s
t
∣
a
t
)
p_\theta(s_t|a_t)
pθ(st∣at)和
p
θ
(
s
t
)
p_\theta(s_t)
pθ(st),而
p
θ
(
s
t
)
p_\theta(s_t)
pθ(st)和
p
θ
′
(
s
t
)
p_{\theta'}(s_t)
pθ′(st)实则是环境出现的概率(通常没法计算,而且大概率都是一样的。例如,游戏第一关打完,必定出现第二关),所以这一项可近似看成1。
E
(
s
t
,
a
t
)
∼
π
θ
′
[
p
θ
(
a
t
∣
s
t
)
p
θ
′
(
a
t
∣
s
t
)
p
θ
(
s
t
)
p
θ
′
(
s
t
)
A
θ
(
s
t
,
a
t
)
∇
l
o
g
p
θ
(
a
t
n
∣
s
t
n
)
]
E_{(s_t,a_t) \sim \pi_{\theta'}}[\frac{p_\theta(a_t|s_t)}{p_{\theta'}(a_t|s_t)} \frac{p_\theta(s_t)}{p_{\theta'}(s_t)} A^\theta(s_t,a_t) \nabla logp_\theta(a_t^n|s_t^n)]
E(st,at)∼πθ′[pθ′(at∣st)pθ(at∣st)pθ′(st)pθ(st)Aθ(st,at)∇logpθ(atn∣stn)]
根据之前常用到的公式:
∇
f
(
x
)
=
f
(
x
)
∇
l
o
g
f
(
x
)
\nabla f(x) = f(x)\nabla logf(x)
∇f(x)=f(x)∇logf(x)
我们可以反推得到优化函数:
J
θ
′
(
θ
)
=
E
(
s
t
,
a
t
)
∼
π
θ
′
[
p
θ
(
a
t
∣
s
t
)
p
θ
′
(
a
t
∣
s
t
)
A
θ
′
(
s
t
,
a
t
)
]
J^{\theta'}(\theta) = 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)]
Jθ′(θ)=E(st,at)∼πθ′[pθ′(at∣st)pθ(at∣st)Aθ′(st,at)]
那么
J
θ
′
(
θ
)
J^{\theta'}(\theta)
Jθ′(θ)是优化的目标,代表
θ
′
\theta'
θ′做演示,
θ
\theta
θ是实际优化的参数。
Add Constraint
我们先前提到了分布 p p p和分布 q q q不能差太远,为了进一步解决这个问题,我们再引入一个限制,KL散度。
KL散度(Kullback-Leibler Divergence)是衡量两个概率分布之间差异的一种方法。在信息论和统计学中,它描述了一个概率分布 P P P相对于另一个概率分布 Q Q Q的信息损失。KL散度可以看作是用分布 Q Q Q来近似分布 P P P所造成的差异或误差。
对于离散概率分布
P
P
P和
Q
Q
Q,KL散度定义为:
D
K
L
(
P
∥
Q
)
=
∑
x
P
(
x
)
l
o
g
P
(
x
)
Q
(
x
)
D_{KL}(P∥Q)= \sum_x P(x)log \frac{P(x)}{Q(x)}
DKL(P∥Q)=x∑P(x)logQ(x)P(x)
对于连续概率分布
P
P
P和
Q
Q
Q,KL散度定义为:
D
K
L
(
P
∥
Q
)
=
∫
−
∞
∞
P
(
x
)
l
o
g
P
(
x
)
Q
(
x
)
d
x
D_{KL}(P∥Q)= \int^{\infty}_{-\infty } P(x)log \frac{P(x)}{Q(x)} dx
DKL(P∥Q)=∫−∞∞P(x)logQ(x)P(x)dx
其中
p
(
x
)
p(x)
p(x)和
q
(
x
)
q(x)
q(x)分别是分布
P
P
P和
Q
Q
Q的概率密度函数。
通过给优化项添加一个KL散度的限制,那么我们就获得了PPO的优化公式了。
Proximal Policy Optimization(PPO)
公式如下:
J
P
P
O
θ
′
(
θ
)
=
J
θ
′
(
θ
)
−
β
K
L
(
θ
,
θ
′
)
J^{\theta'}_{PPO}(\theta) = J^{\theta'}(\theta) - \beta KL(\theta, \theta')
JPPOθ′(θ)=Jθ′(θ)−βKL(θ,θ′)
我们需要优化的是
J
θ
′
(
θ
)
J^{\theta'}(\theta)
Jθ′(θ),这个值越大越好,惩罚项是
β
K
L
(
θ
,
θ
′
)
\beta KL(\theta, \theta')
βKL(θ,θ′),是我们希望最小化的部分。这里要注意一下,虽然公式是这么写的,但我们实际希望的不是
θ
\theta
θ与
θ
′
\theta'
θ′的实际数值越相似越好,而是它们的behavior越接近越好。就是说输入
s
t
s_t
st给到
θ
\theta
θ和
θ
′
\theta'
θ′,它们得到的action越接近越好。
PPO的前身是TRPO,它更复杂一点:
J
T
R
P
O
θ
′
(
θ
)
=
E
(
s
t
,
a
t
)
∼
π
θ
′
[
p
θ
(
a
t
∣
s
t
)
p
θ
′
(
a
t
∣
s
t
)
A
θ
′
(
s
t
,
a
t
)
]
K
L
(
θ
,
θ
′
)
<
δ
J^{\theta'}_{TRPO}(\theta) = 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)] \qquad KL(\theta, \theta') < \delta
JTRPOθ′(θ)=E(st,at)∼πθ′[pθ′(at∣st)pθ(at∣st)Aθ′(st,at)]KL(θ,θ′)<δ
TRPO是将KL散度当成一个限制,希望它小于一个值,这个值比较难确定,而且难优化。在实际优化中,PPO和TRPO效果差不多,所以后面基本都用PPO。
PPO算法流程
PPO的整个流程其实很简单,先初始化一个参数
θ
\theta
θ,让它与环境做互动收集数据,计算Advantage项。由于添加了惩罚项,收集的数据可以update
θ
\theta
θ很多次,或者可以将学习率调大,直到收敛。其中
β
\beta
β是一个动态的数值,我们可以设置一个能够接受的最大值和最小值,让它根据实际情况动态调整。
PPO2
PPO2是PPO的加强版,我们先来看看它的公式:
J
P
P
O
2
θ
k
(
θ
)
≈
∑
(
s
t
,
a
t
)
m
i
n
(
p
θ
(
s
t
∣
a
t
)
p
θ
k
(
s
t
∣
a
t
)
A
θ
k
(
s
t
,
a
t
)
,
c
l
i
p
(
p
θ
(
s
t
∣
a
t
)
p
θ
k
(
s
t
∣
a
t
)
,
1
−
ϵ
,
1
+
ϵ
)
A
θ
k
(
s
t
,
a
t
)
)
\begin{align*} J^{\theta^k}_{PPO2}(\theta) \approx \sum_{(s_t,a_t)} min( &\frac{p_\theta(s_t|a_t)}{p_{\theta^k}(s_t|a_t)} A^{\theta^k}(s_t,a_t), \\ &clip(\frac{p_\theta(s_t|a_t)}{p_{\theta^k}(s_t|a_t)}, 1 - \epsilon,1 + \epsilon) A^{\theta^k}(s_t,a_t)) \end{align*}
JPPO2θk(θ)≈(st,at)∑min(pθk(st∣at)pθ(st∣at)Aθk(st,at),clip(pθk(st∣at)pθ(st∣at),1−ϵ,1+ϵ)Aθk(st,at))
我们分开来看:
c
l
i
p
(
p
θ
(
s
t
∣
a
t
)
p
θ
k
(
s
t
∣
a
t
)
,
1
−
ϵ
,
1
+
ϵ
)
clip(\frac{p_\theta(s_t|a_t)}{p_{\theta^k}(s_t|a_t)}, 1 - \epsilon,1 + \epsilon)
clip(pθk(st∣at)pθ(st∣at),1−ϵ,1+ϵ)
这一项是指
p
θ
(
s
t
∣
a
t
)
p
θ
k
(
s
t
∣
a
t
)
\frac{p_\theta(s_t|a_t)}{p_{\theta^k}(s_t|a_t)}
pθk(st∣at)pθ(st∣at)如果小于
1
−
ϵ
1 - \epsilon
1−ϵ,就截断为
1
−
ϵ
1 - \epsilon
1−ϵ,如果大于
1
+
ϵ
1 + \epsilon
1+ϵ,那就截断为
1
+
ϵ
1 + \epsilon
1+ϵ。相当于设置了一个区间,函数曲线是这样的:
接下来,我们再加上
m
i
n
(
p
θ
(
s
t
∣
a
t
)
p
θ
k
(
s
t
∣
a
t
)
A
θ
k
(
s
t
,
a
t
)
min(\frac{p_\theta(s_t|a_t)}{p_{\theta^k}(s_t|a_t)} A^{\theta^k}(s_t,a_t)
min(pθk(st∣at)pθ(st∣at)Aθk(st,at),会有点复杂,我们可以分情况来分析:
- 如果 A > 0 A > 0 A>0,也就是说某个状态和动作 ( s t , a t ) (s_t,a_t) (st,at)是好的,我们需要调大这一项 p θ ( s t ∣ a t ) p θ k ( s t ∣ a t ) \frac{p_\theta(s_t|a_t)}{p_{\theta^k}(s_t|a_t)} pθk(st∣at)pθ(st∣at)出现的机率。但是不要忘了,不能让 θ \theta θ和 θ ′ \theta' θ′差距太大,所以最大不能超过 1 + ϵ 1 + \epsilon 1+ϵ
- 如果 A < 0 A < 0 A<0,也就是说某个状态和动作 ( s t , a t ) (s_t,a_t) (st,at)是不好的,我们需要减小这一项 p θ ( s t ∣ a t ) p θ k ( s t ∣ a t ) \frac{p_\theta(s_t|a_t)}{p_{\theta^k}(s_t|a_t)} pθk(st∣at)pθ(st∣at)出现的机率。同时,不能让 θ \theta θ和 θ ′ \theta' θ′差距太大,所以最小不能小于 1 − ϵ 1 - \epsilon 1−ϵ
所以 1 + ϵ 1 + \epsilon 1+ϵ和 1 − ϵ 1 - \epsilon 1−ϵ是惩罚项的上界和下界。
以上就是PPO/PPO2的全部内容。
争议
曾经在面试的时候,被问到过一个问题:“PPO是On-policy还是Off-policy的?”。当时不假思索的就回答是On-policy的。但后面听到面试官说是Off-policy的,我又回来查了下资料。引用一下我认为比较清晰的解释
其实可以很简单的解释这个问题,根据off-policy的定义,采样的网络和要优化的网络不是一个网络,那么对于PPO来说,使用一批数据从更新actor的第二个epoch开始,数据虽然都是旧的actor采样得到的,但是我们并没有直接使用这批数据去更新我们的新的actor,而是使用imporance sampling先将数据分布不同导致的误差进行了修正。那么这个importance sampling的目的就是让这两者数据分布之间的差异尽可能的缩小,那么就可以近似理解成做了importance sampling之后的数据就是我们的更新(这里的更新指的是多个epoch更新的中间过程)后的actor采样得来的,这样就可以理解成我们要优化得actor和采样得actor是同一个actor,那么他就是on-policy的。