神经网络炼丹实录:Kingz战棋游戏

内容纲要

一次惨烈的失败,大楚兴,专家王!

之前

新学期有两个好玩的bot作业,第一个是编写一个国际麻将八番起胡的bot,和JeremyGuo以及Ender组队写bot。

我们最初的宏图是:

1.把Botzone平台上的所有麻将对局数据下载下来,压缩封装,做成一个数据表。

2.编写一个搜索算法

3.编写专家系统对局面进行估值,然后用手牌查表,综合专家和查表结果给出局面的最终估值,使用搜索寻找最优估值。

JeremyGuo负责写搜索算法主体,Ender负责先写一个简单的麻将Bot做强度参照系,Hineven(我)负责数据处理以及数据表制作,我从Botzone上下载了三年来的所有20G的对局数据,写了个脚本,把每个麻将手牌局面编码,编码后13张手牌+胜负信息占用大约38位,再使用花色互换去个重,剩下只有5M个状态 塞到哈希表里 20MB出头。JeremyGuo使用没有专家系统的搜索算法整合了一下数据表,第一版bot光荣诞生

最初版搜索bot排名变化

然而放到botzone上,排名分一泻千里,经过几盘人机对局发现这个bot难以想象地,麻将手牌的状态空间在10^11左右,但是数据库里只有5M个状态,算上花色替换也就大约20M个状态,JeremyGuo的搜索常熟太大,在一秒钟的时间限制内只能搜索50K个状态(后来经过辛苦的常数优化优化到了3M个状态),在麻将丢牌时最多有14个分支,每个分支预计命中数据表次数在100上下,但这个数字显然是不够的,而且,由于Botzone里存在大量智障bot的对局数据,数据表的质量也较低。

于是我们放弃了数据表,考虑使用专家系统估值。JeremyGuo和Hineven开始鼓捣专家系统,JeremyGuo和Hineven分别以自己的方式重写了JeremyGuo之前的搜索,然后Hineven使用专家估值+专家丢牌+随缘搜索(其实是按概率进行随机化搜索...这在某种程度上能提高搜索深度)写了一个稍微拥有战斗力的bot:

搜索bot改革红

目前其排名在30左右浮动。后来我心不死,试着把查数据表的估值整合到这个bot专家系统的估值中,结果bot反而变弱了...后来就彻底的放弃了数据表。Ender的专家bot依然没写出来,他比较咕。

JeremyGuo在第一次搜索的死亡之后认为“不如不如写砖家,砖家可以出奇迹”,于是他坚定不移地投入了砖家系统的怀抱,在经过数个砖家策略尝试后:

JeremyGuo的专家排名变化

真的砖家出奇迹了,纯砖家系统暴打各种搜索算法,排名一度上升到11名(虽然最近掉下去了)

于是,搜索与砖家系统之间,砖家胜出。

有兴趣的同学可以试试在botzone上和我们的bot玩麻将,不要吐槽它们的名字(改革红,QwQ,玩游戏要啸着玩,等等),毕竟一时兴起。

Botzone: https://botzone.org.cn/

正文

写了那么多,这篇文章和神经网络有什么关系呢?和Kingz有什么关系呢?砖家系统vs搜索算法又和神经网络有什么关系呢?

砖家出奇迹!砖家南波万!

那时因为在打麻将bot作业中,砖家系统胜过了搜索,而在Kingzbot作业中,砖家系统完爆了神经网路(至少...是我们炼出来的神经网络)。

首先,关于Kingz是个怎样的游戏,可以体验一下:https://generals.io

Kingz玩法和generals及其相似,不过Kingz是固定10*10大小地图,1v1,没有swamp沼泽,并且信息完全:你可以随时观察对手的一举一动,总体而言Kingz是generals的简化版。

我们早在三月份就了解到期末考试考Kingz的bot,所以深谋远虑,决定动用虚妄的最强大杀器——神经网络算法——作为我们Kingz的bot核心。

既然要炼丹,炉子必不可少,搭炉子又得耗费一些精力。我们在本地实现了一个Kingz裁判系统,做了一个简单的图形界面,用户可以编写Kingz程序,类似botzone一样使用pipe(最初我们使用了socket...回想起来那时真的傻)与裁判系统进行交互,用户可以在线观看bot之间的战斗。

然后兵分两路,Ender负责编写一个经典的蒙特卡洛搜索bot作为与神经网络对练的选手,JeremyGuo和我继续搭建神经网络bot。

鉴于之前的一些经验,我们的设计总思路是:神经网络宏观调控,多种脚本负责微操。

整个bot分为

1.特征提取器,该组件负责获取Kingz游戏信息,对游戏信息进行加工,提取出一些神经网络可能难以提取的特征,加入到神经网络的输入之中

2.策略脚本,该组件包含多种选择操作兵力起点、操作兵力目标、行动路径、调用兵力数量的策略,每种策略是一小段脚本,不同策略脚本之间相互组合可以组建数百种不同的行动方式。

2.神经网络决策器,神经网络使用CNN+FC的naive组合,输入经过处理的地图数据和特征,根据输出来选择执行的策略。

三个部分。

训练神经网络时,训练器包含:

1.reward奖励函数,它会根据bot操作给予奖励或惩罚。这个函数比较复杂。

2.bot,每个bot拥有自己的对局数据历史记录,打完一局会从数据历史记录中随机选择部分数据进行训练。每个bot还拥有VISION(远见)参数,在训练网络时,用DoubleQ模型,网络的拟合目标不是reward,而是reward为首项,未来reward乘以VISION等比数列求和。这样在理想情况下bot就能学会“最大化未来的reward”总和。同时,每个bot还有随机参数EPSILON,在EPSILON概率下会做出随机操作,探索新的可能。

