Asynchronous Advantage Actor-Critic (A3C)
切换视频源:

Asynchronous Advantage Actor-Critic (A3C)

作者: 莫烦 编辑: 莫烦 发布于: 2017-05-03

学习资料:

要点

一句话概括 A3C: Google DeepMind 提出的一种解决 Actor-Critic 不收敛问题的算法. 它会创建多个并行的环境, 让多个拥有副结构的 agent 同时在这些并行环境上更新主结构中的参数. 并行中的 agent 们互不干扰, 而主结构的参数更新受到副结构提交更新的不连续性干扰, 所以更新的相关性被降低, 收敛性提高.

因为这节内容是基于 Actor-Critic, 所以还不了解 Actor-Critic 的朋友们, 强烈推荐你在这个短视频这个 Python 教程中获得了解,

下面是这节内容的效果提前看:

算法

A3C 的算法实际上就是将 Actor-Critic 放在了多个线程中进行同步训练. 可以想象成几个人同时在玩一样的游戏, 而他们玩游戏的经验都会同步上传到一个中央大脑. 然后他们又从中央大脑中获取最新的玩游戏方法.

这样, 对于这几个人, 他们的好处是: 中央大脑汇集了所有人的经验, 是最会玩游戏的一个, 他们能时不时获取到中央大脑的必杀招, 用在自己的场景中.

对于中央大脑的好处是: 中央大脑最怕一个人的连续性更新, 不只基于一个人推送更新这种方式能打消这种连续性. 使中央大脑不必有用像 DQN, DDPG 那样的记忆库也能很好的更新.

6-3-1.png

为了达到这个目的, 我们要有两套体系, 可以看作中央大脑拥有 global net 和他的参数, 每位玩家有一个 global net 的副本 local net, 可以定时向 global net 推送更新, 然后定时从 global net 那获取综合版的更新.

如果在 tensorboard 中查看我们今天要建立的体系, 这就是你会看到的.

6-3-2.png

W_0 就是第0个 worker, 每个 worker 都可以分享 global_net.

6-3-3.png

如果我们调用 sync 中的 pull, 这个 worker 就会从 global_net 中获取到最新的参数.

6-3-4.png

如果我们调用 sync 中的 push, 这个 worker 就会将自己的个人更新推送去 global_net.

这次我们使用一个连续动作的环境 Pendulum 举例. 如果直接看所有代码, 请看我的 Github, 如果你处理的是一个离散动作环境, 可以参考这个Github 中的这个文件.

接下来我们就开始定义连续动作的 A3C 啦.

主结构

我们用 Tensorflow 搭建神经网络, 对于我们的 Actor, tensorboard 中可以看清晰的看到我们是如果搭建的:

6-3-5.png

我们使用了 Normal distribution 来选择动作, 所以在搭建神经网络的时候, actor 这边要输出动作的均值和方差. 然后放入 Normal distribution 去选择动作. 计算 actor loss 的时候我们还需要使用到 critic 提供的 TD error 作为 gradient ascent 的导向.

6-3-6.png

critic 很简单啦, 只需要得到他对于 state 的价值就好了. 用于计算 TD error.

Actor Critic 网络

其搭建的代码部分在这, 因为写下来全部代码比较眼花, 所以会有点伪代码 (如果想一次性看全部, 请去我的Github):

我们将 ActorCritic 合并成一整套系统, 这样方便运行.

这些只是在创建网络而已, worker 还有属于自己的 class, 用来执行在每个线程里的工作.

Worker

每个 worker 有自己的 class, class 里面有他的工作内容 work, 看全部请来我的 Github.

Worker 并行工作

这里才是真正的重点! Worker 的并行计算.

我的电脑里可以建立 4个 worker, 也就可以把它们放在4个线程中并行探索更新. 最后的学习结果可以用这个获取 moving average 的 reward 的图来概括.

6-3-7.png

上面讲到的是一个 continuous action 的例子, 全部代码在这里清晰可见. 还有一个是 discrete action 的例子. 使用的是 Cartpole 的实验, 代码在这. 同时, 我还做了一个 A3C 加上 RNN 的例子, 同样是用 Pendulum 的例子, 代码在这.

机械手臂

我也用这套 A3C 测试过自己写的机器手臂的环境, 发现效果也还行. 有兴趣的朋友可以看到这里.

有很多人留言说想要我做一个关于这个机器手臂的教程, 不负众望, 你可以在这里 看到我怎么从零开始, 手写环境, debug 测试, 来制作一个强化学习的机器手臂.

multiprocessing + A3C

除此之外, 我心里一直有一个疙瘩, 因为这个 A3C 中, 我用的是 python 的 threading, 懂 python 的朋友知道, threading 有 GIL, 运算速度是问题, 我的 CPU 都不是满格的. 我一直想把这个 A3C 代码移植去 multiprocessing, 提高效率. 但是 Tensorflow 的 session 就是和 multiprocessing 不兼容, Global Net 做不好. 怎么办?

Distributed Tensorflow 是一个备选方案. 但是这个要求你是在计算机集群上做, 不然速度上还不如这个 threading 的 A3C. 这时, 我不爽了, 到在知乎上抱怨了一番. 和知友们聊了会, 然后我想出了下面这个方案.

和 Tensorflow 一样, 我做过一些 Pytorch 的教程, pytorch 也是做神经网络的. 但是它是支持 multiprocessing 的. 我专门开了一个 repo, 把 Pytorch + multiprocessing 的代码分享了出来. 这会儿, CPU 满格, 心情舒畅多了~

6-3-8.png


降低知识传递的门槛

莫烦经常从互联网上学习知识,开源分享的人是我学习的榜样。 他们的行为也改变了我对教育的态度: 降低知识传递的门槛免费 奉献我的所学正是受这种态度的影响。 【支持莫烦】 能让我感到认同,我也更有理由坚持下去。

我组建了微信群,欢迎大家加入,交流经验,提出问题,互相帮持。 扫码后,请一定备注"莫烦",否则我不会同意你的入群申请。

wechat