前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何丝滑地入门神经网络?写个AI赛车游戏,只训练4代就能安全驾驶

如何丝滑地入门神经网络?写个AI赛车游戏,只训练4代就能安全驾驶

作者头像
量子位
发布2019-04-24 10:31:00
9330
发布2019-04-24 10:31:00
举报
文章被收录于专栏:量子位量子位
车栗子 发自 凹非寺 量子位 出品 | 公众号 QbitAI
训练前

要了解机器学习、了解神经网络,一种非常有趣的方式,就是找个小游戏,自己实现一下。

游戏里的每一位AI玩家 (智能体) ,都是一个小小的神经网络。

一开始,它们什么都不懂,刚开局就GG。但有了进化算法 (Evolution) ,AI可以在一代一代更迭中,掌握强大的游戏技能。

成效显著

比如,在这个赛车游戏里,萌新车手跑出去不久便撞上了马路牙子。不过,用不了几代进化,就有AI车手可以毫发无损地跑完一周。

进化的赛车手

AI赛车手如何快速炼成?

首先,要有一个庞大的车队。

赛车AI的开发者,是一位叫做Johan Eliasson的程序猿。他的训练计划里,有650辆车同时训练。

第二,AI开车需要一些空间信息。

这5条黄线代表5个距离,指示离马路牙子还有多远;

除此之外,AI还需要知道自己当前的速率,以及方向

这样算来,神经网络一共会接受7个输入

第三,就是让神经网络不断进化。

输入七个值,处理一下,输出两个值

一个代表方向盘,按照数值大小,分为左转右转方向不变三种操作; 一个代表油门/刹车,按照数值大小,分成加速减速速率不变三种操作。

最开始,谁不知道游戏规则,输出值很随机。

第一代,死得快

650辆车冲出去没多久,路边就出现了大批车辆的尸体。

但重要的是,依然有硕果仅存的汽车,不止通过了第一次的右转考验,也机智地发现下一处弯道应该猛烈左转

虽然,它并没有成功掉头,但依然是下一代的希望:进化算法就是要在每一代里,选出最优秀的一只或者几只智能体,繁育出色的后代。

(这里,程序猿没有找到一种很好的方法,让系统自动选择出优质的个体,于是就手动马克了,反正也没有训练很多代。)

所以,第二代的650辆车,全是这一只智能体的子嗣,各自有些轻微的变异:神经网络的权重发生小小的变化。

变异是为了保持车队的多样性,期待从中生产出更加优秀的个体,繁育下一代。

第二代,马克三只

由于继承了优良传统,第二代汽车大部分都完成了第一次右转,还有一小部分掉头成功。

这一次,把冲到最前面的3辆车马克一下,它们差一点就能达成两次连续掉头的S形操作。

既然,第三代的父母有3位,那么繁育过程中除了变异之外,还涉及杂交:就是把不同的神经网络揉到一起:

第三代的表现更加精进,有的智能体完成了多次连续转弯,胜利在望。

第四代,便有智能体跑完一周,值得纪念:

程序猿说:这效果比想象的好多了,之前我还有点怀疑,现在只能说机器学习好厉害。

第四代车队中的佼佼者,已经不太撞到路肩,只是速度还很慢,就像一大波僵尸。

车队的主人表示,后面的主要任务就是训练速度。毕竟,这是赛车。

到了第十代,速度已经有了明显的提升,不过依然不算快:

第十代

不知训练了多少代,现在把每一代的优质选手放在一起跑。你看,好快:

这才是赛车

成果斐然之余,程序猿还请大家注意一个重点:

AI不知道自己在开车,不知道有跑道。它只接收七个输入的数值,不了解它们代表什么意思,也不知道自己输出的每一个决策,产生了怎样的效果。

就算这样,它还是学会了怎样在游戏世界里更好地生存。

不想开车?还有其他游戏

虽然,赛车游戏的视频,没有讲到程序猿用了怎样简单的神经网络。不过,可以通过另一个简单的游戏,来感受一下:

Flappy Bird

这个HTML 5实现, 也是进化算法和神经网络共同的结晶。而且开源了。

它的作者ssusnic说,神经网络部分,用的是突触神经网络 (Synaptic Neural Network) 库。

没有650辆车那么多,种群里只有10只小鸟。每一只,都是一个三层的神经网络:

