AI的更新迭代和《空洞骑士》的叙事达成了奇妙的和谐:要不断尝试,不断犯错,直到战胜敌人。
开始直播第五天,Ailec的直播间诞生了一场颇为精彩的战斗。
正在直播的游戏是《空洞骑士》,玩家挑战的BOSS是作品中的高人气角色大黄蜂。小骑士先是用冲锋的无敌帧躲过大黄蜂的冲刺,接着又在大黄蜂掷出飞针的同时下劈并靠近,攻击得手后一个小跳,轻易躲过收回的飞针……
迅速靠近敌人,大黄蜂起跳瞬间预判使用法术,在BOSS做出冲锋姿势时一刀打出硬直,几乎没有停顿地位移靠近继续输出。
耗时40秒,小骑士用最后一刀劈中正处于冲锋状态的大黄蜂,利落地结束了这场战斗。弹幕一时飘过好几串代表着惊讶和振奋的“ohhhhhh”,而小骑士只是沉默,继续开始与大黄蜂纠缠新的一局。
不少观众感慨这位才刚开始玩游戏没几天的新手已经拥有了远超自己的水平,甚至认为其中某些精妙的操作已经超脱了正常人类的范畴——当然,其中完全没有质疑小骑士舞弊的意思。
毕竟,这位幕后的玩家本来就不是人类。
1
老实说,AI打游戏并不算是什么稀罕事。
有以实力强著称的,像横扫围棋界的AlphaGo和《星际争霸2》达到宗师段位的AlphaStar,已经被不少人称作人工智能领域的里程碑。也有以实力差闻名的,日本一家AI公司的首席技术官曾经在推特上发布一个“史上最弱”的黑白棋AI,即便是职业棋手上阵,想在它面前输掉比赛也不得不绞尽一番脑汁。
胜率逼近0.5%
而且AI往往不按套路出牌。你让它玩索尼克,他跑去墙角卡BUG走捷径通关。
你让它学俄罗斯方块,他迅速落下每一块方块并在游戏即将Game Over的时候按下暂停键。因为每落下一块方块都能使AI获得的更多奖励分,而在输掉游戏前按下暂停就不会得到失败的惩罚——你得承认,这对它来说确实是一种极具效率的得分方式。
正在美国留学,且面临着期末考核的Ailec在开始自己的作业前就已经做好了一定的心理预期,可即便是站在前人的肩膀上,直到真正开始调教AI打游戏,他才切身感受到这是一项多么充满坎坷的挑战。
之所以选择《空洞骑士》,除了Ailec自己刚在去年年底通关了这款游戏之外,更直接的原因是他恰巧点进了一位名叫“烽征战”的up主的直播间。
烽征战是一位国内的研究生,虽然平日学业繁忙,但偶尔也会在B站开直播,今年三月份的时候,他正在尝试的项目是训练AI击败《空洞骑士》中的大黄蜂。
为什么是《空洞骑士》,为什么是大黄蜂,其中实际上包含了诸多考量。首先,《空洞骑士》是一款2D平面游戏,且BOSS战需要投入关注的对象只有自己和BOSS,这减轻了计算机的工作量,其次,大黄蜂的整体攻略难度不高,而且招式多变,相对来说是个难易程度适中的好老师。
Ailec和烽征战一拍即合,与对方沟通交流一番后便开始了同样内容的直播。他觉得这是个再合适不过的期末作业——创造一个能够稳定战胜大黄蜂的AI。
2
Ailec最初版本的AI框架基本继承自一位名叫“蓝魔digital”的up主。这位在2020年写了一套AI学习打《只狼》的代码,借鉴其代码创作的AI击败苇名弦一郎的视频还上过B站首页。
不出所料,在《只狼》中如鱼得水的AI 立马对《空洞骑士》呈现出水土不服的症状。作为“只狼”,AI需要做出的判断是锁定弦一郎、挥刀、格挡、适时看破,而作为“小骑士”,“格挡”和“看破”这样的机制在游戏中并不存在,它得重新学习如何使用基本的挥砍和法术打败敌人。
于是Ailec开始马不停蹄地修改代码。白天对AI算法进行更新迭代,睡前打开直播,把AI扔进游戏训练学习——这时候国内正是上午。一觉醒来,审视一下学习成果,和观众们聊上两句,然后紧接着投入新的更新迭代。
Ailec至今清楚记得第一次重大更新(事故)发生在容器7身上——容器,这是直播间的观众为AI取的名字。你知道,有关游戏的具体版本,开发者往往会用上1.1、1.2甚至是尼尔那样行为艺术的“1.22474487139”加以描述区分,但具体到《空洞骑士》中,AI的版本更迭和游戏的叙事产生了奇妙的映射关系。根绝游戏的设定,玩家操纵的小骑士是万千容器中的一个,在他必然踏上的旅途中,无数容器曾经历过与其相似却又不同宿命,就像一代代挑战大黄蜂又倒在她针下的AI。
容器7之所以与众不同,主要在于这是Ailec第一次尝试手把手教AI如何战斗。简单来说,他将自己对阵大黄蜂的录像演示给AI,希望它能从中学习到一些操作技巧,结果容器7受到教诲后,不仅没有成长为武林高手,反而立地成佛,具体表现为只追着BOSS跑,靠近后却一刀不砍——可惜大黄蜂不会因此手下留情。
事后反思时,Ailec找到了症结所在。对人类来说,靠近BOSS是为了有效击中BOSS,这点不言而喻。但AI不能理解人类的思路,它认为小骑士花了更多的操作和时间接近大黄蜂,最后却只挥出一刀。如果进攻一次的得分是1,那么靠近BOSS可能占0.9,挥刀则占0.1。既然如此,一个劲往BOSS身上靠就是十分合乎逻辑的操作……
Ailec挂在直播间的FAQ
3
总结失败经验,不断优化算法,一个个容器因此诞生。进化到11号容器时,Ailec终于做出了大刀阔斧的改动。
具体的尝试主要体现在两方面:一是优化奖励机制,降低移动在“得分”中的权重,杜绝只追着BOSS不砍这种现象的发生;二是将动作组合起来,命令AI一次性做出一组动作,比如在冲刺后衔接攻击,从而更好地抓住输出机会。
容器11的表现一度十分亮眼,文章开篇的那顿精彩操作就是它的闪光时刻之一。不过好景不长,威猛没多久,11号就陷入了日墙状态。
病因和容器7类似,在不断的练习过程中,容器11的进攻权重完全压倒了移动权重,换句话说,这回只知道砍不知道动了。
除此之外,动作组合的弊端同样显现出来。原本Ailec为容器们设定的操作只有17项(例如左移动、右移动、左攻击、右攻击……),但在强行添加派生动作后,AI的学习难度陡然增加,根据BOSS行动作出的反馈延迟也剧增——小骑士一刀挥出最快只需要0.25秒,但AI的反应时间却长达0.3、0.4甚至0.8秒。
Ailec最终找到的应对方法是放弃动作组合,将小骑士的移动和攻击分别交给两组模型管理,其中方向脑只负责移动,而行动脑则负责除移动之外的挥刀、法术、跳跃等等。
应用这套框架后,Ailec又在容器16身上尝试削弱延迟奖励机制对AI 影响。延迟奖励机制的主要作用是让AI认清长期利益,他用迷宫举例,看上去离出口更近的岔路口可能是死路,延迟奖励能够让AI意识到短时间内的绕路实际上会节省更多的时间。
但《空洞骑士》不是迷宫,大黄蜂的攻击方式是多变的,小骑士的一次操作也不会对后续战斗造成类似于迷宫选错岔路口那么严重的影响——降低延迟奖励机制对AI的影响之后,容器16的胜率终于稳定在了30%左右。
Ailec几乎以天为单位对算法进行细致的优化,容器们的胜率也因此来回波动不定。当然,也有做无用功的时候,比如一位观众曾建议他尝试应用RNN(循环神经网络),结果花了两天时间改的代码最终对小骑士毫无帮助。
但容器们总体上还是在一点点变得更强的。容器23,Ailec对奖励机制做出细化,使得只能控制移动的方向脑即便无法通过“攻击”行为得分,也能凭借靠近BOSS获得奖励。
追着大黄蜂揍的23
容器24,Ailec进一步完善行动脑的奖励机制,鼓励AI做出诸如“在距离BOSS过远时使用冲刺”之类的操作,同时完全去除了延迟奖励机制——此时24号已经基本能够以90%以上的胜率击败大黄蜂。
对整体神经网络结构进行最后一次大范围改动优化,并“灌顶”容器24的经验后,容器26达到了接近完美的状态。起初它的表现一般,但用Ailec的话来说,就像学会了挂挡、把方向盘、控制离合刹车,却没适应怎么打开车门——打开车门终究不是什么难事,很快容器26就能够以将近百分百的胜率战胜敌人,即使是难度更高的进升级大黄蜂,胜率也在最后达到了90%。
一血险胜进升级大黄蜂
它已经是个足够强大的小骑士了。
4
交流过程中,Ailec曾数次向我提起教授、朋友(烽征战)以及直播间观众对他的帮助,于是我问:“你觉得为什么会有这么多人来看AI打大黄蜂?”
他想了想,觉得自己也不太能确定。可能是这部分观众本身对人工智能感兴趣,可能是AI的一点点强大带给观众“儿子长大了”的快感,甚至可能只是因为AI与“容器”之间产生一种奇妙的对应关系。
写到这里,我对这个问题也大致有了自己的想法。让AI训练小骑士打败大黄蜂即是对机器的挑战,也是对人的挑战,而《空洞骑士》,或者说“容器们”,用一种和谐而直观的方式呈现出机器的成长,以及人的成长。
就像在泪水之城,大黄蜂告诉玩家操纵的小骑士:“你的灵魂出自两个虚空,难怪你能到达这世界的中心。”