查看: 2690|回复: 1

[征集/转载]使用机器学习投篮,轻松搞定篮筐投球!

[复制链接]
  • TA的每日心情
    开心
    2019-11-4 13:48
  • 签到天数: 14 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2018-8-20 16:07:32 | 显示全部楼层 |阅读模式
    分享到:
    文 / Abe Haskins(Twitter,Github)

    我们将在本文中探讨如何使用 Unity3D 和 TensorFlow 来教授 AI 执行简单的游戏任务:投球入篮。完整的源代码可于Github 上获取。如有任何疑问,请通过 Twitter 联系我。
    注:Github 链接
    https://github.com/abehaskins/tf-jam

    1.gif


    游戏简介
    在这款游戏中,玩家的主要目标就是将球投入篮筐中。乍一听,这不难做到,但当您热血沸腾、心跳加速,旁边又有观众在热情欢呼时,投中的难度就会加大。我现在谈的是经典美式篮球比赛吗?不,没这回事。我所讲的是 Midway 经典街机游戏 “NBA 嘉年华 (NBA Jam)”。

    如果您玩过 “NBA 嘉年华 (NBA Jam)” 或由其激发灵感创作的任意一款游戏(包括真实版 NBA 联赛,我认为该联赛便取自于该款游戏),便会知道投篮技巧在玩家眼中就是小菜一碟。您只需按住投射按钮,然后等待最佳时机松开即可。但您有否想过这一投射动作 在游戏中 是如何进行的?所选球的运动弧线是怎样的?投球力度如何?计算机如何确定投射角度?

    如果您脑瓜灵光、精通数学,或许可以用纸和笔计算出这些问题的答案,但本篇博文的作者在 8 年级代数考试中都不及格,更别提像那些 “聪明人” 一样计算出答案了。所以,我需要另辟蹊径。

    我们不会采用更简单、快速且高效的数学方法来计算投篮问题,而是会探讨其中的原理,并学习一些 TensorFlow 基础知识,然后尝试向一些难搞的篮筐投球。


    入门准备
    开始项目之前,我们需要准备以下工具。

    • Unity:用于模拟篮球和创造物理环境
    • Node.js 和 TensorFlow.js:用于训练模型
    • TensorFlowSharp:用于通过机器学习代理 (ML-Agents) 资源软件包将模型嵌入 Unity
    • tsjs-converter:用于将 TensorFlow.js 模型转换为可在 Unity 中使用的图表。
    • Google 表格:用于轻松直观地呈现我们的线性回归分析


    即使您对以上任一技术均不擅长,也无妨!(我也不是都精通!)我会尽力阐明这些工具的协同运作方式。使用如此众多的技术会有一个弊端,那就是我在介绍时无法面面俱到,涵盖所有细节,但我会尽可能提供更多外部教育资源的链接!


    下载项目
    我不打算一步步重建该项目,所以建议您下载 Github 上的源代码,并紧跟我的讲述节奏。
    注:Github 上的源代码链接
    https://github.com/abehaskins/tf-jam

    注意:您需要下载并导入 机器学习代理 (ML-Agents) Unity资源软件包,以便在 C# 中使用 Tensorflow。如果您收到无法在 Unity 中找到 Tensorflow 之类的错误,则需确保遵循 Unity 的 TensorflowSharp 安装文档。

    注:机器学习代理 (ML-Agents) Unity 链接
    https://github.com/Unity-Technologies/ml-agents
    Unity 的 TensorflowSharp 安装文档链接
    https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Using-TensorFlow-Sharp-in-Unity.md


    我们的目标是什么?
    为简便起见,我们为该项目设定的预期结果也很简单。我们想要解决如下问题:如果投球手与篮筐之间的距离为 X,则使用力度 Y 投球。就这么简单!我们不会试图盯住球或以任何其他花样为目标,我们只想弄清楚要使用多大力度投球才能投中。

    如果您有意深究如何在 Unity 中训练更复杂的 AI,请前往 Unity 查看更多完整的机器学习代理 (ML-Agents) 项目。我在文中介绍的方法简单易行,但未必是最佳实践(因为我也正在学习中!)

    我对 TensorFlow、机器学习和数学知识的掌握也很有限,谈不上精通。本文纯属自娱,诸君请勿尽信。


    篮筐和球
    前面提到过,我们的主要目标是投球入篮。要将球投入篮中,我们首先要有篮筐和球。这时,Unity 就可以派上用场了。

    如果您不熟悉 Unity,只需知道这是一个游戏引擎,可为所有平台构建 2D 和 3D 游戏。Unity 内置物理引擎、基本的 3D 模型和出色的脚本运行时 (Mono),支持使用 C# 对游戏编程。

    我并非艺术家,只是拖动了一些组块,拼凑起一个球场场景。

    2.jpg
    红色组块显然 代表 我们的球员。篮筐事先已设置隐形触发器,能够帮助我们检测物体(球)何时穿过篮筐。

    3.jpg
    在 Unity 编辑器中,可以看到以绿色轮廓表示的隐形触发器。图中显示有两个触发器。如此,我们可以确保仅计算从篮筐顶部落至底部的篮球数量。

    如果看一下 /Assets/BallController.cs(每个篮球实例均有此脚本)中的 OnTriggerEnter 方法,便能了解如何将这两个触发器结合使用。

    此函数会执行以下任务。首先,函数要确保顶部和底部的触发器均被击中;其次,它会改变篮球的材质,向我们直观展示球已入篮;最后,它会记录我们最关心的这两个关键变量:distance 和 force.y。


    投篮
    请打开 /Assets/BallSpawnerController.cs。这是一个依存于投球手的脚本,负责生成篮球并试图投中篮筐。您也可在 DoShoot() 方法的末尾处查看这段代码。

    此代码会先实例化一个新的篮球实例,然后设定投篮力度以及投球者与篮板的距离(这样便于我们稍后记录,正如上段代码中所示)。

    如果您仍未关闭 /Assets/BallController.cs,可以查看我们的 Start() 方法。我们在创建新篮球时将会调用此代码。

    换言之,我们会创建一个新球,为其设定一定的力度,然后设定 30 秒后篮球自爆,这样我们就能够源源不断地处理新产生的球,并确保一切都在合理范围内运行。

    下面我们尝试运行以上代码,看看这位全明星球员的投篮表现。您可以点击 Unity 编辑器中的 ▶️(“播放”)按钮,之后将会看到……

    4.gif

    我们的球员(暂且称它为 “小红”)几乎百发百不中。

    为什么小红的表现如此糟糕?答案就在于 Assets/BallController.cs 中有一行代码写的是 float force = 0.2f。这行代码大胆断定每次投篮动作都应完全相同。如您所见,Unity 会严格做到 “完全相同”。使用相同力度再三重复动作,同样的物体总是以完全相同的方式弹回。所有动作整齐划一。

    这当然不是我们想要的结果。若不尝试新的突破,我们永不可能训练出堪比勒布朗 (Lebron) 的卓越投球手,所以我们要做一些改进。


    随机投篮,收集数据
    我们可以简单将力度改为随机大小来引入一些随机噪音。

    这样,我们就会产生不同的投篮结果,最终发现投篮成功时的状况,当然,这可能也要花些时间才能猜对结果。

    5.gif
    小红表现很差,虽然偶尔也会投中一球,但纯靠运气。没关系。此时,任何投篮都能作为可供使用的数据点。我们稍后会谈到这一点。

    同时,我们不希望只能从一个位置投球。我们希望小红可以从任意距离成功投篮(如果足够幸运的话)。在 Assets/BallSpawnController.cs 中查找以下行,并取消对 MoveToRandomDistance() 的注释。

    再次运行后,我们会看到小红每次投完篮后都会在球场上兴奋地跳来跳去。

    6.gif

    随机移动与随机力度相结合会产生一种非常奇妙的东西:数据。如果此时查看 Unity 中的控制台,您会看到每次成功投篮的数据都有记录。

    7.gif

    每次投中后,系统都会记录目前为止的进球数量、投射位置与篮筐的距离以及投射所需的力度。但这种进度太慢,我们需要进行加速。返回至先前添加 MoveToRandomDistance() 调用处,然后将 0.3f(每次投篮延迟 300 毫秒)改为 0.05f(延迟 50 毫秒)。

    现在再投篮,我们会看到进球数大大增加。

    8.gif

    这种训练方式效果不错!从后面的计数器中可以看到:进球率已达 6.4% 左右。但小红现在仍比不上斯蒂芬·库里。说到训练,我们真的从中学到什么了吗?TensorFlow 是如何起作用的?乐趣何在呢?这就要看下一步了。现在,我们准备从 Unity 中提取上述数据,并构建模型来预测所需力度。


    预测、模型和回归
    在 Google 表格中查看数据
    在深入探讨 TensorFlow 之前,我想看看数据,所以我让 Unity 一直运行,直到小红成功投进大约 50 球。若您查看 Unity 项目的根目录,应该能看到新文件 successful_shots.csv。这是 Unity 中对每次成功进球产生的原始转储文件!我从 Unity 中导出此文件,以便在电子表格中轻松进行分析。

    .csv 文件只有三行内容,分别为 index、distance 和 force。我已将此文件导入 Google 表格,并创建了一张绘有趋势线的散点图,此图为我们直观展示了数据的分布情况。

    9.jpg
    哇!快看。我是说,看看这张图。 我想说太赞了……好吧,我得承认,其实我刚开始的时候也看不懂这张图。我们下面就来具体分析一下这张图表中,Y 轴代表投射力度,X 轴代表投射距离,这些坐标点在两轴之间分布开来。图中显示了所需力度与投射距离之间具有十分明显的相关性(尽管会有个别严重离群的随机异常值)。

    实际上,您也可以这样解读:“TensorFlow 对此非常擅长。”

    该用例简单易懂,但 TensorFlow 还有一项卓越功能,即能够让我们使用类似代码构建更为复杂的模型(如果我们愿意)。例如,在完整的游戏中,我们可以加入更多特征,如另一方的投射位置及其过往的盖帽频率统计资料,以此来确定我们的球员应该投篮还是传球。

    创建 TensorFlow.js 模型
    在您最爱的编辑器中打开 tsjs/index.js 文件。该文件只是一个脚本,与 Unity 无关。我们可以使用该脚本基于 successful_shots.csv 中的数据来训练模型。

    下面介绍这种训练及保存模型的完整方法……

    如您所见,操作起来不是很复杂。我们从 .csv 文件中加载数据并创建一连串 X 和 Y 坐标点,听起来与上文的 Google 表格操作十分类似!在此处,我们要求模型 “拟合” 这些数据。完成后保存模型,以备日后使用!

    很遗憾,TensorFlowSharp 并不接受 Tensorflow.js 所能保存的模型格式。为此,我们需要进行一些巧妙的转换,以便模型能够嵌入 Unity。我用了一些实用程序来帮助解决此问题。大致过程如下:将模型从 TensorFlow.js 格式转换为 Keras 格式,在此格式中创建检查点,并将检查点与 Protobuf Graph Definition 合并,得到 Frozen Graph Definition,然后即可将其嵌入 Unity。

    幸运的是,如果您想快速开始,也可以跳过 这些步骤, 只运行 tsjs/build.sh;若一切顺利,它便能自动执行所有步骤并在 Unity 中填充冻结模型。

    在 Unity 内部,我们能够通过 Assets/BallSpawnController.cs 中的 GetForceFromTensorFlow() 查看模型的交互情形。

    在作出图表定义时,您将定义一个包含多个步骤的复杂系统。本例中,我们将自己的模型定义为单一密集层(具有隐式输入层),这表示我们的模型会接受单个输入并会生成相应输出。

    在 TensorFlow.js 中使用 model.predict 时,它会将您的输入自动馈送至正确的输入图节点,并在计算完成后为您提供该节点的输出。然而,TensorFlowSharp 的运作方式与之不同,需要我们直接透过名称与图表节点交互。

    鉴于此,我们便需将输入数据转换为图表可接受的格式,并将输出数据发送给小红。


    游戏日!
    我使用上述系统对模型作出了部分变动。该模型仅使用 500 次成功进球数据进行了训练,下图展示小红使用该模型的投篮效果。

    10.gif
    我们可以看到进球率约提升了 10 倍!如果我们对小红训练数小时,然后收集 1 万或 10 万次成功进球数据,结果又会如何呢?他的投球表现无疑会进一步提升!这就交给您来实现吧。

    强烈推荐您查看 Github 上的源代码,如果您训练的成功率超过 60%,欢迎在 Twitter 上给我留言(友情提示:60% 以上的成功率绝对能够实现,可以返回查看第一张 GIF 动画,看看您对小红的训练成效!)

    评分

    参与人数 1与非币 +25 收起 理由
    satoll + 25 感谢分享

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情

    2024-4-8 15:13
  • 签到天数: 42 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2018-8-20 16:20:22 | 显示全部楼层
    虽然和这次AI征集的主题有点偏离,但是是很精彩的分享哇
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-19 18:02 , Processed in 0.140292 second(s), 21 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.