介绍
Easy RL是由清华大学、北京大学以及中国科学院大学的三名硕士生编写的一门强化学习入门书籍,又称为“蘑菇书”Easy RL github地址。笔者主要从事博弈论、多智能体强化学习等方面的研究。最近在学习该本书,故将学习笔记和心得在这里记录下来,供大家观看交流。之后笔者也会继续更新有关多智能体和强化学习的内容,包括强化学习算法原理和代码实现、论文复现、强化学习竞赛等,对文章内容有任何问题或想一起学习强化学习相关内容可以邮件联系。(lllzesheng@163.com)
四、策略梯度
- 表格型方法和基于策略的方法不同之处在于:表格型方法在一个状态下,输出所有动作的对应的价值;而基于策略的方法则在一个状态下,输出动作空间上的一个概率分布。
- 基于策略的方法的基本思想就是将策略参数化,借助参数的梯度信息来最优化策略对应的目标函数。
1、策略梯度算法PG
将策略
π
\pi
π参数化为
π
θ
\pi_{\theta}
πθ,并假设在该策略下,强化学习过程中出现的一条轨迹
τ
\tau
τ为:
τ
=
(
s
1
,
a
1
,
s
2
,
a
2
,
.
.
.
s
t
,
a
t
)
\tau=(s_1,a_1,s_2,a_2,...s_t,a_t)
τ=(s1,a1,s2,a2,...st,at)
在强化学习过程中,该轨迹会带来一个回报
R
(
τ
)
R(\tau)
R(τ).(PS:可能是回合结束后获得的回报,也可能是在轨迹中的每一步的奖赏的累积值)。
上述轨迹出现的概率为:
π
θ
(
τ
)
=
p
(
s
1
)
π
θ
(
a
1
∣
s
1
)
p
(
s
2
∣
s
1
,
a
n
1
)
π
θ
(
a
2
∣
s
2
)
.
.
.
p
(
s
t
∣
s
n
−
1
,
a
n
−
1
)
π
θ
(
a
n
∣
s
n
)
\pi_{\theta}(\tau)=p(s_1)\pi_{\theta}(a_1|s1)p(s_2|s_1,a_n1)\pi_{\theta}(a_2|s_2)...p(s_t|s_{n-1},a_{n-1})\pi_{\theta}(a_n|s_n)
πθ(τ)=p(s1)πθ(a1∣s1)p(s2∣s1,an1)πθ(a2∣s2)...p(st∣sn−1,an−1)πθ(an∣sn)
其中,p表示状态转移概率函数。则该策略对应的期望回报为:
R
θ
=
E
τ
∼
π
θ
(
τ
)
R
(
τ
)
R_{\theta}=E_{\tau\sim\pi_{\theta}(\tau)}R(\tau)
Rθ=Eτ∼πθ(τ)R(τ)
上式表明,当前的策略
τ
\tau
τ下,可能产生多条轨迹。假设
π
θ
(
τ
)
\pi_{\theta}(\tau)
πθ(τ)是关于所有轨迹的一个概率分布,则上式就是该策略对应的期望回报。实际上在进行计算时,可以用采样的方式近似计算该期望回报,即:
R
θ
=
∑
k
=
1
T
π
θ
(
τ
k
)
R
(
τ
k
)
R_{\theta}=\sum_{k=1}^T\pi_{\theta}(\tau^k)R(\tau^k)
Rθ=k=1∑Tπθ(τk)R(τk)
基于策略的强化学习算法的思想就是,找到最优的参数
θ
\theta
θ,使得在该参数化策略下,获得的期望回报最大。因此上式可以作为目标函数,关于参数
θ
\theta
θ对该目标函数求梯度,有:
∇
R
θ
=
∑
k
=
1
T
∇
π
θ
(
τ
k
)
R
(
τ
k
)
\nabla R_{\theta}=\sum_{k=1}^T\nabla\pi_{\theta}(\tau^k)R(\tau^k)
∇Rθ=k=1∑T∇πθ(τk)R(τk)
根据公式
∇
f
(
x
)
=
f
(
x
)
∇
l
o
g
(
f
(
x
)
)
\nabla f(x)=f(x)\nabla log(f(x))
∇f(x)=f(x)∇log(f(x)),可对上式进行推导
∇
R
θ
=
∑
k
=
1
T
∇
π
θ
(
τ
k
)
R
(
τ
k
)
=
∑
k
=
1
T
π
θ
(
τ
k
)
∇
l
o
g
(
π
θ
(
τ
k
)
)
R
(
τ
k
)
=
∑
k
=
1
T
π
θ
(
τ
k
)
∇
(
l
o
g
(
p
(
s
1
k
p
(
s
2
k
∣
s
1
k
,
a
1
k
)
.
.
.
p
(
s
t
k
∣
s
n
−
1
k
,
a
n
−
1
k
)
)
)
+
l
o
g
(
(
π
θ
(
a
1
k
∣
s
1
k
)
π
θ
(
a
2
k
∣
s
2
k
)
.
.
.
π
θ
(
a
n
k
∣
s
n
k
)
)
)
)
R
(
τ
k
)
=
∑
k
=
1
T
π
θ
(
τ
k
)
∇
∑
t
=
1
n
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
R
(
τ
k
)
=
∑
k
=
1
T
∑
t
=
1
n
π
θ
(
τ
k
)
∇
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
R
(
τ
k
)
\nabla R_{\theta}=\sum_{k=1}^T\nabla\pi_{\theta}(\tau^k)R(\tau^k)=\sum_{k=1}^T\pi_{\theta}(\tau^k)\nabla log(\pi_{\theta}(\tau^k))R(\tau^k)\\ =\sum_{k=1}^T\pi_{\theta}(\tau^k)\nabla(log(p(s^k_1p(s^k_2|s^k_1,a^k_1)...p(s^k_t|s^k_{n-1},a^k_{n-1})))+\\log((\pi_{\theta}(a^k_1|s^k_1)\pi_{\theta}(a^k_2|s^k_2)...\pi_{\theta}(a^k_n|s^k_n))))R(\tau^k)\\ =\sum_{k=1}^T\pi_{\theta}(\tau^k)\nabla \sum_{t=1}^n log \pi_{\theta}(a_t^k|s_t^k)R(\tau^k)\\=\sum_{k=1}^T\sum_{t=1}^n \pi_{\theta}(\tau^k) \nabla log \pi_{\theta}(a_t^k|s_t^k)R(\tau^k)
∇Rθ=k=1∑T∇πθ(τk)R(τk)=k=1∑Tπθ(τk)∇log(πθ(τk))R(τk)=k=1∑Tπθ(τk)∇(log(p(s1kp(s2k∣s1k,a1k)...p(stk∣sn−1k,an−1k)))+log((πθ(a1k∣s1k)πθ(a2k∣s2k)...πθ(ank∣snk))))R(τk)=k=1∑Tπθ(τk)∇t=1∑nlogπθ(atk∣stk)R(τk)=k=1∑Tt=1∑nπθ(τk)∇logπθ(atk∣stk)R(τk)
最终可以得到:
∇
R
θ
=
∑
k
=
1
T
∑
t
=
1
n
π
θ
(
τ
k
)
∇
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
R
(
τ
k
)
\nabla R_{\theta}=\sum_{k=1}^T\sum_{t=1}^n \pi_{\theta}(\tau^k) \nabla log \pi_{\theta}(a_t^k|s_t^k)R(\tau^k)
∇Rθ=k=1∑Tt=1∑nπθ(τk)∇logπθ(atk∣stk)R(τk)
在上上式中,可以看出
π
θ
(
τ
k
)
\pi_{\theta}(\tau^k)
πθ(τk)相当于一个概率分布,因此上式还可以记作:
∇
R
θ
=
E
τ
k
∼
π
θ
(
τ
k
)
∑
t
=
1
n
∇
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
R
(
τ
k
)
=
E
τ
k
∼
π
θ
(
τ
k
)
∇
l
o
g
π
θ
(
τ
k
)
R
(
τ
k
)
\nabla R_{\theta}=E_{\tau_k \sim \pi_{\theta}(\tau^k)} \sum_{t=1}^n \nabla log \pi_{\theta}(a_t^k|s_t^k)R(\tau^k)=E_{\tau_k \sim \pi_{\theta}(\tau^k)} \nabla log\pi_{\theta}(\tau^k) R(\tau^k)
∇Rθ=Eτk∼πθ(τk)t=1∑n∇logπθ(atk∣stk)R(τk)=Eτk∼πθ(τk)∇logπθ(τk)R(τk)
如果假设采样每条轨迹的概率相等,则有:
∇
R
θ
≈
1
N
∑
k
=
1
T
∑
t
=
1
n
∇
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
R
(
τ
k
)
\nabla R_{\theta}\approx \frac 1N \sum_{k=1}^T\sum_{t=1}^n \nabla log \pi_{\theta}(a_t^k|s_t^k)R(\tau^k)
∇Rθ≈N1k=1∑Tt=1∑n∇logπθ(atk∣stk)R(τk)
在上式中,可以直观地看出一个思想:
首先,我们的最终目的是使得R最大化。对于一条轨迹 τ \tau τ,如果其奖赏 R ( τ ) R(\tau) R(τ)是正的,那么奖赏R会随着其中在该轨迹下的状态 s t s_t st采取 a t a_t at的概率 π θ ( a t k ∣ s t k ) \pi_{\theta}(a_t^k|s_t^k) πθ(atk∣stk)呈现正相关变化,故此时优化的目标应该是增大在这些状态先出现对应动作的概率。
,若奖赏为负,那么R随着上述概率呈现负相关变化,那么此时应该减少上述概率,从而使得R更大。
2、PG的参数优化过程
借助上述思想,参数
θ
\theta
θ的优化方式为:
θ
=
θ
+
η
∇
R
θ
∇
R
θ
≈
1
N
∑
k
=
1
T
∑
t
=
1
n
∇
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
R
(
τ
k
)
\theta=\theta+\eta\nabla R_{\theta}\\\nabla R_{\theta}\approx \frac 1N \sum_{k=1}^T\sum_{t=1}^n \nabla log \pi_{\theta}(a_t^k|s_t^k)R(\tau^k)
θ=θ+η∇Rθ∇Rθ≈N1k=1∑Tt=1∑n∇logπθ(atk∣stk)R(τk)
由上图可知,策略梯度的大致步骤为:
- 智能体借助策略 π θ \pi_{\theta} πθ与环境互动,得到若干条轨迹。其中,包含每条轨迹下的状态动作对,以及轨迹结束时获得的奖赏。
- 借助采样得到的数据,计算上式定义的梯度,更新参数 θ \theta θ,从而得到新的策略。
- 舍弃之前采样的数据,用新的策略重新采样,并进行参数更新。
不难看出,策略梯度是一种在线学习方法。(改进的和与环境互动的策略是一种)
PS:pytorch实现PG细节(以分类问题的角度看强化学习)
考虑图片分类问题,对于每一张输入的图片,输入神经网络后,都会输出一个关于类别空间上的概率分布。在训练过程中,训练集中有关于该图片的真实类别,可以将其也看作一个概率分布(即该类别对应概率为0,其他类别对应的概率为1),将真实概率分布于输出的概率分布之间的交叉熵(Cross Entropy)作为损失函数,通过优化方法使得输出的类别分布与真实类别更接近。
交叉熵: − ∑ i p ( x i ) l o g ( q ( x i ) ) -\sum_i p(x_i)log(q(x_i)) −∑ip(xi)log(q(xi)),可以衡量两个分布的相似性.
首先将强化学习问题看作分类问题,若假设认为在某个状态
s
t
s_t
st下得到的真实动作
a
t
a_t
at就是我们需要学习的目标,那此时强化学习问题也就变成了分类问题。使用最大化似然估计的思想设计目标函数:(最小化交叉熵和最大化似然估计是等价的)
1
N
∑
k
=
1
T
∑
t
=
1
n
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
\frac 1N \sum_{k=1}^T\sum_{t=1}^n log \pi_{\theta}(a_t^k|s_t^k)
N1k=1∑Tt=1∑nlogπθ(atk∣stk)
而事实上,与分类任务不同,强化学习的任务是学习最优动作。然而在某个状态
s
t
s_t
st下得到的真实动作
a
t
a_t
at并不一定是最优的动作,因此有了强化学习中的目标函数:
R
θ
≈
1
N
∑
k
=
1
T
∑
t
=
1
n
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
R
(
τ
k
)
R_{\theta}\approx \frac 1N \sum_{k=1}^T\sum_{t=1}^n log \pi_{\theta}(a_t^k|s_t^k)R(\tau^k)
Rθ≈N1k=1∑Tt=1∑nlogπθ(atk∣stk)R(τk)
与前面的目标函数唯一不同之处在于,这里对于每一个状态动作对样本,都乘上了一个权重。这意味着,如果这个动作比较好,则应该增大其出现的概率(就像分类问题一样),但如果这个动作不太好,则应该减少其出现的概率。
上面的过程是为了说明:在编程实现PG时,可以借助分类问题的思想计算出交叉熵,并乘上一个权重,以此作为目标函数并通过训练求解出最优参数。
3、策略梯度算法的两个小技巧
上述算法的更新过程主要有以下两个问题:
1、同一条轨迹下的所有状态动作对都使用该轨迹结束之后获得的奖赏,而事实上这些选择(在某个状态下选取某个动作)有好有坏,不应该同一而论。
2、由于奖赏函数的设计方式不同,有可能出现奖赏恒正或者恒负的情况,那此时对每种状态-动作对,都要增大其概率。但总的概率是1,进行归一化后将导致奖赏较小的动作其概率会下降。(但事实上我们希望只要是正奖赏就可以增加该动作对应的概率)
**Tips1:**针对第一个问题,解决的办法是为每个状态-动作对分配不同的奖赏,该奖赏不再是一个回合的最终奖赏,而是在该状态下采取相应动作以后获取的累积折扣奖赏,即
∑
t
′
=
t
T
γ
t
′
−
t
r
t
′
n
{\sum}^T_{t'=t}\gamma^{t'-t}r_{t'}^n
∑t′=tTγt′−trt′n
**Tips2:**针对第二个问题,可以通过添加一个基线来解决此问题,即:
∑
t
′
=
t
T
γ
t
′
−
t
r
t
′
n
−
b
{\sum}^T_{t'=t}\gamma^{t'-t}r_{t'}^n-b
∑t′=tTγt′−trt′n−b
通过添加基线,可以避免奖赏函数恒正或者恒负的问题。其中,b表示在该状态下未来的期望奖赏,可以取多条轨迹回报的均值,也可以用一个网络来估算。
基于上面两个技巧,最终PG算法的期望奖赏函数的梯度为:
∇
R
θ
≈
1
N
∑
k
=
1
T
∑
t
=
1
n
∇
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
(
∑
t
′
=
t
T
γ
t
′
−
t
r
t
′
n
−
b
)
\nabla R_{\theta}\approx \frac 1N \sum_{k=1}^T\sum_{t=1}^n \nabla log \pi_{\theta}(a_t^k|s_t^k)({\sum}^T_{t'=t}\gamma^{t'-t}r_{t'}^n-b)
∇Rθ≈N1k=1∑Tt=1∑n∇logπθ(atk∣stk)(∑t′=tTγt′−trt′n−b)
其中,R-b这一项称为优势函数,用
A
θ
(
s
t
,
a
t
)
A^{\theta}(s_t,a_t)
Aθ(st,at)来表示。(类似于表格型方法中的Q函数),
A
θ
(
s
t
,
a
t
)
A^{\theta}(s_t,a_t)
Aθ(st,at)通常可以用一个网络来估计处理,该网络通常称为Critic网络。
4、蒙特卡洛策略梯度REINFORCE
上述策略梯度方法,根据计算优势函数的不同,可以分为蒙特卡洛策略梯度方法(基于蒙特卡洛方法)以及演员-评论家方法Actor-Critic(基于时序差分)。
REINFORCE方法就是借助蒙特卡洛方法随机采样,只有采样得到完整的一组轨迹之后才可以根据上面的公式进行策略的更新(回合更新机制)。其优势函数为Gt,即在状态
s
t
s_t
st下采取动作
a
t
a_t
at之后获得的折扣累积回报。(这里完全可以类比于MC-Q-learning)该算法的步骤如下:
PS:注意这里虽然是对回合中的每一步都完成一次更新,但也只有等回合结束之后才能回过头来更新(不然无法计算Gt)。
结合上面说的将该问题类比于分类问题的说法,编程实现REINFORCE算法时还可以基于以下思想:
其中损失可以表示为交叉熵(即真实采取动作的独热编码乘以网络输出的对数动作概率分布)再乘上一个权重(奖赏)。
5、优势演员-评论家算法A2C
当策略梯度与时序差分的思想相结合时,就可以得到Actor-Critic算法。
Actor-Critic算法是典型的同时基于策略和基于值的方法。当不采用异步机制时(异步机制下的AC算法称为A3C),AC算法常成为优势演员-评论员算法(A2C)。其相比于PG或者REINFORCE算法,主要的改进点在于:
- REINFORCE算法借助真实的Gt来作为优势函数的一部分,以此更新策略参数,但事实上,在采样过程中得到的Gt具有很大的不确定性,方差较大。对此,AC算法的思想是借助一个神经网络来拟合Gt,使其更准确。
基于上述思想,事实上,Gt表示在状态st下采取动作at的累积奖赏,其期望就是Q函数。因此完全可以用Q函数来代替Gt,并且考虑到PG算法中基线b的作用是让优势函数有正有负,可以用V函数来代替b。这是因为,V函数是Q函数的期望(V函数表示在该状态下的价值,而Q函数表示在该状态下采取某个动作的价值,而采取的动作可能有多种),基于此,用Q-V代替PG算法中的Gt-b是合理的,因此AC算法有以下的结构:
∇
R
θ
≈
1
N
∑
k
=
1
T
∑
t
=
1
n
∇
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
(
Q
π
θ
(
s
t
k
,
a
t
k
)
−
V
π
θ
(
s
t
k
)
)
\nabla R_{\theta}\approx \frac 1N \sum_{k=1}^T\sum_{t=1}^n \nabla log \pi_{\theta}(a_t^k|s_t^k)(Q_{\pi_\theta}(s_t^k,a_t^k)-V_{\pi_\theta}(s_t^k))
∇Rθ≈N1k=1∑Tt=1∑n∇logπθ(atk∣stk)(Qπθ(stk,atk)−Vπθ(stk))
但上述方法有一个缺点,就是需要同时用两个网络分别估计Q和V,这将会导致估计不准的风险大大增加。因此,可以值估计V函数,而Q函数可以表示为:
Q
π
θ
(
s
t
k
,
a
t
k
)
=
E
[
r
t
k
+
V
π
θ
(
s
t
+
1
k
)
]
Q_{\pi_\theta}(s_t^k,a_t^k)=E[r_t^k+V_{\pi_\theta}(s_{t+1}^k)]
Qπθ(stk,atk)=E[rtk+Vπθ(st+1k)]
由于无法真正计算其期望,可以直接用以下方式来估计Q:
Q
π
θ
(
s
t
k
,
a
t
k
)
=
r
t
k
+
V
π
θ
(
s
t
+
1
k
)
Q_{\pi_\theta}(s_t^k,a_t^k)=r_t^k+V_{\pi_\theta}(s_{t+1}^k)
Qπθ(stk,atk)=rtk+Vπθ(st+1k)
由此一来,则只需要估计V函数即可。此时优势函数实际上也变成了关于V函数的时序误差:
Q
π
θ
(
s
t
k
,
a
t
k
)
−
V
π
θ
(
s
t
k
)
=
r
t
k
+
V
π
θ
(
s
t
+
1
k
)
−
V
π
θ
(
s
t
k
)
Q_{\pi_\theta}(s_t^k,a_t^k)-V_{\pi_\theta}(s_t^k)=r_t^k+V_{\pi_\theta}(s_{t+1}^k)-V_{\pi_\theta}(s_t^k)
Qπθ(stk,atk)−Vπθ(stk)=rtk+Vπθ(st+1k)−Vπθ(stk)
对应的模型为:
∇
R
θ
≈
1
N
∑
k
=
1
T
∑
t
=
1
n
∇
l
o
g
π
θ
(
a
t
k
∣
s
t
k
)
(
r
t
k
+
V
π
θ
(
s
t
+
1
k
)
−
V
π
θ
(
s
t
k
)
)
\nabla R_{\theta}\approx \frac 1N \sum_{k=1}^T\sum_{t=1}^n \nabla log \pi_{\theta}(a_t^k|s_t^k)(r_t^k+V_{\pi_\theta}(s_{t+1}^k)-V_{\pi_\theta}(s_t^k))
∇Rθ≈N1k=1∑Tt=1∑n∇logπθ(atk∣stk)(rtk+Vπθ(st+1k)−Vπθ(stk))
PS:尽管上式中的优势函数是根据原本的回报值减去基线推来的,但实际上它本身还有另外的解释,即此时的优势函数(前面说了很多次优势函数,优势函数真正的意思可以理解当目前的状态-动作对相对于其他状态-动作对的优势,优势大的就更值得增加其出现概率)为关于V函数的时序误差,而时序误差越大的,代表其给智能体带来的“惊喜”越多,那么再之后应该更加关注这样的状态-动作对。
A2C的运作流程如下:
在图中可以看出,A2C大致步骤为:
- 首先根据一个初始策略进行采样,得到部分数据。
- 其次,与REINFORCE算法不同,A2C借助这些数据估计状态值函数 V π ( s ) V_\pi(s) Vπ(s)。
- 基于 V π ( s ) V_\pi(s) Vπ(s)的时序误差可以得到优势函数,基于PG的思想更新参数。
- 用更新的参数与环境交互,重新采样,重复进行上述步骤。