Keras强化学习练手——FlappyBird

Document

keras强化学习——FlappyBird

运行过程

main.py中train()函数定义好网络和回调函数。

变量 参数
网络 net
预测函数 func = Model(net.input[0], net.out1)

强化学习有5个元素:环境,代理,状态,激励函数(reward),动作。

Keras强化学习练手——FlappyBird

代理产生动作,环境根据动作反馈该动作之后的环境状态以及reward。需要注意该State知识环境反馈的一个画面,数据根据游戏的画面而生成,4帧为一个游戏状态,为current_state, next_state。

环境会根据游戏状态,用激励函数给出激励,但是环境的激励通常只有结束(-1)、胜利(1)和正在进行(0.1)三种

强化网络的目标是训练代理,这个代理也叫智能体,训练过程的数据格式如下:

  1. 当前游戏状态current_state,

  2. 当前游戏动作(action),

  3. (Q_value)下个游戏状态(next_sate)理想中的

代理的训练过程实质为代理激励函数的拟合过程。FlappyBird中,飞过中心线才获得为1的激励,但是靠近中心线以及在管道外面飞的激励均为0.1,这对于环境是正常的,如下图。

Keras强化学习练手——FlappyBird

但是对于人的大脑两者的价值绝不等同,靠近中心线的状态(下图中的2)人们会在下意识觉得鸟更棒,需要更高的激励值。但是初始化的网络不能够正常反馈这种激励函数,因此训练代理就是拟合这种激励函数,使之接近于人的想法。

Q_value为net的out1

Q_value = max(func.predict(next_state))

那么代理觉得Bird在游戏状态中真正的激励为:

agent_reward = reward + Q_value * (1-terminal)

terminal表示Bird是否翻车 为1就是翻车了

代理根据游戏的current_sate和action根据自己拟合出来的激励函数,给出的激励值为current_reward为net的out2.

current_reward = net.predict([current_state, action])

最终优化current_reward与agent_reward的差,两者越小越好。

为了加快数据产生速度,开始将游戏的帧率提高,正常的fps为30,训练时调整为1000,因为游戏每一帧过去,就会训练一次,如果帧数过慢,网络训练就会陷入等待。调整后训练每一批次一万条记录,训练事件为2分50秒左右,200轮训练将近9.5到10个小时之间。

Keras强化学习练手——FlappyBird

292轮后的效果移步

Keras强化学习练手——FlappyBird

文件结构

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)