如下内容来源于一次部门内部的分享,主要针对AI初学者,介绍包括CNN、Deep Q Network以及TensorFlow平台等内容。因为笔者并不是深度学习算法研究者,所以如下更多从应用的角度对整个系统进行介绍,而不会进行详细的公式推导。ios
关于Flappy Bird Flappy Bird(非官方译名:笨鸟先飞)是一款2013年鸟飞类游戏,由越南河内独立游戏开发者阮哈东(Dong Nguyen)开发,另外一个独立游戏开发商GEARS Studios发布。—— 以上内来自《维基百科》 Flappy Bird操做简单,经过点击手机屏幕使Bird上升,穿过柱状障碍物以后得分,碰到则游戏结束。因为障碍物高低不等,控制Bird上升和降低须要反应快而且灵活,要获得较高的分数并不容易,笔者目前最多得过10分。算法
本文主要介绍如何经过AI(人工智能)的方式玩Flappy Bird游戏,分为如下四个部份内容: Flappy Bird 游戏展现 模型:卷积神经网络 算法:Deep Q Network 代码:TensorFlow实现 1、Flappy Bird 游戏展现 在介绍模型、算法前先来直接看下效果,上图是刚开始训练的时候,画面中的小鸟就像无头苍蝇同样乱飞,下图展现的是在本机(后面会给出配置)训练超过10小时后(训练步数超过2000000)的状况,其最好成绩已经超过200分,人类玩家已基本不可能超越。网络
训练数小于10000步(刚开始训练)app
训练步数大于2000000步(10小时后)dom
因为本机配置了CUDA以及cuDNN,采用了NVIDIA的显卡进行并行计算,因此这里提早贴一下运行时的日志输出。机器学习
关于CUDA以及cuDNN的配置,其中有一些坑包括:安装CUDA以后循环登陆,屏幕分辨率没法正常调节等等,都是因为NVIDIA驱动安装的问题,这不是本文要讨论的主要内容,读者可自行Google。分布式
加载CUDA运算库函数
TensorFlow运行设备/gpu:0学习
/gpu:0 这是TensorFlow平台默认的配置方法,表示使用系统中的第一块显卡。 本机软硬件配置: 系统:Ubuntu 16.04 显卡:NVIDIA GeForce GTX 745 4G 版本:TensorFlow 1.0 软件包:OpenCV 3.2.0、Pygame、Numpy、… 细心的朋友可能发现,笔者的显卡配置并不高,GeForce GTX 745,显存3.94G,可用3.77G(桌面占用了一部分),属于入门中的入门。对于专业作深度学习算法的朋友,这个显卡必然是不够的。知乎上有帖子教你们怎么配置更专业的显卡,有兴趣的能够移步。人工智能
神经网络算法是由众多的神经元可调的链接权值链接而成,具备大规模并行处理、分布式信息存储、良好的自组织自学习能力等特色。人工神经元与生物神经元结构相似,其结构对好比下图所示。
生物神经元
人工神经元
人工神经元的输入(x1,x2...xm)相似于生物神经元的树突,输入通过不一样的权值(wk1, wk2, ....wkn),加上偏置,通过激活函数获得输出,最后将输出传输到下一层神经元进行处理。 单神经元输出函数 激活函数为整个网络引入了非线性特性,这也是神经网络相比于回归等算法拟合能力更强的缘由。经常使用的激活函数包括sigmoid、tanh等,它们的函数表达式以下:
sigmoid函数
tanh双曲正切函数
这里能够看出,sigmoid函数的值域是(0,1),tanh函数的值域是(-1,1)。
卷积神经网络起源于动物的视觉系统,主要包含的技术是:
1. 局部感知域(稀疏链接) 全链接网络的问题在于:
好比,咱们看到一个美女,可能最早观察到的是美女身上的某些部位(本身体会)。
所以,卷积神经网络与人类的视觉相似,采用局部感知,低层的神经元只负责感知局部的信息,在向后传输的过程当中,高层的神经元将局部信息综合起来获得全局信息。
全链接与局部链接的对比(图片来自互联网)
从上图中能够看出,采用局部链接以后,能够大大的下降训练参数的量级。
2. 参数共享
虽然经过局部感知下降了训练参数的量级,但整个网络须要训练的参数依然不少。
参数共享就是将多个具备相同统计特征的参数设置为相同,其依据是图像中一部分的统计特征与其它部分是同样的。其实现是经过对图像进行卷积(卷积神经网络命名的来源)。
能够理解为,好比从一张图像中的某个局部(卷积核大小)提取了某种特征,而后以这种特征为探测器,应用到整个图像中,对整个图像顺序进行卷积,获得不一样的特征。
卷积过程(图片来自互联网)
每一个卷积都是一种特征提取方式,就像一个筛子,将图像中符合条件(激活值越大越符合条件)的部分筛选出来,经过这种卷积就进一步下降训练参数的量级。
如上,每一个卷积都是一种特征提取方式,那么对于整幅图像来说,单个卷积核提取的特征确定是不够的,那么对同一幅图像使用多种卷积核进行特征提取,就能获得多幅特征图(feature map)。
不一样的卷积核提取不一样的特征(图片来自互联网)
多幅特征图能够当作是同一张图像的不一样通道,这个概念在后面代码实现的时候用得上。
获得特征图以后,可使用提取到的特征去训练分类器,但依然会面临特征维度过多,难以计算,而且可能过拟合的问题。从图像识别的角度来说,图像可能存在偏移、旋转等,但图像的主体却相同的状况。也就是不一样的特征向量可能对应着相同的结果,那么池化就是解决这个问题的。
池化就是将池化核范围内(好比2*2范围)的训练参数采用平均值(平均值池化)或最大值(最大值池化)来进行替代。
终于到了展现模型的时候,下面这幅图是笔者手画的(用电脑画太费时,将就看吧),这幅图展现了本文中用于训练游戏所用的卷积神经网络模型。
卷积神经网络模型
图像的处理过程
能够看出,该模型实现了端到端的学习,输入的是游戏屏幕的截图信息(代码中通过opencv处理),输出的是游戏的动做,便是否点击屏幕。深度学习的强大在于其数据拟合能力,不须要传统机器学习中复杂的特征提取过程,而是依靠模型发现数据内部的关系。
不过这也带来另外一方面的问题,那就是深度学习高度依赖大量的标签数据,而这些数据获取成本极高。
有了卷积神经网络模型,那么怎样训练模型?使得模型收敛,从而可以指导游戏动做呢?机器学习分为监督学习、非监督学习和强化学习,这里要介绍的Q Network属于强化学习(Reinforcement Learning)的范畴。在正式介绍Q Network以前,先简单说下它的光荣历史。
2014年Google 4亿美金收购DeepMind的桥段,你们可能据说过。那么,DeepMind是如何被Google给盯上的呢?最终缘由能够归咎为这篇论文:
Playing Atari with Deep Reinforcement Learning
DeepMind团队经过强化学习,完成了20多种游戏,实现了端到端的学习。其用到的算法就是Q Network。2015年,DeepMind团队在《Nature》上发表了一篇升级版:
Human-level control through deep reinforcement learning、
自此,在这类游戏领域,人已经没法超过机器了。后来又有了AlphaGo,以及Master,固然,这都是后话了。其实本文也属于上述论文的范畴,只不过基于TensorFlow平台进行了实现,加入了一些笔者本身的理解而已。
回到正题,Q Network属于强化学习,那么先介绍下强化学习。
强化学习模型
这张图是从UCL的课程中拷出来的,课程连接地址(YouTube):
https://www.youtube.com/watch?v=2pWv7GOvuf0
强化学习过程有两个组成部分:
如图所示,在每步迭代过程当中,首先智能代理(学习系统)接收环境的状态st,而后产生动做at做用于环境,环境接收动做at,而且对其进行评价,反馈给智能代理rt。不断的循环这个过程,就会产生一个状态/动做/反馈的序列:(s1, a1, r1, s2, a2, r2.....,sn, an, rn),而这个序列让咱们很天然的想起了:
MDP:马尔科夫决策过程
马尔科夫决策过程与著名的HMM(隐马尔科夫模型)相同的是,它们都具备马尔科夫特性。那么什么是马尔科夫特性呢?简单来讲,就是将来的状态只取决于当前的状态,与过去的状态无关。
HMM(马尔科夫模型)在语音识别,行为识别等机器学习领域有较为普遍的应用。条件随机场模型(Conditional Random Field)则用于天然语言处理。两大模型是语音识别、天然语言处理领域的基石。
上图能够用一个很形象的例子来讲明。好比你毕业进入了一个公司,你的初始职级是T1(对应图中的 s1),你在工做上刻苦努力,追求上进(对应图中的a1),而后领导以为你不错,准备给你升职(对应图中的r1),因而,你升到了T2;你继续刻苦努力,追求上进......不断的努力,不断的升职,最后升到了sn。固然,你也有可能不努力上进,这也是一种动做,换句话说,该动做a也属于动做集合A,而后获得的反馈r就是没有升职加薪的机会。
这里注意下,咱们固然但愿获取最多的升职,那么问题转换为:如何根据当前状态s(s属于状态集S),从A中选取动做a执行于环境,从而获取最多的r,即r1 + r2 ……+rn的和最大 ?这里必需要引入一个数学公式:状态值函数。
状态值函数模型
公式中有个折合因子γ,其取值范围为[0,1],当其为0时,表示只考虑当前动做对当前的影响,不考虑对后续步骤的影响,当其为1时,表示当前动做对后续每步都有均等的影响。固然,实际状况一般是当前动做对后续得分有必定的影响,但随着步数增长,其影响减少。
从公式中能够看出,状态值函数能够经过迭代的方式来求解。加强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略。
策略就是如何根据环境选取动做来执行的依据。策略分为稳定的策略和不稳定的策略,稳定的策略在相同的环境下,老是会给出相同的动做,不稳定的策略则反之,这里咱们主要讨论稳定的策略。
求解上述状态函数须要采用动态规划的方法,而具体到公式,不得不提:
贝尔曼方程
其中,π表明上述提到的策略,Q π (s, a)相比于V π (s),引入了动做,被称做动做值函数。对贝尔曼方程求最优解,就获得了贝尔曼最优性方程。
状态值函数最优解
动做值函数最优解
求解该方程有两种方法:策略迭代和值迭代。
策略迭代分为两个步骤:策略评估和策略改进,即首先评估策略,获得状态值函数,其次,改进策略,若是新的策略比以前好,就替代老的策略。
策略迭代
从上面咱们能够看到,策略迭代算法包含了一个策略估计的过程,而策略估计则须要扫描(sweep)全部的状态若干次,其中巨大的计算量直接影响了策略迭代算法的效率。而值迭代每次只扫描一次,更新过程以下:
值迭代
即在值迭代的第k+1次迭代时,直接将能得到的最大的Vπ(s)值赋给Vk+1。
Q-Learning是根据值迭代的思路来进行学习的。该算法中,Q值更新的方法以下:
Q值更新方法
虽然根据值迭代计算出目标Q值,可是这里并无直接将这个Q值(是估计值)直接赋予新的Q,而是采用渐进的方式相似梯度降低,朝目标迈近一小步,取决于α,这就可以减小估计偏差形成的影响。相似随机梯度降低,最后能够收敛到最优的Q值。具体算法以下:
Q-Learning算法
若是没有接触过动态规划的童鞋看上述公式可能有点头大,下面经过表格来演示下Q值更新的过程,你们就明白了。
状态 | a1 | a2 | a3 | a4 |
S1 | Q(1, 1) | Q(1, 2) | Q(1, 3) | Q(1, 4) |
S2 | Q(2, 1) | Q(2, 2) | Q(2, 3) | Q(2, 4) |
S3 | Q(3, 1) | Q(3, 2) | Q(3, 3) | Q(3, 4) |
S4 | Q(4, 1) | Q(4, 2) | Q(4, 3) | Q(4, 4) |
Q-Learning算法的过程就是存储Q值的过程。上表中,横列为状态s,纵列为Action a,s和a决定了表中的Q值。
Q值更新公式
来更新Q值,这里咱们假设α是1,λ也等于1,也就是每一次都把目标Q值赋给Q。那么这里公式变成:
Q值更新公式
因此在这里,就是
本次Q值更新
那么对应的s3状态,最大值是0,因此
Q值
Q表格就变成:
状态 | a1 | a2 | a3 | a4 |
S1 | 0 | 1 | 0 | 0 |
S2 | 0 | 0 | 0 | 0 |
S3 | 0 | 0 | 0 | 0 |
S4 | 0 | 0 | 0 | 0 |
而后置位当前状态s为s3。
Q值更新
因此Q的表格就变成:
状态 | a1 | a2 | a3 | a4 |
S1 | 0 | 1 | 0 | 0 |
S2 | 0 | 0 | 0 | 0 |
S3 | 0 | 0 | 3 | 0 |
S4 | 0 | 0 | 0 | 0 |