▲ 中国象棋
笔者一直在想,这么有趣的事情怎么可以没有中文版呢?对于国际象棋来说,其中文版自然就是中国象棋了,于是我一直有想着把它的结果在中国象棋上面复现一下。拖了大半年,在最近几天终于把这个事情完成了,在此跟大家分享一下。
象棋谱式:
将军不离九宫内,士止相随不出官。象飞四方营四角,马行一步一尖冲。炮须隔子打一子,车行直路任西东。唯卒只能行一步,过河横进退无踪。
背棋谱
其实,简单看看量子位的文章,就能理解 GPT2 下象棋的原理了,无非就是“背棋谱”。简单来说,就是象棋的棋谱可以表示为一个连续的文本字符串,而 GPT2 正是擅长于背诵文本,因此可以用 GPT2 把人类的棋谱都背诵下来,而对于下棋来说,就可以看成是根据已经走的部分棋谱背诵下一步棋谱了,因此整个任务理论上确实是可以用 GPT2 完成。
为了完成这个任务,我们就需要了解计算机是如何记谱的。关于记谱的标准,比较通用的是 ICCS 记谱法和 FEN 局面表示法,其细节可以参考文章《中国象棋电脑应用规范(二):着法表示》[1] 和《中国象棋电脑应用规范(二):FEN文件格式》[2]。
1.1 ICCS记谱
简单来说,ICCS 记谱就是将棋盘用如下图的横纵坐标表示,每一步走法只需要记录起始坐标,比如“h2e2”就是指将原来位于坐标(h, 2)的子移动到(e, 2),如果是当前局面是新开局,那么这就对应着走法“炮二平五”。这样一来每一步就只需要 4 个字符来记录了,n 步的棋谱就变成了 4n 长度的字符串了。
当然,如果要输入到模型的话,不一定非得要按照这样的方式来,比如我也可以把“h2”只用一个 id 表示、“e2”用另一个 id 表示,也就是每个格点都用一个坐标而不是两个坐标来描述,这样每一步的只需要两个 id 来记录,以此来缩小棋谱的序列长度,这没有什么定法,有兴趣大家自己改进着完就好。
1.2 FEN局面
至于 FEN 局面表示法,则是用来表示当前局面有哪些子,轮到谁走。本文所建模的棋谱实际上都是全局棋谱,所以实际上本文的模型不需要用到它(局面都是默认的新开局面),不过为了方便有兴趣的读者做出改进,这里也简单介绍下。
所谓 FEN 表示法,主要就是想办法表示出每一行有哪些子,比如开局表示为“
rnbakabnr/9/1c5c1/p1p1p1p1p/9/9/P1P1P1P1P/1C5C1/9/RNBAKABNR w - - 0 1
”。其中红色部分表示局面,小写表示黑方,大写表示红方,不同行之间用/隔开,字母含义如下表。
这样,“rnbakabnr”就表示第一行为黑子的“車馬象士將士象馬車”,“9”表示第二行 9 个点都是空白的,“1c5c1”表示第三行是“1个空白 +1 个黑砲 +5 个空白 +1 个黑砲 +1个空白”,等等;绿色部分表示轮到哪一方走子,“w”表示红方,“b”表示黑方;剩下部分一般不大重要,有兴趣的读者自己去看链接就行。
建模型
看了上述对记谱表示的介绍,我们知道,不管是每步的走法还是局面的表示,都被我们转化为了一串文本了,而对于象棋的推演都是以局面与走法作为输入输出的,所以理论上来说象棋的建模完全就是一个“文本处理”问题!这便是 GPT2 下象棋的理论依据了。本质上来讲,GPT 也就是 BERT 加上语言模型的 Attention Mask,所以这样的做法我们说是 BERT 下象棋或者 GPT 下象棋都行。
2.1 代码分享
项目链接:
https://github.com/bojone/gpt_cchess
训练过程使用渐进式训练,即逐步增加序列长度,而不是一次性使用同一的长度,有些文章将这种做法称之为“课程学习(Curriculum Learning)”。
这种做法能提高模型的训练速度和收敛速度(一开始序列更短,训练速度更快,也更容易收敛),直观来看就是让模型先学习“开局”,然后再学习“开局+中局”,最后学习“开局+中局+残局”,逐步增加难度。
训练前加载了 BERT 的权重,可能读者会疑问 BERT 的权重还能跟棋谱有关系?其实没什么关系,但是不管怎么说,用 BERT 的权重比完全随机初始化的权重要好点,收敛会快一点点。
2.2 测试一下
模型脚本还包含了一个可以跟模型交互式下棋的实现,读者可以自行体验一下,这个交互式下棋使用了 python 的 cchess 模块
[3]
来辅助实现,在此表示感谢。
GPT 本身是一个生成模型,但是在决定下一步棋走什么的时候,笔者并不是用生成式方法(因为无约束生成有可能输出不可行的走法),而是用打分式的方法,即直接生成当前局面的所有可行走法,然后输入到模型打分,取分数最高的那个走法,这样就保证模型输出的每一步都是可行的,保证了可以跟 AI 一直对局下去,直到分出输赢。
也许读者可能会有疑问,枚举所有可行走法计算量会不会很大?其实,对于每个局面来说,可行走法并不多,可以通过简单论证它不会超过 111 种(是不是有点意外?中国象棋每一步的候选走法不超过 111 种,而不是一个非常大的数字),所以这一步的 batch_size 不会超过111,因此是可以接受的。
推导过程很简单:1 个车或炮最多有 17 种走法,2 车 2 炮最多有 68 种走法;兵如果都过河了,那么每个兵最多有3种走法,5 个兵最多有 15 种走法;1 个马最多有8种走法,2 个马就是 16 种;2 个相最多有 6 种走法(1 个在中间,1 个在边,4+2);1 个士在花心最多有 4 种走法(2 个士反而相互堵塞);最后的帅最多有 2 种走法。因此结果是 68+15+16+6+4+2=111。具体局面设计可以参考数学研发论坛的《一个中国象棋局面设计难题》
[4]
。
大家最关心的可能就是这样弄出来的模型棋力究竟怎样?笔者简单跟它测了一下,大概的结论是:基本上可以开一个比较好的局,开局的时候具有不错的应变能力,不过一旦到了中局之后,应变能力会大大下降。对于吃子不是很敏感,也就是说当你乱吃它的子的时候,它可能不会应对。可以看出这些其实都是纯背棋谱的缺点。当然,前面说了每一步的输出都是可行,因此你可以跟它一直玩下去,直到把棋下完。
谈改进
应该有读者会问能不能自己跟自己对弈来提高棋力?理论上当然是可以的,但很遗憾这里没有实现,一是没那个心思实现,二是没那个算力实现。
此外,增加模型大小应该也能进一步提升棋力,要注意笔者上述结果只用了 Base 版本(1 亿参数)的模型,本文开头提到的网友用 GPT2 下国际象棋可是用了 15 亿参数的 GPT2,是我们的 15 倍。
还有一个改进的地方,那就是上面的建模中我们直接学习了整个对局棋谱,按道理为了更好的棋力我们可以只学习赢家的走法,不能学习输家的走法。
当然,这些做法就算有提升,估计也是有限的,归根结底,这跟我们所理解的下棋原理不一样。我们下棋是根据局面形势往前推的,但上述的语言模型做法则没有局面这个概念,或者说它的局面需要用已经走的所有步骤来确定,这对于中后局来说历史步数太多,确实有点强模型所难了。
改进方法其实也很简单,改为“以局面为输入、以走法为输出”就好了,前面我们说了,局面也可以用 FEN 表示法表示为一个文本,因此这也是只是个 Seq2Seq 任务而已。
除此之外,还有一些别的做法,比如我们可以把赢家的每一个局面都当作正样本,输家的每一个局面都当作负样本,那么就可以训练一个二分类模型,来判断局面优劣,有了这个判断函数,我们也可以直接枚举每一个可行走法,根据判断函数的结果来选择最优下法。而局面可以表示为文本,这就意味这我们将下棋变成了一个文本分类任务了。
总之,得益于 Transformer 模型对文本的强大的建模能力,这使得我们对下棋的建模思路也变得简单多样起来了。
总小结
本文尝试了通过 bert4keras 用 GPT 来下中国象棋的做法,主要思路是通过“语言模型背棋谱”的方式来让模型具有预测下一步的能力,并谈及了一些改进思路。尽管本文的做法并非对下棋这个任务进行建模的标准做法,但通过这样的方式,能让我们进一步体会到语言模型的强大之处。
欢迎大家报告自己所训练的下棋模型的棋力智商,哈哈。
[1]
https://www.xqbase.com/protocol/cchess_move.htm
[2] https://www.xqbase.com/protocol/cchess_fen.htm
[3] https://github.com/walker8088/cchess
[4] https://bbs.emath.ac.cn/thread-17051-1-1.html
如何才能让更多的优质内容以更短路径到达读者群体,缩短读者寻找优质内容的成本呢?答案就是:你不认识的人。
总有一些你不认识的人,知道你想知道的东西。PaperWeekly 或许可以成为一座桥梁,促使不同背景、不同方向的学者和学术灵感相互碰撞,迸发出更多的可能性。
PaperWeekly 鼓励高校实验室或个人,在我们的平台上分享各类优质内容,可以是最新论文解读,也可以是学习心得或技术干货。我们的目的只有一个,让知识真正流动起来。
📝 来稿标准:
• 稿件确系个人原创作品,来稿需注明作者个人信息(姓名+学校/工作单位+学历/职位+研究方向)
• 如果文章并非首发,请在投稿时提醒并附上所有已发布链接
• PaperWeekly 默认每篇文章都是首发,均会添加“原创”标志
📬 投稿邮箱:
• 投稿邮箱:hr@paperweekly.site
• 所有文章配图,请单独在附件中发送
• 请留下即时联系方式(微信或手机),以便我们在编辑发布时和作者沟通
🔍
现在,在「知乎」也能找到我们了
进入知乎首页搜索「PaperWeekly」
点击「关注」订阅我们的专栏吧
关于PaperWeekly
PaperWeekly 是一个推荐、解读、讨论、报道人工智能前沿论文成果的学术平台。如果你研究或从事 AI 领域,欢迎在公众号后台点击「交流群」,小助手将把你带入 PaperWeekly 的交流群里。