序言
昨天在看到讲解利用深度强化网络玩Flappy Bird的文章
很感兴趣,于是自己把代码拿下来,结合作者解析和多方查找资料,细心揣摩了下
现将代码解析和分析总结如下
摘要
简要概述深度强化网络的构架,分析实现代码的框架及细节
深度强化学习
1 强化学习是一种什么样的方法
强化学习作为一个序列决策(Sequential Decision Making)问题,它需要连续选择一些行为,从这些行为完成后得到最大的收益作为最好的结果。它在没有任何label告诉算法应该怎么做的情况下,通过先尝试做出一些行为——然后得到一个结果,通过判断这个结果是对还是错来对之前的行为进行反馈。由这个反馈来调整之前的行为,通过不断的调整算法能够学习到在什么样的情况下选择什么样的行为可以得到最好的结果。
2 通俗语言解释
我们训练出一个人工大脑Agent,这个Agent可以对环境Environment中的状态Status做出判断,读取环境的状态,并做出行动Action.
这个人工大脑做出行动之后,环境会根据受到的来自Agent的行动给这个Agent进行反馈Reward,这个人工大脑会根具环境的反馈做出改进,从而做出更好Improve的行动.
就是这样一个循环往复的过程,Agent不断地尝试,不断地改进自己。
那么如何让Agent变得足够远见,能够从长远的角度优化当前固定行动,而不是急功近利呢。所以Agent 每一步都要需要向着获得最大利益那边靠齐。
3 具体案例 Flappy Bird with DQ
在这个案例里面就要实现一个人工大脑。
这个Agent可以读取游戏的画面,然后判断是点击屏幕还是不动以控制小鸟飞跃障碍物。
经过长时间的训练,得到的Agent几乎可以一直玩下去。
训练一个小时之后
可以看到刚开始的时候还不是很流畅。
对于这样一个游戏来说。
- Agent 即我们用来读取图像信息并做出分析的CNN网络
- Environment 即这个已经封装起来的游戏,输入Action,并反馈回来Reward和Status(S_t+1)(还有是否游戏结束状态即terminal,这个 也可以视为Reward)
- Action 即对屏幕的点击操作,选择点击或者不点击
- Reward 即环境对Action的反馈
- Status 即环境目前的状态 S_t
以上就是一个深度强化网络所需的五大要素,我们整个代码实现都是围绕这五个要素来进行逻辑实现。
代码逻辑结构
整个代码逻辑相对来说比较复杂,且听我娓娓道来。
1 我们从对游戏图像的分析开始,在无输入的时候,初始化游戏图像数据,进行基本处理,将图像转化为80* 80*4 的矩阵Status即s_t,以这个数据矩阵作为神经网络的输入。
# 初始化
# 将图像转化为80*80*4 的矩阵
do_nothing = np.zeros(ACTIONS)
do_nothing[0] = 1
x_t, r_0, terminal = game_state.frame_step(do_nothing)
# 将图像转换成80*80,并进行灰度化
x_t = cv2.cvtColor(cv2.resize(x_t, (80, 80)), cv2.COLOR_BGR2GRAY)
# 对图像进行二值化
ret, x_t = cv2.threshold(x_t, 1, 255, cv2.THRESH_BINARY)
# 将图像处理成4通道
s_t = np.stack((x_t, x_t, x_t, x_t), axis=2)
第一阶段循环开始
2 将Status即s_t输入到Agent即CNN网络中得到分析结构(二分类),并由分析结果readout _t通过得到Action即a _t
# 将当前环境输入到CNN网络中
readout_t = readout.eval(feed_dict={s: [s_t]})[0]
a_t = np.zeros([ACTIONS])
action_index = 0
if t % FRAME_PER_ACTION == 0:
if random.random() <= epsilon:
print("----------Random Action----------")
action_index = random.randrange(ACTIONS)
a_t[random.randrange(ACTIONS)] = 1
else:
action_index = np.argmax(readout_t)
a_t[action_index] = 1
else:
a_t[0] = 1 # do nothing
3 将Action即a _t输入到Environment即game _state游戏中,得到Reward即r _t和s _t1和terminal
# 其次,执行选择的动作,并保存返回的状态、得分。
x_t1_colored, r_t, terminal = game_state.frame_step(a_t)
x_t1 = cv2.cvtColor(cv2.resize(x_t1_colored, (80, 80)), cv2.COLOR_BGR2GRAY)
ret, x_t1 = cv2.threshold(x_t1, 1, 255, cv2.THRESH_BINARY)
x_t1 = np.reshape(x_t1, (80, 80, 1))
s_t1 = np.append(x_t1, s_t[:, :, :