并行强化学习设计的一些想法

突然冒出了一个想法,可以不可以设计一个并行的强化学习计算模式,能够使强化学习算法充分利用计算机的硬件平台来快速计算呢???

经过好一顿胡思乱想有了下面的设计:

说明:

由于强化学习算法需要和环境交互,比如最常见的在线强化学习就需要不断的和环境交互以获得最新的数据从而来训练强化学习算法。以往的强化学习算法都是和单一环境交互,并且都是串行的来进行环境交互与最终策略网络的训练,那么我们能不能同时并行化的和多个环境来进行交互,同时将与环境进行交互的行为生成的部分与最终策略网络训练部分也并行化呢,于是有了上面的设计。

其中,行为网络与游戏环境联系最为频繁,行为网络需要不断的给出游戏环境的下步动作;

游戏进程需要将根据行为决策后获得的最新状态发送给行为网络,以便行为网络给出下步决策动作;

游戏进程又需要在完成一定数据生成后将数据发送给最终策略网络,以便策略网络进行训练;

策略网络又需要在一定训练周期后将获得的策略发送给行为网络,以使行为网络可以获得较新的策略。

可以看到把一个单进程的强化学习算法拆解成多进程并行的程序很重要的一点就是解决各部分(各子进程)间的消息传递问题(信息共享)。

多进程通信我们可以使用队列、管道和共享内存的方式。其中对于较大数据量的话共享内存方式性能较好。但是使用共享内存不能很好解决进程间相互通知的问题,在这时候可以使用队列和管道来传递同步通知以达到辅助的作用。

同时还需要注意的是多进程算法是否采用同步方式还是使用异步方式,考虑到一定的复现性和运行稳定性这里建议考虑同步方式的多进程并行。

本文所做设想比较笼统,也比较具有概括性,该设计中可以把强化学习算法分为三部分:

1. 为游戏环境提供决策的行为决策网络,这里称为角色A;

2. 运行仿真环境的游戏环境,这里称为角色B;

3. 强化学习最终的决策网络,提供算法最终的训练获得的策略,这里称为角色C。

角色A为角色B提供的决策数据存在共享内存中,角色A被角色B发送的通知唤醒后从共享内存中取出状态信息计算出行为决策信息并将其保存到共享内存中,并通过队列或管道发送通知给角色B,然后角色A进入堵塞状态等待被B唤醒。

角色B获得角色A发送来的唤醒通知后从共享内存中取出决策数据,便以此运行游戏环境,获得下步状态等信息,将下步状态存入共享内存中并并通过队列或管道发送通知给角色A以唤醒角色A,此时角色B进入堵塞状态等待被A唤醒。

角色A每次被唤醒后   角色A每次进入堵塞之前都会检查共享内存中是否有角色C存入的最新策略数据,其中可以设置某个hash值来验证是否有新的策略数据存入,如果有新的策略数据则对自身策略数据进行替代。其中,这个hash值可以用随机函数来获得,为防止角色A与角色C同时访问共享内存这部分内存应该加锁。

角色B在一定周期后需要将生成的数据存入共享内存中以便角色C来进行训练使用,这部分共享内存由于可能有多个角色B与角色C访问,因此也应该加锁。

这个设计的主要思想也就是上面所述,其中三个角色A、B、C之间的同步问题是难以有个很好解决的,这方面的尝试以前也是做过的:

https://gitee.com/devilmaycry812839668/Parallelism_Reinforce_CartPole

https://gitee.com/devilmaycry812839668/parallelism_-multi_-step_-reinforce_-cart-pole

https://gitee.com/devilmaycry812839668/reinforce_with_-experience-buffer

其中最大的问题AC之间采用同步还是异步的问题,BC之间数据传递的时效性;AB之间采用同步即可,因为AB之间关联性极强,A计算出对应状态的决策动作给B,B根据A给的决策动作行动后获得新的状态再给A。

强化学习是分为同策略算法和异策略算法两种,其中异策略算法以DQN为代表,同策略算法以AC为代表。

由于异策略对于数据的时延性要求不高,所以采用上述并行设计中,AC之间完全可以采用异步的方法,即C将最新的策略发送给A,A获得最新策略随时进行替换,其中A不必等待C,如果没有获得C的最新策略也可以使用旧的策略与B进行交互。B发送给C的数据也一般不需要考虑对于C的时效性,可以随时发送给C。

而对于同策略算法则不同,如AC算法:

如果A与B进行交互时使用的策略不是C中最新的(当前的策略)那么B发送给C的数据就具有一定的延后性,或者说B发送给C的数据是C几次更新前的策略对应的数据,这时C利用这样的有一定时延的数据计算就会不准确甚至是发散从而无法收敛。

那么如何使B发送给C的数据不至于使C发散呢,之前作者也是做过几种尝试,总之有一定效果但是不很理想,具体看上面给出的链接地址。

最后如何实现在异策略下AC角色异步这个问题最后的解决方法就是AC采用同步方法,BC也采用同步方法:

假设这里一个用8个环境子进程,也就是说B角色的个数为8。A与B进行交互,B中每完成一个子进程(子进程完成了一个episode)则把对应的数据发送给C,C根据数据计算出更新的梯度,但是C此时并不对参数进行更新。B中每完成一个进程则与A进行交互时就少一个进程,8个环境进程全部完成后C也就进行了8次的梯度计算,此时A进入堵塞状态等待C的唤醒,C角色对这个8个梯度求和或者求均值后对C的参数进行更新。C的参数更新后发送给A,此时唤醒A继续下一轮的运行。

采用异步的方法或同步的方法并行化异策略强化学习算法都是可以实现较好性能的。

采用同步的方法并行化同策略强化学习算法可以或者一个比较稳定的结果,可能性能不如异步的并行化方法,但是稳定性、复现性都较好,也便于理解。

不论是同策略强化学习还是异策略强化学习算法使用同步的并行方式都是一个不错的选择,稳定性、复现性、可理解性往往更重要些。

相关类似的算法设计参考A3C强化学习算法。

==============================================================

其实并行强化学习很多问题的产生都是由于把一个进程中运行的策略决策部分(推理部分)和最终策略训练部分(训练部分)拆开为两个进程所导致的。如果不拆开运行性能得不到进一步的提升,拆开后同步问题、数据时效性问题、算法稳定性问题又难以解决,这就是并行强化学习算法中很致命的一个问题。

本博客是博主个人学习时的一些记录,不保证是为原创,个别文章加入了转载的源地址还有个别文章是汇总网上多份资料所成,在这之中也必有疏漏未加标注者,如有侵权请与博主联系。
原文地址:https://www.cnblogs.com/devilmaycry812839668/p/15085109.html