输入层:两个神经元 隐藏层:六个神经元 输出层:一个神经元

输入两个值,代表小鸟当前距离下一个障碍物的相对位置,分成水平距离 (x) 和竖直距离 (y) 。

经过隐藏层的处理,输出一个0-1之间的数值,决定下一步要不要扇翅膀:

如果大于0.5,就扇翅膀,反之就不操作。

第一代

第一代的小鸟,都是随机神经网络 (Random Neural Networks) ,集体见光死。

全部阵亡之后,要选出四只最优质的小鸟去繁殖。问题来了,肉眼看去相差无几,要选哪几只?

并不需要手动选择,而是用一个适应度函数 (Fitness Function) :

适应度 = 小鸟存活的最远距离 - 小鸟到下一个障碍物的距离

这里,讨论水平距离

适应度分数排名前四的小鸟,按下面的规则繁殖10个后代:

· 前两名,杂交出一个后代 · 4只中随机选两只,杂交出三个后代 · 4只中随机选两只,分别直接复制,生成两个 (和上代一样的) 后代 · 给每个后代加入一些变异

就这样,来到第11代,已经有小鸟飞出很远且毫发无伤:

第23代,完全碾压,可以换个游戏了:

吃豆豆

当然,不是所有游戏都像小鸟扇翅膀这样简单。

吃豆人 (Pacman) 就是个更复杂的栗子。比如,前面要躲避的障碍物都是静止的,Pacman的敌人是移动的,穷追不舍。

重点是,为了抓到Pacman,四个敌人还有各自不同的运动规则:

红色鬼,直接瞄准Pacman的位置进发; 粉色鬼,瞄准Pacman前方的第四格; 蓝色鬼,利用Pacman和红色鬼的位置来搞伏击; 橙色鬼,原本和红色鬼一样,但当它和Pacman的距离近到8格以内,就会朝一个角落退缩,那是它出发的地方。

并且,Pacman吃到无敌大豆豆的时候,敌人还会从追击模式转成逃跑模式。

复杂的游戏,自然也需要更加精密的算法,来帮智能体进化。

名叫Code Bullet的程序猿,就用了一种叫做NEAT的神经进化算法。

这种方法很特别,神经网络在迭代过程中,不止权重会变化,网络结构也会变复杂

而网络结构越复杂,就可以支持越复杂的行为,让Pacman在险恶的世界里存活。

虽有强大的算法,训练还是要由浅入深

先不加无敌大豆豆,也不加敌人,给AI一个简单的世界。

这样它就能吃光所有豆豆?不存在的。

第一代最优秀的智能体,也只会右转不会左转,还把自己困在一处,永远走不出去。

第二代,有的选手学会了左转,但依然会困住。

……

第十八代,眼看快要吃光豆豆,AI还是困死了自己。

在平静中训练20代之后,趁AI不注意把敌人放出来,又要从手忙脚乱开始重新适应:

不过好在,智能体学以很快便学会了躲避敌人:

又过了40代,是时候加入无敌大豆豆了。

这一层防护令AI如有神助,就像在经历了40代卧薪尝胆之后,开启了复仇模式,疯狂追击。

终于,有智能体在第七十三代通关成功:

视频的画外音里,程序猿的声音都激昂了起来,这场战役的胜利他期待已久。

除了发表获奖感言,谢过各路亲友的支持,他也没忘在GitHub上分享代码 (传送门见文底) 。

动手吧,少年

同学,你也去搭个神经网络打游戏吧,呆萌的游戏也能打出热血的气质。

以后,神经网络可能就是你朋友了。

(友情提示:虽然赛车游戏没有开源代码,但OpenAI Gym里面有赛车场,也可以去试试。)

赛车游戏视频传送门: https://www.youtube.com/watch?v=wL7tSgUpy8w

OpenAI Gym赛车场: https://gym.openai.com/envs/CarRacing-v0/

Flappy Bird代码传送门: https://github.com/ssusnic/Machine-Learning-Flappy-Bird

Pacman代码传送门: https://github.com/Code-Bullet/PacNeat (NEAT算法) https://github.com/Code-Bullet/PacmanGame (搭建游戏环境)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 量子位 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 进化的赛车手
  • 不想开车?还有其他游戏
    • Flappy Bird
      • 吃豆豆
      • 动手吧,少年
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档