目录
简介
策略梯度,顾名思义,就是优化策略的梯度。我们之前讲了Policy-based和Value-based,而Policy-based方法就是直接训练策略的一组参数。如何训练?策略梯度就是一种方法。
基本思路
要训练一个Policy-based的方法,其实只需要三步。
- 第一步,用一个神经网络作为策略自身,神经网络的参数为 θ \theta θ。
- 第二步,设置一个Loss function,告诉神经网络什么样的策略是好的。
- 第三步,得到最佳策略。
符号
- τ \tau τ:一轮游戏中的具体过程(trajectory), τ = { s 1 , a 1 , r 1 , s 2 , a 2 , r 2 , … , s T , a T , r T } \tau=\{s_1,a_1,r_1,s_2,a_2,r_2,\ldots,s_T,a_T,r_T\} τ={s1,a1,r1,s2,a2,r2,…,sT,aT,rT},是状态-行为-奖赏的时间序列。
- p ( τ ∣ θ ) p(\tau \vert \theta) p(τ∣θ):参数为 θ \theta θ时,采取过程 τ \tau τ的概率。
- τ n \tau^n τn:根据 p ( τ ∣ θ ) p(\tau \vert \theta) p(τ∣θ)采样出来的过程 τ \tau τ,上标 n n n代表是采样第 n n n次的得到的过程。
- R θ R_\theta Rθ:参数为 θ \theta θ时在一轮游戏中的累积奖赏, R θ = ∑ r t R_\theta=\sum r_t Rθ=∑rt。
- R ( τ ) R(\tau) R(τ):游戏过程中所获取的奖赏的总和, R ( τ ) = ∑ t = 1 T r t R(\tau)=\sum_{t=1}^{T} r_t R(τ)=∑t=1Trt
- π θ \pi_\theta πθ:使用参数 θ \theta θ的策略 π \pi π。由于我们采取神经网络,所以实际上策略 π \pi π和参数 θ \theta θ是基本可以看作绑定在一起的。
目标函数 J ( θ ) J(\theta) J(θ)
第一步没什么好说的,输入状态,输出对每一个动作的选取概率,这就是神经网络,至于具体用CNN还是ResNet之类的,看实际情况来决定,我们先来说说Loss function。
损失函数,就是衡量神经网络的输出
y
^
\hat{y}
y^,和最终目标
y
y
y之间的差距大小。但是强化学习并没有那个给定的“最终目标”,他不会告诉你在s状态下采取行为a是最优解,他只会给你这个行为的reward。因此,这里我们使用的不是“损失函数”,而是目标函数
J
(
θ
)
=
R
ˉ
θ
=
E
[
R
θ
]
=
∑
τ
R
(
τ
)
P
(
τ
∣
θ
)
J(\theta)=\bar{R}_\theta=\mathbb{E}[R_\theta]=\sum_\tau R(\tau)P(\tau \vert \theta)
J(θ)=Rˉθ=E[Rθ]=∑τR(τ)P(τ∣θ)。
我们的目标是最大化这个目标函数。
Gradient Ascent
关于gradient decent和gradient ascent的区别比较好理解,梯度下降是为了最小化,而梯度上升是为了最大化,因此我们这里选择梯度上升,从而得到最佳的参数
θ
⋆
\theta^\star
θ⋆:
θ
⋆
=
a
r
g
max
θ
R
ˉ
θ
\theta^\star=arg\max_\theta{\bar{R}_\theta}
θ⋆=argθmaxRˉθ
怎么实现梯度上升呢?很简单:
- 选取一个初始值 θ 0 \theta^0 θ0
- θ 1 ← θ 0 + η ∇ R ˉ θ 0 \theta^1\leftarrow \theta^0+\eta \nabla{\bar{R}_{\theta^0}} θ1←θ0+η∇Rˉθ0
- θ 2 ← θ 1 + η ∇ R ˉ θ 1 \theta^2\leftarrow \theta^1+\eta \nabla{\bar{R}_{\theta^1}} θ2←θ1+η∇Rˉθ1
- … \ldots …
这其中,
∇
R
ˉ
θ
\nabla{\bar{R}_{\theta}}
∇Rˉθ就是
R
ˉ
θ
\bar{R}_{\theta}
Rˉθ的梯度,是一个向量,且向量中每一项是
R
ˉ
θ
\bar{R}_{\theta}
Rˉθ对
θ
i
\theta_i
θi分量的偏微分
∂
R
ˉ
θ
∂
θ
i
\frac{\partial \bar{R}_{\theta}}{\partial \theta_i}
∂θi∂Rˉθ。
但如果直接这样对每一项取偏微分,实际运算压力太大了,因此我们作出转换。
∇
R
ˉ
θ
=
∇
(
∑
τ
R
(
τ
)
P
(
τ
∣
θ
)
)
=
∑
τ
R
(
τ
)
∇
P
(
τ
∣
θ
)
=
∑
τ
R
(
τ
)
P
(
τ
∣
θ
)
∇
P
(
τ
∣
θ
)
P
(
τ
∣
θ
)
=
∑
τ
R
(
τ
)
P
(
τ
∣
θ
)
∇
l
o
g
P
(
τ
∣
θ
)
\begin{aligned} \nabla{\bar{R}_{\theta}}&=\nabla{(\sum_\tau {R(\tau)P(\tau \vert \theta)})}\\ &=\sum_\tau {R(\tau)\nabla P(\tau \vert \theta)}\\ &=\sum_\tau {R(\tau)P(\tau \vert \theta) \frac{\nabla P(\tau \vert \theta)}{P(\tau \vert \theta)}}\\ &=\sum_\tau {R(\tau)P(\tau \vert \theta)\nabla logP(\tau \vert \theta)}\\ \end{aligned}
∇Rˉθ=∇(τ∑R(τ)P(τ∣θ))=τ∑R(τ)∇P(τ∣θ)=τ∑R(τ)P(τ∣θ)P(τ∣θ)∇P(τ∣θ)=τ∑R(τ)P(τ∣θ)∇logP(τ∣θ)
这其中,第二步是由于
R
(
τ
)
R(\tau)
R(τ)与
θ
\theta
θ无关,因此梯度可以移到里面去。而第三步到第四步的转换是简单的高数基础,即对数函数的微分等于其函数的倒数乘上函数内部的微分。又因为有求和符号和概率P,所以可以由概率分布的形式转换成均值的形式,于是我们得到了公式2.1:
∇
R
ˉ
θ
≈
1
N
∑
n
=
1
N
R
(
τ
n
)
∇
l
o
g
P
(
τ
∣
θ
)
(2.1)
\nabla{\bar{R}_{\theta}}\approx \frac{1}{N}\sum_{n=1}^{N} {R(\tau^n)\nabla logP(\tau \vert \theta)}\tag {2.1}
∇Rˉθ≈N1n=1∑NR(τn)∇logP(τ∣θ)(2.1)
那么接下来,我们来看看
∇
l
o
g
P
(
τ
∣
θ
)
\nabla logP(\tau \vert \theta)
∇logP(τ∣θ)等于什么。
由于
τ
=
{
s
1
,
a
1
,
r
1
,
s
2
,
a
2
,
r
2
,
…
,
s
T
,
a
T
,
r
T
}
\tau=\{s_1,a_1,r_1,s_2,a_2,r_2,\ldots,s_T,a_T,r_T\}
τ={s1,a1,r1,s2,a2,r2,…,sT,aT,rT},所以有:
P
(
τ
∣
θ
)
=
p
(
s
1
)
p
(
a
1
∣
s
1
,
θ
)
p
(
r
1
,
s
2
∣
a
1
,
s
1
)
p
(
a
2
∣
s
2
,
θ
)
…
P(\tau \vert \theta)=p(s_1)p(a_1\vert s_1,\theta)p(r_1,s_2\vert a_1,s_1 )p(a_2\vert s_2,\theta)\ldots
P(τ∣θ)=p(s1)p(a1∣s1,θ)p(r1,s2∣a1,s1)p(a2∣s2,θ)…
其中不含
θ
\theta
θ的项都是由环境environment提供的概率,不需要考虑。又因为对于不含
θ
\theta
θ的项作出
l
o
g
log
log(连乘变求和)再偏微分后全部是0,所以有:
∇
l
o
g
P
(
τ
∣
θ
)
=
∑
t
=
1
T
∇
l
o
g
p
(
a
t
∣
s
t
,
θ
)
(2.2)
\nabla logP(\tau \vert \theta)=\sum_{t=1}^T \nabla logp(a_t\vert s_t,\theta) \tag{2.2}
∇logP(τ∣θ)=t=1∑T∇logp(at∣st,θ)(2.2)
结合公式2.1和2.2,我们可以得到公式(约等于符号直接写成等号了):
∇
R
ˉ
θ
=
1
N
∑
n
=
1
N
∑
t
=
1
T
n
R
(
τ
n
)
∇
l
o
g
p
(
a
t
n
∣
s
t
n
,
θ
)
\nabla{\bar{R}_{\theta}}=\frac{1}{N}\sum_{n=1}^{N} \sum_{t=1}^{T_n}{R(\tau^n) \nabla logp(a_t^n\vert s_t^n,\theta)}
∇Rˉθ=N1n=1∑Nt=1∑TnR(τn)∇logp(atn∣stn,θ)
其中,
T
n
T_n
Tn代表第n轮游戏所持续的时间,上标n代表第n轮游戏的a和s。
再次回顾迭代式
θ
n
e
w
←
θ
o
l
d
+
η
∇
R
ˉ
θ
o
l
d
\theta^{new}\leftarrow \theta^{old}+\eta \nabla{\bar{R}_{\theta^{old}}}
θnew←θold+η∇Rˉθold,我们会发现
θ
\theta
θ的优化会使得某轮游戏中的所有行动a在对应状态s下出现的概率提升或降低。这是由于我们式子中的reward是
R
(
τ
n
)
R(\tau^n)
R(τn),是第n轮游戏的整体收益。如果
R
(
τ
n
)
>
0
R(\tau^n)>0
R(τn)>0,那么
p
(
a
t
n
∣
s
t
n
,
θ
)
p(a_t^n\vert s_t^n,\theta)
p(atn∣stn,θ)就会增大;反之就会减小。
这是很直觉也很管用的。假设我们计算的reward不再是一整轮游戏而是某个具体的动作,比如说打飞机游戏可以向左、向右、开火,而learning出来的结果是开火获得了reward,那最后学出来的策略可能就只会开火,而不会左右移动了。
而缺点在于,他增大或降低的是所有行为的概率,因此需要很多的训练量,足够的数据量才能保证训练结果可靠,否则会出现很多不可信的“冗余操作”。实际应用中,就是神经网络要训练很久。
至此为止,Policy Gradient基本就讲完了,下面还有两个可以优化的tip。
Tip1:Add a Baseline
在实际操作过程中,可能会出现所有
R
θ
R_\theta
Rθ都为正的情况,这是根据游戏设计而定的,这就会出现一些问题。
比如说,某游戏一共有三个动作
a
1
,
a
2
,
a
3
a_1,a_2,a_3
a1,a2,a3,并且我们已知在状态s下这三个动作增加的reward的关系是
r
a
1
<
r
a
2
<
r
a
3
r_{a_1}<r_{a_2}<r_{a_3}
ra1<ra2<ra3。如果在数据采样的过程中,这三个动作都采样到了,那当然没关系,三个动作的p都会提升,且
a
3
a_3
a3提升的幅度最大,从而导致其他两个动作的概率相应减小;但假设
a
3
a_3
a3没有采样到,
a
1
,
a
2
a_1,a_2
a1,a2采样到了,那么
a
1
,
a
2
a_1,a_2
a1,a2的概率必然提升(因为
R
θ
R_\theta
Rθ总为正),而
a
3
a_3
a3的概率必然下降。
因此,我们希望保证
R
θ
R_\theta
Rθ能有正有负,所以公式变为:
∇
R
ˉ
θ
=
1
N
∑
n
=
1
N
∑
t
=
1
T
n
(
R
(
τ
n
)
−
b
)
∇
l
o
g
p
(
a
t
n
∣
s
t
n
,
θ
)
\nabla{\bar{R}_{\theta}}=\frac{1}{N}\sum_{n=1}^{N} \sum_{t=1}^{T_n}{(R(\tau^n)-b) \nabla logp(a_t^n\vert s_t^n,\theta)}
∇Rˉθ=N1n=1∑Nt=1∑Tn(R(τn)−b)∇logp(atn∣stn,θ)
其中,b就是baseline,
b
≈
E
[
R
(
τ
n
)
]
b\approx \mathbb{E}[R(\tau^n)]
b≈E[R(τn)]。
Tip2:Assign Suitable Credit
之前也说过了,我们是根据一整轮游戏的结果来对所有
τ
\tau
τ上的行为,而非针对行为a本身。这是不公平的,显然。有可能有一些行为是好的,但是其他行为是差的,从而导致了不好的结果。虽然经过大数量的采样可以基本保证好的行为得到正的奖赏,但我们可以考虑直接对行为进行奖赏或惩罚。
怎么做呢?想法也很简单。我们不再考虑整盘游戏的
R
(
τ
n
)
R(\tau^n)
R(τn),而是从行为所在的时间点开始的累积奖赏
∑
t
′
=
t
T
n
r
t
′
n
\sum_{t'=t}^{T_n}r_{t'}^n
∑t′=tTnrt′n。又考虑到未来的奖赏受此时行为的影响较小,我们考虑添加一个折扣参数
γ
\gamma
γ,于是改为
∑
t
′
=
t
T
n
γ
t
′
−
t
r
t
′
n
\sum_{t'=t}^{T_n}\gamma^{t'-t} r_{t'}^n
∑t′=tTnγt′−trt′n,这里
γ
\gamma
γ上的
(
t
′
−
t
)
(t'-t)
(t′−t)不是上标,而是幂次数。当然了,
γ
<
1
\gamma<1
γ<1。
于是我们得到公式:
∇
R
ˉ
θ
=
1
N
∑
n
=
1
N
∑
t
=
1
T
n
(
∑
t
′
=
t
T
n
γ
t
′
−
t
r
t
′
n
−
b
)
∇
l
o
g
p
(
a
t
n
∣
s
t
n
,
θ
)
\nabla{\bar{R}_{\theta}}=\frac{1}{N}\sum_{n=1}^{N} \sum_{t=1}^{T_n}{(\sum_{t'=t}^{T_n}\gamma^{t'-t} r_{t'}^n-b) \nabla logp(a_t^n\vert s_t^n,\theta)}
∇Rˉθ=N1n=1∑Nt=1∑Tn(t′=t∑Tnγt′−trt′n−b)∇logp(atn∣stn,θ)
这样看起来太冗长了。我们定义优势函数
A
θ
(
s
t
,
a
t
)
=
∑
t
′
=
t
T
n
γ
t
′
−
t
r
t
′
n
−
b
A^\theta (s_t,a_t)=\sum_{t'=t}^{T_n}\gamma^{t'-t} r_{t'}^n-b
Aθ(st,at)=∑t′=tTnγt′−trt′n−b,上标
θ
\theta
θ表示我们是用
π
θ
\pi_\theta
πθ的策略模型来对环境做出互动。
所以,最终公式为:
∇
R
ˉ
θ
=
1
N
∑
n
=
1
N
∑
t
=
1
T
n
A
θ
(
s
t
,
a
t
)
∇
l
o
g
p
(
a
t
n
∣
s
t
n
,
θ
)
(2.3)
\nabla{\bar{R}_{\theta}}=\frac{1}{N}\sum_{n=1}^{N} \sum_{t=1}^{T_n}{A^\theta (s_t,a_t) \nabla logp(a_t^n\vert s_t^n,\theta)} \tag{2.3}
∇Rˉθ=N1n=1∑Nt=1∑TnAθ(st,at)∇logp(atn∣stn,θ)(2.3)
总结
策略梯度的目的就是最大化
R
θ
R_\theta
Rθ的期望值,常用的方法是采用神经网络,以梯度上升的方式来进行优化。
策略梯度的缺点在于每一次参数更新完都要重新用更新完的模型去采样,然后再次更新,非常慢。有关这一点的优化我们会在之后进行讨论。