3.训练主循环,使用3个不同的神经网络bot+一个固定的静态bot一起训练。令三个神经网络bot开启学习模式进行车轮战互相学习,然后分别挑战静态bot,然后继续车轮战,然后...往复循环,如果一个神经网络bot在车轮战中连跪七把,那么这个网络会被另外两个bot之一随机覆盖,防止出现“一个网络爆打全场”而所有人学不到任何东西的状况。

同时,训练主循环中开令每个bot的EPSILON参数逐渐衰减,而VISION参数从0缓慢上升到0.95,期望能让bot前期勇于尝试,后期趋于稳定、进行微调,前期能快速拟合奖励函数,后期能拥有“远见”拟合未来的奖励函数之和。放入的静态bot是JeremyGuo编写的砖家系统bot,期望让神经网络能够学会与砖家进行对抗。

理想,是丰满的

开炉

炼丹第一夜:

把训练器挂在台式机上炼丹,第二天早上一醒发现bot看似凶猛实则实力极弱,打不过Ender的MCTS。后来,JeremyGuo发现它的训练目标写错了...好吧,重来。

炼丹第二夜:

对策略、奖励、bot都进行了许多调整,第二天早上一醒,发现bot好像牛逼了!天哪!它快速地铺开军团,快速的发育,快速地聚集兵力!它在前50回合内就聚集了200+的兵团!它要干什么?它调动兵团冲出了自己的家!它要去冲对方老家吗?不!它似乎在犹豫,看着对手逐渐聚集的兵力,它带领兵团回到了自己的家中...它在防御,它时时刻刻提防着对手!天哪,多么机智啊!但现在,是时候进攻了!不!现在该防御!是时候进攻了!防御!进攻!防御....

它带着大兵团在家门口进进出出,循环往复,看着对局二人默契地进行着如此傻逼的循环操作,我脑海中冒出了一个大大的问号...

奖励函数...对,我在奖励函数里写出了一个bug

def defendReward (map, me, my_move):
    if not me.home.inDanger():
        if towards_home(my_move):
            return big_reward+my_move.army_moved/distance(my_move.move_pos, me.home)
    return small_reward</code></pre>

伪代码差不多这个意思,由于第二行写出的bug,无论在任何情况下,只要把兵力往家里调就会获得一个大奖励,而且如果兵力越多,距离家越短,奖励越大。

神经网络很机智地发现了这个bug...于是,它们学会了利用这个bug刷出巨量奖励:先稍作发育,然后使用发育而来的大兵团,在家门口进进出出!

Yes!你 真 天 才!

气愤地删掉了torch的参数表,又对策略、提取器、奖励函数进行了一波升级...然后似乎只用了1h就训练出了很强的bot!前期疯狂发育,中期一波偷家,丝滑流畅!

上传到botzone上,被各路砖家系统轮流打爆....

JeremyGuo:我一晚上写了个新的砖家系统whatsyourname!现在它很牛逼!

好啊!来当staticbot,帮忙训练神经网络吧!

whatsyourname(砖家) vs 从现在起这里叫改革红广场(神经网络)

裁判程序就位!ready? fight!

战报雪片般飞来,双方落子如飞,十分钟过去了

神 经 网 络 百 战 百 负

还能有奇迹吗?

炼丹第三夜:

我重置了所有模型

staticbot换成了whatsyourname(砖家系统)

这个名字的威压,摆在神经网络面前,似乎就是

whosyourdaddy

我删掉了所有花里胡哨的奖励

reward中只留下了两个数字:

15000与-15000,你死,我亡

神经网络只剩下一个目的:

胜利,只有胜利

调好了所有参数,确定了所有设定

听着至强CPU呜呜的风扇声,这是炼丹炉火的低鸣

晚安。

结果

在神经网络bot代码的海洋中,有一个文件夹

里面放满了策略脚本

许多策略脚本之中,又有一个三十行的小函数,这个函数,叫做“进攻”

第二天早上,打开电脑屏幕,我惊讶地发现,神经网络在胜率上已经压制了whatsyourname。

但这也是我最不希望看到的结果:

whatsyourdaddy作为一个砖家系统,缺陷是难免有的,这个缺陷就在于它的防御系统不够强。

本来我期待看见攻城略地,斗智斗勇,但现在,我只看见两个疯狗一般的bot忽视了一切发育,忽视了一切策略,神经网络只会攻击,只会攻击,疯狗一般低能地无限互撕,但这个策略对whatsyourdaddy很有效! 神经网络bot抓住了whatsyourdaddy的缺陷,就像抓住那个曾经存在于reward函数中的bug一样,并狠狠利用了它,一遍遍爆它的基地,而没有学出任何机智的普适游戏策略。

我总感觉不是我在玩神经网络,而是神经网络在玩我。我看着它**一般的操作,似乎看到了一张人脸,从电脑屏幕里盯着我,调皮地说:surprise!

Fuck u

已经累了...

后记

  • 神经网络发现了JeremyGuo砖家系统的缺陷。或许...这是它的唯一作用吧,发现规则的漏洞,然后钻个空子,然后利用这个漏洞获利...
  • JeremyGuo的砖家系统后来暴打了Ender上千行的MCTS,搜索算法再一次在砖家系统面前颜面扫地
  • Hineven把只会偷家的神经网络bot放到了botzone上,排名分居然上涨了?什么鬼?

红方是神经网络bot

  • 项目地址贴上来了,大家可以尝试一下炼丹器,蛮好玩的。
  • https://gitee.com/hineven/ggh
此条目发表在小项目分类目录,贴了标签。将固定链接加入收藏夹。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注