相关文件将会包含在我的GitHub仓库中
CartPole与AC算法简介
CartPole
CartPole是强化学习领域的经典题型了,题目就是一个小车和一个倒立摆,也就是一个可以左右移动的方块上有一跟可以自由倾斜的棍子,开始的时候环境给予棍子一个小的角度,然后让程序控制小车左右移动使得棍子尽量不掉下来。
游戏的评分就是坚持的时间长短,环境会在倾斜15度或者超出小车移动范围的时候结束游戏。一般认为坚持超过200帧则游戏成功。
AC算法
代码思想是强化学习中的ActorCritic
算法,即“演员 - 评委”体系。
首先需要介绍的是程序对游戏环境的识别。对于一个未知的状态体系(一般认为是马尔可夫状态),程序可能不能马上得到它走到这一步的价值如何(因为环境反馈的激励有可能不与当前状态直接关联),因此重点将在于如何评估到达一个状态后的价值,以及针对这样的状态-价值变换,我们如何进行抉择。我们一般将这样的两个问题分别称作评委和演员。
一般来说,使用两个网络分别扮演演员和评委,演员输入当前状态,输出概率参数,而评委输入当前状态,选择后状态以及获得的激励,输出估计的价值。
在训练的时候,根据价值网络(评委)的输出,我们可以训练动作网络(演员)的权重,然后通过估计价值和激励价值之差(TD-error)我们可以训练价值网络。
代码概述
代码使用的是VScode
的python
环境,使用OpenAI-gym
的CartPole-v0
作为测试环境,matplotlib
的pyplot
和animation
作为可视化以及gif
动图的输出(注意,gif
输出采用的writer
是ffmpeg
,这需要另行配置,程序会提示当前可用的writer
),AC
代码没有找到现成库,Actor
和Critic
均使用的tensorflow
下的keras
构建神经网络,而且都是3层网络(包括输出层和输入层)。
在运行代码时,可以通过调整注释掉的代码改变代码的输出,得到想要的内容。另外,为避免奇怪的冲突,默认gif
保存的位置为绝对位置D盘。注意,由于plt.show()
的位置在输出gif
的函数之前,关掉图像后才能获得gif动图(这是为了避免gif和图像被输出到一起)。
程序在AC
的C(Critic
)中将Advantage
,即TD-error
作为评判标准。
同时,由于Advantage
中含有本来model
自己的输出,使得AC
结果不容易收敛,Critic
代码采取了双神经网络的形式,一个网络负责进行训练,而另一个神经网络负责输出(作为副本),并以一定周期(程序内为5帧)与前一个神经网络进行同步(更新参数),由此加快收敛。
##代码细节
AC部分
1 | # 关于Actor的部分 |
有基本的注释,实现了几个简单的功能。
其中A的训练取了个巧,在激励为正的情况下,可以视为训练数据的权重变化带入,就不用打开神经网络里面了。
动画gif处理
照网上写了个函数,然后在需要的帧添加进列表,最后组装即可。
1 | def display_frames_as_gif(frames,name): |
添加帧:
1 | frames.append(env.render(mode = 'rgb_array')) |
然后最后组装:
1 | display_frames_as_gif(frames,'result') |
主程序处理
主函数负责调用之前的库:
1 | import gym |