本
文
摘
要
随着这几年AI技术的快速发展,以及AlphaGo等具有时代影响力事件的出现,快速的将AI技术展现到广大民众面前。随之带来了技术和产业的快速发展。但在核心算法的发展上速度还是比较缓慢的。很多算法都是多年前就提出,受限于数据问题或者计算能力等外界因素,直到今年来才逐渐释放出其影响力。
2017年AlphaZero的出现,带来了强化学习强有力的声音,展示了一种更接近人类学习方式的方法,“自我训练”一个带有科幻色彩的名词在AI时代变成了可能。今天就通过一个热门的Flappy Bird游戏的自学习过程,也就是教程序学会打这个游戏,通过这个实例带大家走进强化学习。由于强化学习已经慢慢发展为AI方向上与监督学习并列的一个大方向,所涉及到的基础理论和技术十分庞杂,因此本篇的重心还是这个实例,通过这个实例来窥探强化学习的思想和解决问题的方式。
Flappy Bird(非官方译名:笨鸟先飞)是一款2013年鸟飞类游戏,由越南河内独立游戏开发者阮哈东(Dong Nguyen)开发,另一个独立游戏开发商GEARS Studios发布。—— 以上内来自《 *** 》
Flappy Bird操作简单,通过点击手机屏幕使Bird上升,穿过柱状障碍物之后得分,碰到则游戏结束。由于障碍物高低不等,控制Bird上升和下降需要反应快并且灵活,要得到较高的分数并不容易。为了将这个过程描述清楚,本篇的结构主要如下:
强化学习思想Q-learning和DQN算法代码实现一.强化学习思想
强化学习(英语:Reinforcement learning,简称RL)是机器学习中的一个领域,强调如何基于环境而行动,以取得最大化的预期利益。其灵感来源于心理学中的行为主义理论,即有机体如何在环境给予的奖励或惩罚的 *** 下,逐步形成对 *** 的预期,产生能获得最大利益的习惯性行为。这个方法具有普适性,因此在其他许多领域都有研究,例如博弈论、控制论、运筹学、信息论、仿真优化、多主体系统学习、群体智能、统计学以及遗传算法。在运筹学和控制理论研究的语境下,强化学习被称作“近似动态规划”(approximate dynamic programming,ADP)。在最优控制理论中也有研究这个问题,虽然大部分的研究是关于最优解的存在和特性,并非是学习或者近似方面。在经济学和博弈论中,强化学习被用来解释在有限理性的条件下如何出现平衡。
以上是 *** 对强化学习的定义,看起来还是很晦涩,下面我们通过一张图和一些例子来说明这个过程就会容易的多。
上图描述出了强化学习的核心思想,主要包含两个角色,
一个是智能代理,可以理解为人或者先进的AI算法。一个是外部环境,也就是我们需要面对和接触的环境,在本文中就是Flappy Bird游戏。那么这个交互模式是怎样呢?如下慢慢道来:
如下我先通过一个人如何练习篮球投篮动作的过程来描述强化学习的交互过程。在这个场景中,人就是智能代理,外部环境就是篮球场。
1.人接收到当前的状态 StS_{t} ,和外部的奖赏 rtr_{t} ,做出反应动作 ata_{t} , 在这个场景中外部状态就是人观察球场和篮筐的状态,外部奖赏就是上次投篮(初始为空)有没有进或者上次没劲的原因是啥,是力气小了还是角度不对,做出反应就是根据现在球场的环境和上次状态,选择一个合适的角度和力度将篮球投出。
2. 外部环境,就是接收这次的动作ata_{t},环境根据这次动作生成状态StS_{t} ,并做出这次的奖赏rtr_{t},在这个场景中描述起来就是,球场和球筐接收你投出的球,做出球进了或者没进,或者三不沾(哇)的现实反馈,同时你会有一个奖赏值产生,这个奖赏怎么描述呢,如果球进了,通常人们会刻意记住这次出手的力度,角度,起跳的高度,时间的节奏等信息,尽量在下次出手时重复上一次的一切。但如果没进,一般的反馈是这次的角度不对,或者力度不对,或者起跳高度不够等信息,这些都是奖赏值的作用。如果球进了,这次就是正向的奖赏值,如果没进就是负向的奖赏值,需要调整。
强化学习的核心思想就是这个不断训练的过程,不断的根据外部环境的反馈做出更好的判断,生成更合理的行动,产生更聪明的决策。
回到本篇说的这个游戏上,就是通过利用强化学习的思想,教会AI程序做出更合理的飞行路线,保持更长的存货时间。对外界就反馈出了更强的智能和反应能力。
下面我们就通过描述如何通过具体的算法和技术方法来实现这个过程。
二. Q-learning和DQN算法
1.Q-learning:
我们首先介绍一下Q-learning算法,一种主流的强化学习算法.
如下图所示,Q-learning算法的主要思想是通过建立一个Q-Table的结构,也就是记录每个状态和行为的Q值(可以理解为一种评分),通过不断的训练,可以得到在任何一个状态下,如果做出每个行为的Q值是多少,这样就可以快速的选择出好的行为。
其算法迭代过程的伪代码如下,通过利用一种贝尔曼方程(Bellman Equation)的算法(由于涉及内容较多,感兴趣的同学可以自己寻找参考资料,本篇不做详细论述)来更新Q值。
其核心的基本想法如下:
其中Q值的更新,可以看做是加入学习率 α\alpha 的更新方式,具体公式如上中描述,‘
采用一种梯度平滑的方式逐步来优化Q值,其每次变化的大小为:
r+γ(max(Q(s′,a′))−Q(s,α)r + γ(max(Q(s’,a’)) - Q(s,\alpha)
新的Q值则为, r+γ(max(Q(s′,a′))r + γ(max(Q(s’,a’)) , 其直观理解为每一个当前状态S,在动作a下的Q值可以是奖级值r和后期状态之中最大的Q的和。
其含义如上去所示,动作s在动作a下,其Q值取决于获得的反馈r,和后续 s和a中最大的Q值之和。然后采用了一种平滑升级的方式来更新Q值。至此,Q-learning的介绍就到此,下面我们聊一聊DQN,
2. DQN算法(Deep Q-learning):
单纯的Q-Learning算法使用表来保存状态,一个1000×1000图像的像素状态数基本接近与无穷,故有了CNN+Q-Learning 即DQN算法,
为了实现降维,我们可以假设一种价值函数近视的方法,例如:
Q(s,a)=w1s+w2a+bQ(s,a)=w_{1}s + w_{2}a+b
的线性表示法,即可获得Q值的更新。
据此,定义损失函数如下:
L(w)=E[(r+γmaxa′Q(s′,a′,w)⏟Target−Q(s,a,w))2]L(w) = E[(\color{blue}{\underbrace{r+\gamma\max_{a^\prime}Q(s^\prime,a^\prime,w)}_{Target}}-Q(s,a,w))^2]
后续采用随机梯度下降的方法来训练损失函数的梯度,直至收敛。找到收敛的深度网络参数。
三. 代码实现
Github : yenchenlin/DeepLearningFlappyBird
这部分主要通过复现github上的源码来说明,流程主要包括如下几个方面:
pygame的相关操作,如何用Python模拟游戏开发(不是本篇重点,简要说明)CNN模型构建部分(比较通用,也不多做说明)强化学习模型的构建以及损失函数的说明如下分布说明,
pygame相关game_state = game.GameState() # get the first state by doing nothing and preprocess the image to 80x80x4 do_nothing = np.zeros(ACTIONS) do_nothing[0] = 1 x_t, r_0, terminal = game_state.frame_step(do_nothing)主要包含两部分,
(1),游戏的启动,相关控件的拼接,时钟系统的控制等。
(2). frame_step方法,这个方法的输入是什么都不做,或者提升bird,返回值是图像像素级的数据(可以看做环境St),得分情况(是否继续存活或者发生碰撞等),是否终止等信息。
2. CNN部分
这部分与主流的CNN操作区别不大,不做太多说明,具体见上图的CNN结构映射图即可。
3. 强化学习模型的构建
a = tf.placeholder("float", [None, ACTIONS]) y = tf.placeholder("float", [None]) readout_action = tf.reduce_sum(tf.multiply(readout, a), reduction_indices=1) cost = tf.reduce_mean(tf.square(y - )) train_step = tf.train.AdamOptimizer(1e-6).minimize(cost)根据环境St的CNN卷积处理,混合当前做的动作a, 可以获得当前的Q值,也就是readout_action部分。
readout_j1_batch = readout.eval(feed_dict = {s : s_j1_batch}) for i in range(0, len(minibatch)): terminal = minibatch[i][4] # if terminal, only equals reward if terminal: y_batch.append(r_batch[i]) else: y_batch.append(r_batch[i] + GAMMA * np.max(readout_j1_batch[i])) # perform gradient step train_step.run(feed_dict = { y : y_batch, a : a_batch, s : s_j_batch} )通过利用动作a产生的St动作,可以获得后续的CNN卷积处理后的操作,然后混合np.max可以获得后续的最大Q值,加入当前的奖赏r_batch[i],即更新出新的Q值。也就是Q-learning中的
r + γ(max(Q(s’,a’))
部分,然后利用损失函数:
L(w)=E[(r+γmaxa′Q(s′,a′,w)⏟Target−Q(s,a,w))2]L(w) = E[(\color{blue}{\underbrace{r+\gamma\max_{a^\prime}Q(s^\prime,a^\prime,w)}_{Target}}-Q(s,a,w))^2]
即计算出cost,然后通过tensorflow内置的Adam优化方法,完成迭代优化计算。
至此,今天的相关讨论主要到此为止,通过利用Flappy Bird游戏自学习的过程带大家系统的梳理了一下强化学习的核心思想,并介绍了其中的Q-learning算法以及本篇中使用的DQN算法。对核心代码进行了说明解释。欢迎大家一起讨论相关问题。
慢慢算法路,与君共勉!