上周,在三星开发者大会(Samsung Developer Conference, SDC),出现了一个十分有趣的SDC展位,展位的主人是Gyroscope的团队,他们为了在展台上呆两天而不显得无聊,做了一件事:他们让Gyroscope的AI在超级任天堂上面征战“街头霸王2:究极格斗”,期望通过与各个角色之间的搏斗,让Gyroscope学会格斗技巧。
Gyroscope的AI并不会玩电子游戏,他们的团队也没有超级任天堂的软件开发包。所以在SDC大会之前,Gyroscope团队先设法从“街头霸王2:究极格斗”中提取了游戏信息,从而建立了Gyroscope的超级任天堂SDK。然后让Gyroscope的AI与游戏内置的计算机对手进行上千场的游戏比拼,同时他们不断地调整AI参数,让它更加适应这个特殊的应用程序。
训练AI
在训练AI之前,首先要弄清楚究竟要解决什么问题,Gyroscope团队把“街头霸王2”的问题抽象为强化学习问题。在强化学习问题中,AI要评估各种方案,选择要采取的行动,最后获得“回报”。但这一次AI程序的目标是根据过去观察到的行为,采取最佳的行动,从而获得最高的“奖赏”。所以在开始应用AI之前,Gyroscope团队需要先定义“街头霸王2”的观察内容,换一个意思来讲,就是要让人工智能“看到”什么,以及如何行动从而获得某种“奖赏”。
观察内容
观察内容可以想象成AI在环境中“看到”的东西,比如人类观察游戏的时候,首先看到的是每个角色,以及角色的跳跃、移动、踢等动作,同时还能看到角色的血条与计时器,Gyroscope团队需要把这些信息提取出来,转化成AI可以理解的格式,这种格式通常被称为“观察空间”。
在强化学习中,观察空间有两种常见的思路,传统的方法是测量人类认为与问题相关的具体信号;现代的方法是为AI提供每次行动后的全部环境图像,让AI决定图像中的重要元素。现代的方法要比传统方法更好,因为它有更好的普适性,不需要对特征的重要性做过多的假设,但这种方法往往需要更长的训练时间,因为时间的限制,Gyroscope团队选择了传统方法,并手动定义观察空间。
观察空间被定义为:
• 每个玩家的X和Y坐标
• 每个玩家的血条
• 每个玩家是否在跳跃
• 每个玩家是否蹲伏
• 为每个玩家的动作编号
• 玩家之间X和Y坐标差的绝对值
• 游戏时钟
游戏观察空间示例,这个观察空间不重复的观察点达到了万亿甚至更多
行动
当AI观察完环境之后必须采取行动,使角色行动起来最简单的方法是采用超级任天堂手柄上的按钮:上、下、左、右、A、B、X、Y、L、R。这几个按钮可以形成很多个按钮组合,如果要考虑所有可能的按钮组合,会产生1024(2^10)个可能的行动。这个可能的行动太多了,即使AI最终能够学会,也需要训练很长一段时间才能知道哪些行为有效,哪些不行,而且并不是所有的按钮都可以随时按下,许多动作要通过按键顺序才能达到更好的效果。
基本动作
“街头霸王2:究极格斗”充分利用了CAPCOM摇杆和超级任天堂手柄。下面的示意图包括8种基本控制的位置以及他们在游戏中的用法。
方向控制(来自街头霸王2:究极格斗游戏说明书)
从12点方法顺时针:跳跃,向前翻转,向前,进攻蹲伏,蹲伏,防御蹲伏,防御,向后跳跃。
手柄按钮控制(来自街头霸王2:究极格斗游戏说明书)
从左上顺时针:重击,重踢,中等击打,中等踢,轻踢,轻击。
考虑到行动空间的另一个方向是一组动作,比如高踢、扔、勾拳等, 可以让AI选择一个动作,然后把这个动作转换成一组按钮。但确定一个角色的动作需要一段时间,不仅需要大量的查阅Google,还要自己亲自玩,并且要对每个角色都要重复这个过程。
所以为了缩短训练时间,Gyroscope团队将动作空间简化为一个按下方向控制和按下一个按钮控制(例如“上+ A”或“L”)的组合,同时是否按下都是可选的,这一构建方法使得行动空间缩减成了35个可能的行动。更高级的动作和组合仍然可能随着训练时间的增加而出现,但是这部分留给了AI自行探索。
回报
最后,还要去思考这么一个问题:一旦采取行动,AI是否就能收到回报?因为当人类玩游戏的时候,会通过血条和伤害的大小,对游戏目前的状况大体上有一个认识。AI也需要通过一个数字的形式来理解游戏状况,让它们使这个数字最大化从而获得最佳奖励,Gyroscope团队选择了每一帧的血条差距作为回报。
在每次观察时,AI都会得到相当于玩家之间血条差距的奖励。例如,如果AI通过踢动作使对方受到10点伤害,之后的血条差距将会是10点,AI得到同样数量的回报。但如果AI在下次观察后不采取行动,在“无”的情况下仍然得到10点,因为它保持了血条差距。相反的,如果AI被踢并且没有防御下来,则血条差距将会减小,所以这个差值也可能出现负的情况。
一场街头争霸比赛中Dhalsim(一个游戏角色)得到的回报
创造人工智能的人工智能
以上是Gyroscope团队讨论的最终在比赛中采用的问题构建方法。同时Gyroscope团队也调整了AI系统的参数,因为Gyroscope的自主AI是一个算法的算法,它可以找到每个问题适用的算法,而有了这么多关于“街头霸王”问题的信息之后,Gyroscope选择深度Q网络 (Deep Q-network, DQN)作为强化学习方法,同时也对DQN进行了一些修改。
值得一提的是基于图像观察空间缺失的修改:DQN使用模型来预测哪些行动最佳,而不是用穷举法测试每个可能的行动。毕竟考虑到观察空间的大小,探索每个可能的行动几乎是不可能的。
模拟器连接
在训练人工智能之前,需要先把它与街头霸王连接起来,因为没有超级任天堂的SDK,Gyroscope团队在某个社区找到了一款连接经典游戏机的工具,可以帮助他们测试超级任天堂的游戏,从而使用AI技术来玩这些游戏。
为了使AI连接到游戏,不仅需要模拟器,还需要支持模拟器核心的工具。Gyroscope团队找到了BizHawk,它可以支持多种模拟器核心,包括超级任天堂的核心。
BizHawk可以提供的重要功能:
• 一个Lua语言脚本界面,以便于逐帧控制游戏;
• 一套控制台内存检查工具,以便检查游戏内存(全部或特定地址);
• 运行中可以不受速度限制,也不需要显示,从而最大化游戏的帧率;
• BizHawk源代码。
特别对于“街头霸王”而言,Lua界面允许我们发送手柄按键信号,读取按下按钮信号,读取存储位置以及控制核心模拟器。内存检测器可以让我们获取对手的血条情况、对手的动作以及其他观察数据。
为了提高速度,Gyroscope团队还将SDK代码从Lua转移到本地BizHawk工具,同时保留了之前写的python代码,他们把这些代码命名为模拟器控制器。而为了能更好的控制游戏和模拟器的方方面面,Gyroscope团队还做了一个使用C#操作街霸的工具。
综合起来:训练AI
训练初期,AI(图中Dhalsim)随机按下按钮
定义好观察结果、动作、奖励值,再将AI连接到超级任天堂,就可以开始训练它了。针对内置的游戏机器人,每个角色大约训练8小时或者3000场比赛。
Gyroscope团队希望训练好的AI将:
(1)最大限度地提高奖励值,
(2)可以在训练结束后拥有相当高的胜率。
训练了3000场比赛后,Dhalsim积极进取,胜率50%
经过了观察空间、动作空间、奖励值函数和DQN参数的许多变体,最终得到了一个高胜率的AI。
训练期间的胜率和模型损失
除了标准模型调优技术和良好的科学原则(一次只改变一个量),Gyroscope团队还有了一个重大发现:方向控制按压与按钮控制按压的权重不同。方向控制只对一帧有效,在游戏中影响很小;然而按钮控制一旦按下,作用会维持一系列帧,在游戏中影响重大。比如完成拳击这一动作需要很多帧。这意味着在一帧内采取的动作会延续很多帧。
此外,虽然与方向控制按压相比,按钮按压非常重要,但相应地也需要更加频繁的按压才能起作用。为了完成这一游戏行为,也为了使AI行为更加人性化,他们让AI在20帧(即1/3秒)内一直重复按钮按压,完后再采取下一个动作。换句话说,他们让AI以1/3秒游戏时间为单位来采取动作、观察结果,而不是以每帧为单位。
至于Gyroscope团队为什么不用“获胜”作为奖励值。简单来说,这样做奖励值是延迟的,会导致训练更困难更耗时。
Gyroscope获胜!
80%胜率;注意AI机智地拦截对方招数,还会潇洒地走位
刚开始训练的时候,AI随机行动,对战3星级对手(街霸采用星级评价体系)的胜率是20%。所以,20%胜率是底线,超过20%才能说明AI取得了成效。最后, AI对抗游戏内置3星级机器人的胜率达到90%!针对比赛,取得80%胜率后Gyroscope团队就停止了训练,以避免过拟合。
AI获胜后,Gyroscope团队开始用街霸II的每个角色训练它。为了训练每个角色,他们使用Google云端平台,写了一些脚本进行全部的训练,训练需要通过一些脚本来自动完成玩家选择、游戏重置、模型记录、进度绘制等功能。
会场上:战斗吧!
SDC上Gyroscope团队的展位
会场上,Gyroscope团队布置了展位来展示四场AI战斗,场场都是两个AI控制的角色对抗。他们还画了比赛树状图——安排展位没展示到的角色参加比赛。
第一天的比赛:M.Bison碾压全场
四分之一决赛
Guile对战Vega:Guile被吊打。Vega AI很快就学会了缩短距离,弯腰躲闪,刺向对方,并且还学会了神奇的走位,Vega胜出。
Blanka对战M.Bison:M.Bison实力碾压。他的独门攻击几乎无法阻挡,就这样M.Bison胜出。
Chun-Li对战Sagat:Chun-Li也是近距离作战——她的速度和近地攻击打败了Sagat的长距离袭击和频繁的走位。Chun-Li胜出。
Balrog对战Dhalsim:十分有趣的是,Dhalsim几乎一直在空中,用他的长腿攻击Balrog。Dhalsim胜出。
半决赛
Vega对战M.Bison:M.Bison的攻击太猛烈了。M.Bison进入决赛。
Chun-Li对战Dhalsim:Dhalsim在空中发起的进攻杀伤力非常大,轻松击败Chun-Li。
决赛
M.Bison对战Dhalsim:由于M.Bison角色太过强大以至于无可匹敌,M.Bison轻松获胜!
第二天的比赛:E.Honda搅动风云
宣布E.Honda对战Blanka
第二天,重新开始比赛,M.Bison从比赛中除名,因为它在夜里私自使用兴奋剂(作弊代码)而被捕,Gyroscope团队准备让E.Honda加入,原因是它在测试时表现很差。
这天的战斗格外引人注目,Vega对抗Sagat打了一场持久战,Vega靠近Sagat时,用神奇的走位至少躲过了三次Sagat的技能,一次是越过火球,两次是拿准时间弯腰躲闪,但很遗憾的是,Vega依然输掉了。
决赛是E.Honda对抗Sagat,当战斗到最后的时刻,两个人物的血量都已经接近0了,但E.Honda出其不意的一击,使其获得了胜利。
Gyroscope团队对E.Honda获得胜利感到不可思议,他们认为E.Honda的运气真的很好,因为他们又重新进行了100场E.Honda对战Sagat的比赛,E.Honda只赢了11场而已。