【深度强化学习】A3C

上一篇对Actor-Critic算法的学习,了解Actor-Critic的流程,但由于普通的Actor-Critic难以收敛,需要一些其他的优化。而Asynchronous Advantage Actor-Critic(A3C)就是其中较好的优化算法。

A3C Introduction

之前学到的DQN算法,为了方便收敛使用了经验回放。Actor-Critic是否也可以使用这个方法呢?当然可以。不过A3C更进一步,还克服了一些经验回放的问题(回放池经验相关性太强,用于训练时很可能效果不佳)。比如,学习下棋,总是和同一个人下,期望提高棋艺,但到一定程度就难以提高了,此时最好的方法就是另寻高手切磋。
A3C的思路也是如此,它利用多线程的方法,同时在多个线程里面分别与环境进行交互学习,每个线程都把学习的成果汇总起来,整理保存在一个公共的地方。并且,定期从公共的地方把大家的齐心学习的成果拿回来,指导自己和环境后面的学习交互。
这样,A3C避免了经验回放相关性过强的问题,同时做到了异步并发的学习模型。

A3C的算法优化

相比Actor-Critic,A3C的优化主要有3点,分别是异步训练框架,网络结构优化,Critic评估点的优化。其中异步训练框架是最大的优化。

1. 首先来看这个异步训练框架:

【深度强化学习】A3C

  • Global Network就是上一节说的共享的公共部分,主要是一个公共的神经网络模型,这个神经网络包括Actor网络和Critic网络两部分的功能。
  • 下面有n个worker线程,每个线程里有和公共的神经网络一样的网络结构,每个线程会独立的和环境进行交互得到经验数据,这些线程之间互不干扰,独立运行。
  • 每个线程和环境交互到一定量的数据后,就计算自己线程里的神经网络损失函数的梯度,但是这些梯度并不更新自己线程里的神经网络,而是去更新公共的神经网络。也就是n个线程会独立的使用累积的梯度分别更新公共部分的神经网络模型参数。
  • 每隔一段时间,线程会将自己的神经网络的参数更新为公共神经网络的参数,进而指导后面的环境交互。

可见,公共部分的网络模型就是我们要学习的模型,而线程里的网络模型主要是用于和环境交互使用的,这些线程里的模型可以帮助线程更好的和环境交互,拿到高质量的数据帮助模型更快收敛。

2. 第二个优化:网络结构的优化

  • 在Actor-Critic中,使用了两个不同的网络Actor和Critic。
  • 在A3C中,把两个网络放到了一起,即输入状态SS,输出状态价值VV,和对应的策略π\pi。当然,我们仍可以把Actor和Critic看作独立的两块,分别处理,如下图:
    【深度强化学习】A3C

3. Critic评估点的优化

  • Actor-Critic算法中,讨论了不同的Critic评估点的选择,其中优势函数AA作为Critic评估点,优势函数AA在时刻tt不考虑参数的默认表达式:
    A(S,A,t)=Q(S,A)V(S)A\left(S,A,t\right)=Q\left(S,A\right)-V\left(S\right)
    Q(S,A)Q\left(S,A\right)的值一般可以通过单步采样近似估计,即:
    Q(S,A)=R+γV(S)Q\left(S,A\right)=R+\gamma V\left(S^{\prime}\right)
    这样优势函数去掉动作可表达为:

A(S,t)=R+γV(S)V(S)A\left(S,t\right)=R+\gamma V\left(S^{\prime}\right)-V\left(S\right)

其中V(S)V\left(S\right)的值通过Critic网络来学习得到。

在A3C中,采样更进一步,使用了N步采样,以加速收敛。则A3C中的优势函数表达为:
A(S,t)=Rt+γRt+1++γn1Rt+n1+γnV(S)V(S)A\left(S,t\right)=R_t+\gamma R_{t+1}+\dots +\gamma^{n-1}R_{t+n-1}+\gamma^nV(S^\prime)-V(S)

对于Actor和Critic的损失函数部分,和Actor-Critic基本相同。有一个小的优化点就是在Actor-Critic策略函数的损失函数中,加入了策略π的熵项,系数为c, 即策略参数的梯度更新和Actor-Critic相比变成了这样:
θ=θ+αθlogπθ(st,at)A(S,t)+cθH(π(St,θ))\theta = \theta + \alpha\bigtriangledown_\theta\log\pi_\theta\left(s_t,a_t\right)A\left(S,t \right) +c\bigtriangledown_\theta H(\pi(S_t,\theta))

A3C算法流程

由于A3C是异步多线程的,这里给出任意一个线程的算法流程。

输入: 公共部分的A3C神经网络结构,对应参数θ\thetaww,本线程的A3C神经网络结构,对应参数θ\theta^\primeww^\prime,全局共享的迭代轮数TT,全局最大迭代次数TmaxT_{max},线程内单次迭代时间序列最大长度TlocalT_{local},状态特征维度nn,动作集AA,步长α\alphaβ\beta,熵系数cc,衰减因子γ\gamma
输出: 公共部分的A3C神经网络参数θ\thetaww

1. 更新时间序列t=1t=1
2. 重置Actor和Critic的梯度更新量:dθ0,dw0d\theta\leftarrow 0,dw\leftarrow 0
3. 从公共部分的A3C神经网络同步参数到本线程的神经网络:θ=θ\theta^\prime=\thetaw=ww^\prime =w
4. tstart=tt_{start}=t,初始化状态sts_t
5. 基于策略π(atst;θ)\pi(a_t\mid s_t;\theta)选择动作ata_t
6. 执行动作ata_t得到奖励rtr_t和新状态st+1s_{t+1}
7. tt+1,TT+1t\leftarrow t+1, T\leftarrow T+1
8. 如果sts_t是终止状态,或ttstart==tlocalt-t_{start}==t_{local},则进入步骤9,否则回到步骤5
9. 计算最后一个时间序列位置sts_tQ(s,t)Q(s,t):
Q(s,t)={0terminal stateV(st,w)none terminal state,bootstrappingQ(s,t)= \begin{cases} 0 & terminal\ state \\ V(s_t,w^\prime) & none\ terminal\ state, bootstrapping\end{cases}
10. for i(t1,t2,,tstart)i \in (t-1,t-2,\dots,t_{start})
  a) 计算每个时刻的Q(s,i)Q(s,i)Q(s,i)=ri+γQ(s,i+1)Q(s,i)=r_i+\gamma Q(s,i+1)
  b) 累计Actor的本地梯度更新:

dθ=dθ+θlogπθ(si,ai)(Q(s,i)V(Si,w))+cθH(π(si,θ))d\theta = d\theta + \bigtriangledown_{\theta^\prime}\log\pi_{\theta^\prime}\left(s_i,a_i\right)(Q\left(s,i \right)-V(S_i,w^\prime) )+c\bigtriangledown_{\theta^\prime}H(\pi(s_i,\theta^\prime))
  c) 累计Critic的本地梯度更新:

dwdw+(Q(s,i)V(Si,w))2wdw\leftarrow dw+\frac{\partial(Q(s,i)-V(S_i,w^\prime))^2}{\partial w^\prime}

11. 更新全局神经网络的模型参数:

θ=θαdθ,w=wβdw\theta=\theta-\alpha d\theta,w=w-\beta dw

12. 如果T>TmaxT>T_{max},则算法结束,输出公共部分的A3C神经网络参数θ\thetaww,否则进入步骤3


笔记参考刘建平Pinard博客