专栏名称: 高可用架构
高可用架构公众号。
目录
相关文章推荐
架构师之路  ·  MySQL必知必会(再版上架,送10本) ·  2 天前  
架构师之路  ·  中国程序员最大的悲哀!(1100W+阅读) ·  4 天前  
架构师之路  ·  漏洞!近千块的技术大会,1折蹭? ·  3 天前  
51好读  ›  专栏  ›  高可用架构

手把手学会人工智能:TensorFlow实现马里奥赛车自动驾驶,含源码

高可用架构  · 公众号  · 架构  · 2017-05-16 09:54

正文

这次年假没啥事做,作者想着试试完成一个两年前就已开始的项目:训练人工智能神经网络来玩《马里奥赛车 64》游戏。因为一年前做过一些机器学习,现在想蹭个热点,TensorFlow 越来越火了。


项目:使用 TensorFlow 来训练一个模型玩《马里奥赛车 64》游戏。


目标:作者想做个人人都能跟着“说明书”一步步理解和实现的机器学习 demo。


在不断的玩《马里奥赛车》游戏并且用 C 语言开发了一个模拟器后,作者得到了一个漂亮的结果。


下图是驾驶未经训练的 Royal Raceway 部分:



动画参看:

https://media.giphy.com/media/1435VvCosVezQY/giphy.gif


下图是驾驶 Luigi Raceway 部分:



动画参看 https://youtu.be/vrccd3yeXnc



达到上面的成绩还是不容易的,作者想分享自己的经验和学习到的知识。


训练数据集


为了创建一个训练数据集,作者编写了一个程序来截图 Xbox 玩《马里奥赛车》游戏的桌面。然后作者跑一个任天堂 N64 模拟器,定位截图区域的位置,如下图:



这只是作者开始该项目以来完成的部分成果。有趣的是在几年来做该项目中发现自己代码风格的变化以及工具选用的变化。


机器学习模型


刚开始是修改 TensorFlow tutorial 的字符识别的例子( MNIST 数据集),改变输入层和输出层的大小,因为作者准备的图片比 MNIST 数据集中的 28 x 28 要大。修改图片大小的工作是非常无趣的,但是 TensorFlow 提供了很好的函数来帮助我们。


后来,作者转而使用 Nvidia’s Autopilot 来开发自动驾驶部分。这简化了数据预处理的代码,该模型可以直接将彩色图片转化成向量,而不需要手动转化成灰度图再展开为向量。


训练模型


为了训练一个 TensorFlow 模型,你必须定义一个 TensorFlow 优化函数。在 MNIST tutorial 中使用的优化函数是错误分类的总和,而 Nvidia’s Autopilot 中使用的是预测值和角度传感记录的差值。对于本项目来讲,有一些重要的游戏手柄输出。作者使用预测输出向量和记录值两者的欧式距离作为优化函数。


TensorFlow 一个最重要的特征之一是显式的函数定义。High Level 的机器学习框架会抽象,但是 TensorFlow 逼着开发者来思考发生了什么,帮助他们消除机器学习的神秘。


模型训练其实是本项目最容易的一部分。TensorFlow 有着优秀的官方文档,以及大量的 tutorial 和源代码。


一显身手


训练完模型,作者打算让其在《马里奥赛车 64》上一显身手。但是好像还缺点啥:如何将模型训练的结果转换到任天堂 N64 模拟器?首先,作者使用 python-uinput 来发送输入事件。该功能在作者以前的几个项目中能够作为游戏手柄工作,但是不幸地,这次不行。


接着作者深挖开发出 mupen64plus-input-sdl,所以作者觉得开发自己的输入插件是明智的。


编写一个 mupen64plus 输入插件


好长一段时间没写过一个像样的 C 程序了,我拿到一个原始输入驱动程序,做了一些简单的复制粘贴工作,我的目标是在模拟器中编译和运行一个插件。 当插件加载时,仿真器检查几个函数定义和错误(如果有的话)。这意味着我的插件需要定义几个空函数。


当插件工作后,我搞明白了如何设置控制器输出,让马里奥能够在跑道上无限的跑起来。



下一步是向本地服务器询问输入的内容。 这需要在 C 中发出 http 请求,这证明是个复杂的任务。人们抱怨分布式系统很难,的确是这样!经过解决几个小问题之后,我终于完成了消费数据并将其输出到内部的 N64 仿真器。


我完成的输入插件可以在GitHub上找到。

https://github.com/kevinhughes27/mupen64plus-input-bot


玩《马里奥赛车 64》游戏


现在是见证奇迹的时刻了,不过第一场比赛太让人失望了:马里奥直接开车撞到墙上,连一个弯都没转。


为了 debug,作者增加了一个手动的控制,当需要时才从 AI 获取控制。作者通过试玩,观察返回的输出结果,提出了两件需要 fix 的点:


  1. 重新检查训练数据时,作者发现偶尔有些截图是模拟器窗口的图片。解决方法是简单的从数据集中移除,继续训练。

  2. 作者注意到《马里奥赛车 64》是一种比较急速的游戏,典型的是你不能平缓的转弯。通常,游戏者需要在大转弯时来个急速调整。由于数据的混淆,一些《马里奥赛车 64》的图片在转弯的中间,假设模型学习从来不转弯,而这将导致一些小误差。模型训练仍然是一个优化问题,如果数据集有问题,那训练的结果也会这样。


记住这些继续玩《马里奥赛车 64》游戏来记录新的训练数据。


随着上面两点的调整,作者得到更好的结果,见文章开始部分。


最终畅想


TensorFlow 是一个超级棒的 low level 抽象的深度学习框架。受益于 cuDNN,TensorFlow 的计算速度不错,并且梯度下降算法也是顶尖的。不过,如果再做另外一个深度学习项目的话,作者说不会直接使用 TensorFlow,而是更愿意尝试 keras ,keras 是基于 TensorFlow 基础上加了一些语法糖。


在寒假的几周里,作者已经能使用 Google 的自动驾驶技术来驾驶虚拟的赛车。数据训练大概 20 分钟之后,作者的 AI 已经可以驾驶大部分简单的赛道,Luigi Raceway 和未经训练的 racetack。作者期待使用更多的数据来构建一个完整的 AI 自动驾驶马里奥赛车 64 游戏。


源代码


  • http://github.com/kevinhughes27/TensorKart

  • http://github.com/kevinhughes27/mupen64plus-input-bot


延伸阅读


OpenAI 公司开发的 AI 框架。

https://openai.com/blog/universe/


Commaai 是一家致力于研发基于人工智能技术的汽车无人驾驶系统的公司,也发布他们的自动驾驶的源代码。

https://github.com/commaai/research


本文作者 KEVIN HUGHES,由侠天翻译,转载请注明出处,技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。


侠天,专注于大数据、机器学习和数学相关的内容,并有个人公众号:bigdata_ny 分享相关技术文章。


推荐阅读



高可用架构

改变互联网的构建方式


长按二维码 关注「高可用架构」公众号