增强学习训练AI玩游戏

1.游戏简介

符号A为 AI Agent。

符号@为金币,AI Agent需要尽可能的接取。

符号* 为炸弹,AI Agent需要尽可能的躲避。

游戏下方一组数字含义如下:

Bomb hit: 代表目前AI Agent所接取的炸弹数。

Coin hit:   代表目前AI Agent所接取的金币数。

Iteration:代表游戏已经进行的帧数,案例正常游玩视频,250ms一帧。高速状态下帧频未知。

Game Play:每帧会随机产生一个炸弹和一个金币,或者只产生一个炸弹或金币。每帧AI agent可以行动一次, 以及所有的炸弹和金币下降一格。

当金币和炸弹到最后一格时会自动消失,此时不在参与AI Agent碰撞。

2.游戏展示

增强学习训练AI玩游戏增强学习训练AI玩游戏

左为AI高速学习视频,右为AI正常游玩视频

3.实现原理

学习种类: 增强学习又称强化学习

学习细节:Q算法 +  值函数线性(参数)逼近,如果您还不知啥么是q算法,啥么是值函数,啥么又是线性参数逼近。那么我推荐您先看看一下资源。

A Painless Q-learning Tutorial (一个 Q-learning 算法的简明教程)

Q-learning toturial

然后,我来给你讲讲什么是线性参数逼近。我们由浅入深,先探讨一下向量。在2维空间中,我们可以用两个正交的二维基向量i,j来任意二维向量v。写作v = x*i+y*j; 我们只需调整x,y,也就是调整基向量的权重参数,就可以表示不同的向量。同理,N维空间,我们也可以用N个正交的N维基向量表示任意N维向量。那么需要调整的权重也会相应的增加到N个。 回到函数的问题,我们是否可以用类似的方式,用N个基函数的和来表示一个复合函数,并且通过修改每个函数的权重参数来表示不同的复合函数。很明显,答案是可以的。 那么现在的问题是如何调整这些权重,使它表达的复合函数更接近我的目标函数?

进一步对于强化学习来说,我们不知道目标函数的具体样子。我们通过不断的实验得知函数的输入输出模式为 in:a0 out:b0; in:a1 out:b1.......

所以我们要建立一个函数f,使其的输入输出与我们的目标函数的输入输出匹配即可。完美的匹配所有输入输出怕是找不到,退而求其次,我们去寻找平均情况下最好的匹配,即允许构造函数f与目标函数t某些输入与输出存在差异,但总体上差距最小。在这里我们使用随机梯度下降

Q(s, a) =  φ(s, a)Tθ (θ是有多个权重构成的向量,我们要不断调整θ, φ(s, a)T则为基函数,返回值为向量 )

C = 1/2(Q+(s, a) - Q(s, a))2 =1/2 (Q+(s, a) - φ(s, a)Tθ)2
∂C/∂θ = -φ(s, a)(Q+(s, a) - φ(s, a)Tθ).

θ ← θ + β φ(s, a)(Q+(s, a) - Q(s, a))  β为调整步长。

4.游戏内状态编码

Game State:

本文 AI Agent 采取对其上方4*3区域进行二进制编码。0代表空位置,1代表空间被bomb或coin占据。那么4*3区域需要24bit的数据来表示coin 和 bomb,以本文为例,前12位代表bomb后12位代码coin。相同位置的bomb和coin可以同时为0,代表既没有bomb也么有coin,但不能同时为1,即二者不可重叠。

对其进行二进制编码的好处为可以把state抽象成为一个int数值,大大了减少了描述state所需的空间。当然监测区域越大状态空间就越大,那么Agent就越智能。

Game Action:

左移,右移,不动。

Feature base φ(s, a):

用于描述当前状态特征的基函数,在程序中它不返回一个12维向量,而是增加参数i,代表获取第几个特征,函数输入为状态s和指令a,特征函数φ(s, a,i)的返回值取值范围为 -1,0,1。

φ(s, a)的计算需要使用当前的状态s 和 当下要执行的action。

Feature base  Weight θ :

θ也是12维向量,用以表示feature base中不同元素的权重。

Q value:

Q(s, a) = φ(s, a)Tθ, 这里是向量的点积,乘积的和。

5.具体实现方法

本游戏采用值函数线性参数化逼近,对动作状态值函数Q(s, a)进行线性参数话逼近。值函数近似多用于求解连续状态集或大规模状态集。因为state或action太多无法全部保存,所以需要抽象出一个函数,函数的参数为state和 action ,返回值为其分数。

最后我们的Q值函数可表示为:Q(s, a) = φ(s, a)Tθ,更新权重法则为:θ ← θ + β φ(s, a)(Q+(s, a) - Q(s, a)),

对于本文给出的小游戏,简单的使用随机梯度下降法可以对动作状态值函数进行线性近似。并可以取得较好的效果。

6.代码分享

相关代码,已上传

https://github.com/RonTang/QLearningForAiPlayGame/

需要的同学请自行获取。

7.未来展望&心语

研究机器学习只是笔者的业余爱好,故本文使用的最基本的强化学习算法,如有错误请耐心指正。如果读者想要进一步深入学习,不妨了解一下Google DeepMind的各种DQN,OpenAL刚刚出新的强化学习算法PPO。这些新的强化学习算法从效率和效果都有很大提高。当然,具体研究起来肯定是很复杂的,有兴趣的读者自己去研究吧。

作为一个游戏开发者,在适当的地方使用机器学习是很好的选择。谨记,我们做游戏是为了让玩家开心,不是为了让AI吊打玩家。至于人工智能学者总爱拿游戏做例子,一是为了方便向民间传播研究进度,刷存在感,拉投资。二是某些游戏的状态空间确实比较复杂。比如搞搞围棋,搞搞Dota2,搞搞星际2。

上一篇:【Unity 3D】学习笔记29:游戏的例子——简单的小制作地图


下一篇:Git 常用配置和使用