我们制造了一个人工智能机器人,可以学习如何在名为Flappy Bird的游戏中得分最高。
这样,我们的小鸟就能安全地飞过一些障碍物了。在最好的情况下,它永远不会死。欢迎阅读这篇完整的HTML5教程,本文展示了针对Flappy Bird游戏设计的**机器学习算法**。本实验的目标是使用**神经网络**和**遗传算法**编写一个人工智能游戏控制器。
因此,我们打算创建一个人工智能机器人,它能够学习如何把Flappy Bird这个游戏玩出最高分。这样,我们的小鸟就能安全地飞过一些障碍物了。在最好的情况下,它永远不会死。
在阅读项目背后原理的时候,你可以在本教程末尾下载源代码。所有的代码都是基于Phaser框架编写的。此外,我们还使用了Synaptic神经网络库来实现神经网络。
演示程序
首先,让我们从演示程序开始,看一下游戏过程中的算法:
点击此处进入全屏演示(需科学上网)
视频演示
除了上面的演示程序之外,你还可以观看这部简单展示了算法的视频短片。这对那些喜欢快进的人来说简直太棒了!
(需科学上网)
什么是机器学习算法
根据1959年亚瑟·塞缪尔(Arthur Samuel)的说法,机器学习是让计算机在不显式编程的情况下行动的科学。一般来说,这是一个循序渐进地改进初始随机系统的学习过程。
因此,实现人工智能的目标是通过对一个差的系统进行模型参数的微调来找到一个适当的解决方案。为此,机器学习算法使用了许多不同的方法。
对于本项目,机器学习算法(ML,Machine Learning)的主要方法是基于神经演化的。这种机器学习在形式上使用了遗传算法(GA,Genetic Algorithm)等进化算法来训练人工神经网络(ANN,Artificial Neural Network)。
所以,在这个例子中,我们可以说:机器学习 = 遗传算法 + 人工神经网络(ML = GA + ANN)。
人工神经网络
人工神经网络是机器学习算法的一个子集。它的诞生受到了生物神经网络结构和功能的启发。这些网络由许多发送信号的神经元组成。
因此,要创建一个人造大脑,我们需要模拟出神经元并将它们连接成一个神经网络。
通用人造神经网络是由输入层、一个或多个隐藏层,以及输出层组成。每一层都有一定数量的神经元。输入和输出神经元直接与外部环境相连,而隐藏的神经元则将以上两者连接起来。
在本项目中,每个单元(小鸟)都有自己的神经网络作为AI大脑来玩游戏。它由以下三层组成:
一个具有2个神经元的输入层,表示一只小鸟看到的东西: - 与最近间隙的水平距离 - 与最近间隙的高度差
具有6个神经元的隐藏层
具有1个神经元的输出层,提供如下动作: - 如果 输出 > 0.5,则扇动翅膀,否则什么也不做
下图显示了本演示程序的神经网络架构:
遗传算法
在谈论到机器学习算法的时候,可以说,遗传算法可以用来训练和改进神经网络。
遗传算法是一种基于搜索的优化技术,其灵感来自于自然选择和遗传过程。它采用选择、交叉和变异相结合的方法来进化初始随机种群。
以下是遗传算法实现的主要步骤:
用**随机神经网络**创建10个单元(小鸟)的初始鸟群
让所有的单元同时使用自己的神经网络进行游戏。
对于每个单元,计算其**适应度**函数来衡量其质量(详情请参阅下面的“适应度函数”章节)
当所有的单元都死亡时,使用遗传算子来评估当前鸟群以生成下一个鸟群(详情请参阅下面的“替换策略”章节)
返回到步骤2
适应度函数
除了遗传算法(步骤3)之外,下面我们将了解一下有关适应度函数的一些细节,例如,适应度函数是什么,如何定义。
因为我们希望通过使用最好的小鸟来进化鸟群,所以需要定义一个适应度函数。
通常来说,适应度函数是衡量对象质量的指标。我们会度量每只鸟的质量,然后选择最适合的小鸟,并用它来重新生成下一批小鸟。
在本项目中,我们会根据小鸟飞行的距离来进行奖励。同时,根据小鸟当前到最近间隙的距离进行惩罚。所以,在这过程中,飞行了相同距离的小鸟之间就会产生差别。
因此,适应度函数是“小鸟飞行的总距离”和“与最近间隙的距离”之间的差。
替代策略
除了遗传算法(步骤4)之外,以下是将自然进化应用于小鸟死亡的步骤。最好的小鸟生存下来,然后他们的孩子就以下面这种方式来替代最糟糕的小鸟:
按照适应度对当前所有的小鸟进行排序
选择前4名(胜利者),并将他们直接传递给下一个鸟群
创建一个后代作为两个最佳胜利者的交叉产品
创建3个后代作为两个随机胜利者的交叉产品
创建2个后代作为两个随机胜利者的直接副本
对每个后代应用随机突变,以增加一些变异
源代码
这是源代码下载链接:
要求
由于程序是使用HTML5基于Phaser框架和Synaptic神经网络库编写的,因此需要这些文件:
game
整个游戏逻辑在**game**文件中实现。它由以下类组成:
A
,主程序,包含以下基本功能:
_preload()_
预加载所有资源_create()_
创建所有对象并初始化一个新的遗传算法对象_update()_
运行游戏的主循环,并使用遗传算法进化鸟群_drawStatus()_
显示所有小鸟的信息
TreeGroup 类
,扩展了Phaser Group类,用于移动障碍物,包含顶部和底部的树。Tree 类
,扩展了Phaser Sprite类,用来表示一棵树。Bird 类
,扩展了Phaser Sprite类,用来表示一只鸟。Text 类
,用于绘制文本的Phaser BitmapText类。
gene
遗传算法在**gene**文件中实现,该文件由以下类组成:
GeneticAlgorithm 类
,处理所有遗传算法操作的主类。它需要两个参数:**_max_units_**用于设置小鸟的总数量,**_top_units_**用于设置获胜者的数量。以下是其基本函数: -_reset()_
重置遗传算法参数 -_createPopulation()_
创建新的鸟群 -_activateBrain()_
激活小鸟的AI神经网络,并根据输入获取其输出动作 -_evolvePopulation()_
通过使用遗传算子(选择、交叉和突变)来让鸟群进化 -_selection()_
从当前鸟群中选择最佳小鸟 -_crossOver()_
执行在两个父节点之间的单点交叉 -_mutation()_
对后代进行随机突变
结论
在本教程中,我们成功实现了一个会学习如何玩Flappy Bird游戏的AI机器人。经过几次迭代,可以得到一个几乎无敌的玩家。为了达到这一目标,采用了两种机器学习算法:人工神经网络和遗传算法。
你可以尝试更改代码中的一些参数,看看会发生什么。例如,你可以更改隐藏层中的神经元数量或小鸟的数量。此外,你还可以尝试以某种方式修改适应度函数,修改一些物理参数,比如障碍物之间的距离、重力等等!
试着将这里的进化理念应用到其他游戏中去吧!
文章原标题《Machine Learning Algorithm for Flappy Bird using Neural Network and Genetic Algorithm》,作者:SRDJAN,译者:夏天,审校:主题曲哥哥。