Keras强化学习练手——FlappyBird
keras强化学习——FlappyBird
运行过程
main.py中train()函数定义好网络和回调函数。
变量 | 参数 |
---|---|
网络 | net |
预测函数 | func = Model(net.input[0], net.out1) |
强化学习有5个元素:环境,代理,状态,激励函数(reward),动作。
代理产生动作,环境根据动作反馈该动作之后的环境状态以及reward。需要注意该State知识环境反馈的一个画面,数据根据游戏的画面而生成,4帧为一个游戏状态,为current_state, next_state。
环境会根据游戏状态,用激励函数给出激励,但是环境的激励通常只有结束(-1)、胜利(1)和正在进行(0.1)三种
强化网络的目标是训练代理,这个代理也叫智能体,训练过程的数据格式如下:
-
当前游戏状态current_state,
-
当前游戏动作(action),
-
(Q_value)下个游戏状态(next_sate)理想中的
代理的训练过程实质为代理激励函数的拟合过程。FlappyBird中,飞过中心线才获得为1的激励,但是靠近中心线以及在管道外面飞的激励均为0.1,这对于环境是正常的,如下图。
但是对于人的大脑两者的价值绝不等同,靠近中心线的状态(下图中的2)人们会在下意识觉得鸟更棒,需要更高的激励值。但是初始化的网络不能够正常反馈这种激励函数,因此训练代理就是拟合这种激励函数,使之接近于人的想法。
Q_value为net的out1
那么代理觉得Bird在游戏状态中真正的激励为:
terminal表示Bird是否翻车 为1就是翻车了
代理根据游戏的current_sate和action根据自己拟合出来的激励函数,给出的激励值为current_reward为net的out2.
最终优化current_reward与agent_reward的差,两者越小越好。
为了加快数据产生速度,开始将游戏的帧率提高,正常的fps为30,训练时调整为1000,因为游戏每一帧过去,就会训练一次,如果帧数过慢,网络训练就会陷入等待。调整后训练每一批次一万条记录,训练事件为2分50秒左右,200轮训练将近9.5到10个小时之间。
292轮后的效果移步
文件结构
net.py 网络结构包含两个网络V1和V2, 目前只训练V1 。
文件名 | 描述 |
---|---|
main.py | 训练文件 |
agent.py | 产生数据 |
play.py | 游戏运行包 |
game\control.py | 游戏调度文件 |
game\element.py | 游戏配置文件 |
game\engine.py | 游戏后端,两种选择PyQt5和pygame |
game\display.py | PyQt5写的游戏引擎 |
网络结构 net.py
Layer (type) | Input Shape | Kernel | stride | Output Shape | |
---|---|---|---|---|---|
0 | input_state | (None, 80, 80, 4) | |||
1 | input_action | (None, 2) | |||
2 | 卷积(conv) | (None, 80, 80, 4) | (8, 8, 4, 32) | 4 | (None, 20, 20, 32) |
3 | 池化(pool) | (None, 20, 20, 32) | 2 | (None, 10, 10, 32) | |
4 | 卷积(conv) | (None, 20, 20, 32) | (4, 4, 32, 64) | 2 | (None, 5, 5, 64) |
5 | 卷积(conv) | (None, 5, 5, 64) | (3, 3, 64, 64) | 1 | (None, 5, 5, 64) |
6 | flatten | (None, 1600) | |||
7 | 全连接(fully_connect) | 1600 | (1600, 512) | (None, 512) | |
8 | out1_全连接(fully_connect) | 512 | (512, 2) | (None, 2) | |
9 | out2_点乘(dot) | (None, 2)[action, out1] | (None, 1) |