【学习强化学习】九、Actor-Critic算法原理及实现
文章目录参考资料1. Actor-Critic框架原理1.1 基本介绍1.2 原理分析1.3 Advantage Actor-Critic1. A2C引入2. A2C流程3. tips2. A3C2.1 A3C理解2.2 A3C运作机理2.3 算法大纲3. Pathwise Derivative Policy Gradient3.1 算法流程3.2算法相对于DQN的改变4. 练习1. A3C在训练
参考资料
代码实现见github仓库
1. Actor-Critic框架原理
1.1 基本介绍
在 REINFORCE 算法中,每次需要根据一个策略采集一条完整的轨迹,并计算这条轨迹上的回报。这种采样方式的方差比较大,学习效率也比较低。我们可以借鉴时序差分学习的思想,使用动态规划方法来提高采样的效率,即从状态 s 开始的总回报可以通过当前动作的即时奖励 r(s,a,s’) 和下一个状态 s′ 的值函数来近似估计。
演员-评论家算法(Actor-Critic Algorithm)是一种结合策略梯度和时序差分学习的强化学习方法,其中:
- 演员(Actor)是指策略函数 π θ ( a ∣ s ) \pi_{\theta}(a|s) πθ(a∣s),即学习一个策略来得到尽量高的回报。
- 评论家(Critic)是指值函数 V π ( s ) V^{\pi}(s) Vπ(s),对当前策略的值函数进行估计,即评估演员的好坏。
- 借助于值函数,演员-评论家算法可以进行单步更新参数,不需要等到回合结束才进行更新。
1.2 原理分析
-
如图,随机变量 G 的期望值是 Q ,即
E [ G t n ] = Q π θ ( s t n , a t n ) E\left[G_{t}^{n}\right]=Q^{\pi_{\theta}} \left(s_{t}^{n}, a_{t}^{n}\right) E[Gtn]=Qπθ(stn,atn)
因为这个就是 Q 的定义。Q-function 的定义就是在某一个状态 s,采取某一个动作 a,假设 policy 就是 π \pi π 的情况下会得到的累积奖励的期望值有多大,所以就是 G 的期望值。
所以假设用 E [ G t n ] E\left[G_{t}^{n}\right] E[Gtn] 来代表 ∑ t ′ = t T n γ t ′ − t r t ′ n \sum_{t^{\prime}=t}^{T_{n}} \gamma^{t^{\prime}-t} r_{t^{\prime}}^{n} ∑t′=tTnγt′−trt′n 这一项的话,把 Q-function 套在这里就结束了,我们就可以把 Actor 跟 Critic 这两个方法结合起来。 -
baseline可以用不同方法表示,一个常见的做法是用价值函数 V π θ ( s t n ) V^{\pi_{\theta}}\left(s_{t}^{n}\right) Vπθ(stn) 来表示 baseline。价值函数是说:假设 policy 是 π \pi π,在某一个状态 s 一直互动到游戏结束,期望奖励(expected reward)有多大。
-
其实 V π θ ( s t n ) V^{\pi_{\theta}}\left(s_{t}^{n}\right) Vπθ(stn)是 Q π θ ( s t n , a t n ) Q^{\pi_{\theta}}\left(s_{t}^{n}, a_{t}^{n}\right) Qπθ(stn,atn) 的期望值,所以 Q π θ ( s t n , a t n ) − V π θ ( s t n ) Q^{\pi_{\theta}}\left(s_{t}^{n}, a_{t}^{n}\right)-V^{\pi_{\theta}}\left(s_{t}^{n}\right) Qπθ(stn,atn)−Vπθ(stn)有正有负,所以 ∑ t ′ = t T n γ t ′ − t r t ′ n − b \sum_{t^{\prime}=t}^{T_{n}} \gamma^{t^{\prime}-t} r_{t^{\prime}}^{n}-b ∑t′=tTnγt′−trt′n−b这一项有正有负。
1.3 Advantage Actor-Critic
1. A2C引入
如上图所示,如果这么实现的话,就要估计 2 个 网络:Q-network 和 V-network,估测不准的风险就变成两倍。
事实上在这个 Actor-Critic 方法里面。可以只估测 V 网络,然后用 V 的值来表示 Q 的值,
Q
π
(
s
t
n
,
a
t
n
)
Q^{\pi}\left(s_{t}^{n}, a_{t}^{n}\right)
Qπ(stn,atn)可以写成
r
t
n
+
V
π
(
s
t
+
1
n
)
r_{t}^{n}+V^{\pi}\left(s_{t+1}^{n}\right)
rtn+Vπ(st+1n) 的期望值,即
Q
π
(
s
t
n
,
a
t
n
)
=
E
[
r
t
n
+
V
π
(
s
t
+
1
n
)
]
Q^{\pi}\left(s_{t}^{n}, a_{t}^{n}\right)=E\left[r_{t}^{n}+V^{\pi}\left(s_{t+1}^{n}\right)\right]
Qπ(stn,atn)=E[rtn+Vπ(st+1n)]
你在状态 s 采取动作 a,会得到奖励 r,然后跳到状态
s
t
+
1
s_{t+1}
st+1。但是你会得到什么样的奖励 r,跳到什么样的状态
s
t
+
1
s_{t+1}
st+1,它本身是有随机性的。所以要把右边这个式子,取期望值它才会等于 Q-function。但我们现在把期望值去掉,即
Q
π
(
s
t
n
,
a
t
n
)
=
r
t
n
+
V
π
(
s
t
+
1
n
)
Q^{\pi}\left(s_{t}^{n}, a_{t}^{n}\right)=r_{t}^{n}+V^{\pi}\left(s_{t+1}^{n}\right)
Qπ(stn,atn)=rtn+Vπ(st+1n)
我们就可以把 Q-function 用 r + V 取代,然后得到下式:
r
t
n
+
V
π
(
s
t
+
1
n
)
−
V
π
(
s
t
n
)
r_{t}^{n}+V^{\pi}\left(s_{t+1}^{n}\right)-V^{\pi}\left(s_{t}^{n}\right)
rtn+Vπ(st+1n)−Vπ(stn)
把这个期望值去掉的好处就是不需要估计 Q 了,只需要估计 V 就够了。但这样就引入了一个 r ,它是一个随机变量。但是这个随机变量,相较于累积奖励 G 可能还好,因为它是某一个步骤会得到的奖励,而 G 是所有未来会得到的奖励的总和。G 的方差比较大,r 虽然也有一些方差,但它的方差会比 G 要小。所以把原来方差比较大的 G 换成方差比较小的 r 也是合理的。
因为
r
t
n
+
V
π
(
s
t
+
1
n
)
−
V
π
(
s
t
n
)
r_{t}^{n}+V^{\pi}\left(s_{t+1}^{n}\right)-V^{\pi}\left(s_{t}^{n}\right)
rtn+Vπ(st+1n)−Vπ(stn) 叫做 Advantage function
。所以这整个方法就叫 Advantage Actor-Critic
。
2. A2C流程
整个流程是这样的。
-
初始的 actor 去跟环境做互动收集数据。在 policy gradient 方法里面收集数据以后,就要拿去更新 policy。但是在 actor-critic 方法里面,不是直接拿数据去更新 policy,而是先拿这些数据去估计价值函数,这边可以用 TD 或 MC 来估计价值函数 。接下来,再基于价值函数,套用下面这个式子去更新 π \pi π。
∇ R ˉ θ ≈ 1 N ∑ n = 1 N ∑ t = 1 T n ( r t n + V π ( s t + 1 n ) − V π ( s t n ) ) ∇ log p θ ( a t n ∣ s t n ) \nabla \bar{R}_{\theta} \approx \frac{1}{N} \sum_{n=1}^{N} \sum_{t=1}^{T_{n}}\left(r_{t}^{n}+V^{\pi}\left(s_{t+1}^{n}\right)-V^{\pi}\left(s_{t}^{n}\right)\right) \nabla \log p_{\theta}\left(a_{t}^{n} \mid s_{t}^{n}\right) ∇Rˉθ≈N1n=1∑Nt=1∑Tn(rtn+Vπ(st+1n)−Vπ(stn))∇logpθ(atn∣stn) -
有了新的 π \pi π 后,再跟环境互动,收集新的数据,去估计价值函数。然后再用新的价值函数 去更新 actor。
3. tips
实现 Actor-Critic 的时候,有两个一定会用的 tip。
-
第一个 tip ,由于我们需要估计两个网络:V function 和 policy 的网络(也就是 actor)。
- Critic 网络 V π ( s ) V^\pi(s) Vπ(s) 输入一个状态,输出一个标量。
- Actor 网络
π
(
s
)
\pi(s)
π(s) 输入一个状态,
如果动作是离散的,输出就是一个动作的分布。
如果动作是连续的,输出就是一个连续的向量。
这两个网络,actor 和 critic 的输入都是 s,所以它们前面几个层(layer),其实是可以共享的。
-
第二个 tip ,是我们需要探索(exploration)的机制。在做 Actor-Critic 的时候,有一个常见的探索的方法是对 π \pi π 的输出的分布做一个约束。这个约束是希望这个分布的熵(entropy)不要太小,希望这个分布的熵可以大一点,也就是希望不同的动作它被采用的概率平均一点。这样在测试的时候,它才会多尝试各种不同的动作,才会把这个环境探索的比较好,才会得到比较好的结果。
2. A3C
2.1 A3C理解
强化学习有一个问题就是训练很慢,那怎么增加训练的速度呢?由此引出了Asynchronous(异步的) Advantage Actor-Critic,也就是 A3C。
A3C 这个方法就是同时开很多个 worker,这些worker 会把所有的经验,通通集合在一起。如果电脑没有很多个 CPU,可能也是不好实现的。
2.2 A3C运作机理
-
A3C 一开始有一个 global network,它包含 policy 的部分和 value 的部分。 policy network 跟 value network 是绑在一起的,它们的前几个层是共享的。
-
假设 global network 的参数是 θ 1 \theta_1 θ1,你会开很多个 worker。每一个 worker 就用一张 CPU 去跑。比如开 8 个 worker,那至少需要 8 张 CPU。每一个 worker 工作前都会把 global network 的参数复制过来。
-
接下来跟环境做互动,每一个 actor 去跟环境做互动的时候,要收集到比较多样性的数据。
-
每一个 actor 跟环境互动完之后,计算梯度。计算出梯度以后,拿梯度去更新 global network 的参数。也就是这个 worker 算出梯度以后,把梯度传回给中央的控制中心,然后中央的控制中心就会拿这个梯度去更新原来的参数。
-
注意,所有的 actor 都是平行跑的,每一个 actor 就是各做各的,不管彼此。所以每个人都是去要了一个参数以后,做完就把参数传回去。所以当第一个 worker 做完想要把参数传回去的时候,本来它要的参数是 θ 1 \theta_1 θ1,等它要把梯度传回去的时候。可能别人已经把原来的参数覆盖掉,变成 θ 2 \theta_2 θ2了。但是没有关系,它一样会把这个梯度覆盖过去就是了。这就是
Asynchronous actor-critic
的运行方式。
2.3 算法大纲
3. Pathwise Derivative Policy Gradient
这部分可参考伯克利课件
这个方法可以看成是DQN 解连续动作的一种特别的方法,也可以看成是一种特别的 Actor-Critic 的方法。Pathwise Derivative Policy Gradient
中的 critic会直接告诉 actor 做什么样的动作才可以得到比较大的 value。
假设我们学习了一个 Q-function,那接下来,我们要学习一个 actor,这个 actor 的工作是解这个 arg max 的问题。这个 actor 的工作就是输入一个状态 s,希望可以输出一个动作 a。这个动作 a 被丢到 Q-function 以后,可以让 Q π ( s , a ) Q^{\pi}(s,a) Qπ(s,a) 的值越大越好。
那实际上在训练的时候,其实就是把 Q 跟 actor 接起来变成一个比较大的网络。Q 是一个网络,输入 s 跟 a,输出一个 value。Actor 在训练的时候,它要做的事情就是输入 s,输出 a。把 a 丢到 Q 里面,希望输出的值越大越好。在训练的时候会把 Q 跟 actor 接起来,当作是一个大的网络。然后固定住 Q 的参数,只去调 actor 的参数,用 gradient ascent 的方法去最大化 Q 的输出。
3.1 算法流程
我们来看一下 pathwise derivative policy gradient 的算法。
一开始有一个 actor π \pi π去跟环境互动,然后用它去估计 Q value。估计完 Q value 以后,就把 Q value 固定,只去学习一个 actor。假设这个 Q 估得很准,它知道在某一个状态采取什么样的动作会得到很大的 value。接下来就学习这个 actor,actor的目的是 在给定 s 的时候,它采取了a,可以让最后 Q-function 算出来的 value 越大越好。通过这个去更新 actor π \pi π。然后有新的 π \pi π 去跟环境做互动,再估计 Q,最后得到新的 π \pi π 去最大化 Q 的输出。DQN用得上的技巧,在这边也几乎都用得上,比如说 replay buffer、exploration 等等。
3.2算法相对于DQN的改变
接下来我们把 DQN 改成 Pathwise Derivative Policy Gradient,这边需要做四个改变。
- 第一个改变是,原本是用 Q 来决定在状态 s t s_t st 产生那一个动作, 现在是直接用 π \pi π 。我们不用再解 arg max 的问题了,我们直接学习了一个 actor。这个 actor 输入 s t s_t st 就会告诉我们应该采取哪一个 a t a_{t} at。
- 第二个改变是,原本这个地方是要计算在 s i + 1 s_{i+1} si+1,根据 policy 采取某一个动作 a 会得到多少的 Q value。那你采取让 Q ^ \hat{Q} Q^ 最大的那个动作 a。现在由 policy π \pi π 来解,所以我们直接把 s i + 1 s_{i+1} si+1 代到 policy π \pi π 里面。在 Q-function 里面,有两个 Q network,一个是真正的 Q network,另外一个是目标 Q network。那实际上在实现这个算法 的时候,也会有两个 actor,会有一个真正要学习的 actor π \pi π和一个目标 actor π ^ \hat{\pi} π^ 。这个原理就跟为什么要有目标 Q network 一样,我们在算目标 value 的时候,我们并不希望它一直的变动,所以我们会有一个目标的 actor 和一个目标的 Q-function,它们平常的参数是固定住的。
- 第三个不同就是之前只要学习 Q,现在多学习一个 π \pi π。
- 第四个步骤,就跟原来的 Q-function 一样。你要把目标的 Q network 取代掉,现在也要把目标 policy 取代掉。
4. 练习
1. A3C在训练时有很多的worker进行异步的工作。那么其具体的如何运作的呢?
答:A3C一开始会有一个 global network。它们有包含 policy 的部分和 value 的部分,假设它的参数就是 θ 1 \theta_1 θ1。对于每一个 worker 都用一张 CPU 训练(举例子说明),第一个 worker 就把 global network 的参数 copy 过来,每一个 worker 工作前都会global network 的参数 copy 过来。然后这个worker就要去跟environment进行交互,每一个 actor 去跟environment做互动后,就会计算出 gradient并且更新global network的参数。这里要注意的是,所有的 actor 都是平行跑的、之间没有交叉。所以每个worker都是在global network“要”了一个参数以后,做完就把参数传回去。所以当第一个 worker 做完想要把参数传回去的时候,本来它要的参数是 θ 1 \theta_1 θ1,等它要把 gradient 传回去的时候。可能别人已经把原来的参数覆盖掉,变成 θ 2 \theta_2 θ2了。但是没有关系,它一样会把这个 gradient 覆盖过去。
2. A3C是on-policy还是off-policy
答:A3C中,评论家学习值函数,同时有多个actor并行训练并且不时与全局参数同步。A3C旨在用于并行训练,是 on-policy 的方法。
3. Actor - Critic有何优点
答:
- 相比以value-based的算法,Actor - Critic应用了策略梯度的做法,这能让它在连续动作或者高维动作空间中选取合适的动作,而 Q-learning 做这件事会很困难甚至瘫痪。
- 相比单纯策略梯度,Actor - Critic应用了Q-learning或其他策略评估的做法,使得Actor Critic能进行单步更新而不是回合更新,比单纯的Policy Gradient的效率要高。
4. actor-critic框架中的critic起了什么作用?
答:critic表示了对于当前决策好坏的衡量。结合策略模块,当critic判别某个动作的选择时有益的,策略就更新参数以增大该动作出现的概率,反之降低动作出现的概率。
5. 简述A3C的优势函数?
答: A ( s , a ) = Q ( s , a ) − V ( s ) A(s,a)=Q(s,a)-V(s) A(s,a)=Q(s,a)−V(s)是为了解决value-based方法具有高变异性。它代表着与该状态下采取的平均行动相比所取得的进步。
如果 A(s,a)>0: 梯度被推向了该方向
如果 A(s,a)<0: (我们的action比该state下的平均值还差) 梯度被推向了反方
但是这样就需要两套 value function,所以可以使用TD error 做估计: A ( s , a ) = r + γ V ( s ′ ) − V ( s ) A(s,a)=r+\gamma V(s')-V(s) A(s,a)=r+γV(s′)−V(s)。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)