在国际象棋上复现AlphaZero的设计和失败的心得
柏舟 新冠4年 12-19
2015年以来,DeepMind公司发展了围棋人工智能AlphaGo及其各种演化版本,这些算法取得了一系列令人瞩目的成绩:AlphaGo Lee于2016年战胜李世石,AlphaGo Master于2017年战胜柯洁。之后,DeepMind公司在 2017年又推出了AlphaGo Zero,它不需要人类示例或指导,通过强大的自学能力,在36h后就超越了AlphaGo Lee。
AlphaZero从随机对弈开始训练,在没有先验知识、只知道基本规则的情况下,成为史上最强大的棋类人工智能。它适用于国际象棋、日本将棋、围棋等。AlphaZero凸显了深度强化学习在解决控制决策问题中的广泛适用性。
蒙特卡洛树搜索
AlphaZero基于蒙特卡洛树搜索(Monte Carlo Tree Search)框架。传统MCTS使用蒙特卡洛方法进行随机模拟获取动作的价值,而AlphaZero使用深度神经网络评估局势减少随机搜索计算量,提高动作价值评估的准确性,使用于更大的状态空间计算。
与DQN等方法相比,AlphaZero的框架更适用于稀疏的奖励的任务场景,并能够通过搜索的方式获得更准确的动作价值。
MCTS框架
MCTS树节点记录信息包括:
- 访问次数N(s,a)
- 动作价值Q(s,a)
- 子节点,父节点信息
MCTS算法包含以下行为:
- 动作选择
- 叶节点扩展
- 叶节点评估
- 信息回溯更新
动作选择
MCTS会从根节点开始,通过类似多臂赌博机问题中的UCB(upper confidence bound)最优算法确定动作抵达某个尚未完全展开的节点。
第1项代表利用,Q(s,a)的值越大,则相应动作越容易被选取;第2项代表探索,动作访问次数N(s,a)越小,则该动作越容易被选择到。$N(s_k,b)$为父节点访问次数,$N(s_k,a)$为当前节点访问次数。
但在AlphaZero中,它的实现如下:
最初算法会倾向于选择具有高先验概率和低访问次数的动作,随着节点访问次数的增多,它会逐渐倾向于具有高动作价值的动作。在最初的AlphaGo中,先验概率p(s,a)使用监督学习神经网络拟合。AlphaZero还尝试过评估动作价值函数Q(s,a),虽然胜率更高,但是选择的多样性不如前者,所以没有采用。
但在AlphaZero中,使用联合策略-价值网络。
叶节点扩展
在新扩展的节点处,将它的每个可行动作的统计信息初始化为0。
叶节点评估
叶节点评估步骤估计新叶节点位置 s的动作价值 Q(s, a)即胜率,采用蒙特卡洛随机模拟(playout)得到,从s开始,通过某种策略(如随机策略)进行模拟直到游戏结束。在AlphaZero中,使用基于模式特征的浅层推演策略神经网络拟合策略函数π:p(a|s)。
国际象棋动作空间设计
国际象棋一共有6种棋子:兵、车、马、象、后、王。输入:最近两步局面信息和先手方。将棋盘编码成6x8x8的点集,一共13x8x8的输入。每一层代表一种棋子,+1代表白棋在棋盘上有棋子,-1代表黑棋在棋盘上有棋子。
输出分为两部分:
- 当前局面走子方的胜率[-1,1]。
- 当前局面走子的策略。
策略层动作编码设计
输出的策略层大小为7 x 8 x 8,1层棋子选择,6层动作选择。这样设计的原因是因为棋子有多种走法,并且可能走到同一个位置。这个方案比较复杂,但是暂时没有想到更好的方案。
动作可以写成a=(from,to)这样一个有序序列,可以用条件概率表示。
MCTS动作编码
MCTS生成的是一系列动作的概率p(a|s),需要将其编码成p(from|s),p(to|from,s)。
p(from|s)即选择棋子,它满足:
等于动作中起始位置为from的和。
而p(to|from,s)的求法如下:
网络设计
使用残差卷积神经网络,分为公用层,选择棋子层,选择动作层,局势评估层。
共用层:
层名 | in | out | kernel |
---|---|---|---|
卷积层 | 13 | 64 | 1 |
残差卷积层 | 64 | 128 | 5 |
卷积层 | 128 | 256 | 1 |
选择棋子层:
层名 | in | out | kernel |
---|---|---|---|
残差卷积层 | 256 | 128 | 3 |
卷积层 | 128 | 1 | 1 |
softmax输出
选择动作层综合了公用层和选择棋子层的输入:
层名 | in | out | kernel |
---|---|---|---|
残差卷积层 | 256 | 128 | 3 |
卷积层 | 128 | 16 | 1 |
全连接层 | 17x64 | 6x64 | 输入合并选择棋子 |
sigmoid输出,理论上动作的概率应该存在约束,但是很难建模。
局势评估层设计使用了图像分类的神经网络的思路,但是效果很差:
层名 | in | out | kernel |
---|---|---|---|
残差卷积层 | 256 | 512 | 3 |
卷积层 | 512 | 1024 | 1 |
池化层 | 4 | - | - |
全连接层 | 1024 | - | - |
tanh输出。
训练
自我对弈和MCTS对弈产生数据。采用模仿学习MCTS的策略训练神经网络。对弈数据包括当前局面棋子分布,走子的概率,对弈结束后会标注每一步局面信息,胜者为1,败者为-1。
损失函数
损失函数包含三部分:棋子、动作选择的损失函数,局势评估的损失函数。
棋子和动作的选择函数用交叉熵表示
它其实反映了两个概率分布的距离:KL散度定义如下:
因为H(P)是目标的概率分布,大小不影响,所以将H(P,Q)作为损失函数。
实际计算的损失也是很小的,只有0.18左右。
而局势评估使用MSE评估。按道理来说每步棋会有更细腻的胜负变化,但是标注数据从始自终只有-1,1,0三个数,学习就像噪声一样,神经网络学不会。损失一直在0.86左右降不下来。
因为最近很忙,也不是专门搞这个的,如果还有机会的话会重新设计局势评估的数据生成,比如使用棋子的价值和状态值的衰减。原本这篇文章是想写强化学习和控制的关系,但是发现REINFORCEMENT LEARNING AND OPTIMAL CONTROL这本书,只好以后再写。