Press "Enter" to skip to content

详解强化学习多智能体博弈算法——蒙特卡洛树搜索

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

强化学习,除了可以用于单个强化学习智能体和环境的相互作用,也可以用于两个或者多个智能体在某个强化学习环境下的博弈。

 

关于这种类型的算法,最有名的应该是 蒙特卡洛树搜索 (Monte Carlo Tree Search,MCTS)。

 

随着AlphaGo和AlphaZero算法在围棋、国际象棋和将棋等棋类领域的广泛应用,并且在这些领域内均取得了相比传统的Alpha-Beta 剪枝算法更加优异的性能,蒙特卡洛树搜索算法作为这些智能体使用的算法也被越来越多的人研究。

 

该算法曾被应用于《指环王》卡牌游戏中,它可以在游戏难度越高的情况下表现得越厉害!

 

本文会讨论 使用蒙特卡洛树搜索算法的基本原理 ,并且使用这个算法来 实现一个简单的五子棋对弈的强化学习算法 。

 

1 算法原理

 

对于大多数的棋类游戏,我们可以把游戏过程抽象成在一个博弈树(Game Tree)上进行决策的过程。

 

其中,游戏树的每个结点相当于棋盘的一个状态,而游戏树的每条边相当于某一个玩家(智能体)做出某一个决策。游戏玩家的对弈过程就相当于在这个博弈树上进行决策, 决策目标是 使自己得到的回报尽可能大,对方的回报尽可能小。

 

为了实现这个目标,算法就需要从决策的当前结点出发,穷举(或者启发式的搜索)所有可能的动作,并且得到这些动作的奖励的估计,而且尽可能采取奖励比较大的动作。

 

这种思想在Alpha-Beta 剪枝算法中得到了很好的体现,而且在一些相对比较复杂的棋类游戏(比如国际象棋)中取得了较好的效果。

 

着名的深蓝(Deep Blue)计算机上运行的算法就是基于Alpha-Beta剪枝算法,这个算法在有充分的硬件资源的情况下能够做相对比较深的博弈树搜索,而且早在1997年的时候,当时的硬件水平加上Alpha-Beta剪枝算法就能击败当时的世界冠军。

 

基于博弈树的启发式搜索算法虽然在搜索空间相对较小的棋类游戏中取得了很大成功,但是对于搜索空间很大的棋类游戏,比如围棋,局限于当前的硬件资源,搜索深度并不能达到击败人类的程度。

 

为了能够在这类项目中达到人类专业选手的水平,基于深度学习的蒙特卡洛树搜索方法被开发出来,主要目的是利用深度学习的模型拟合能力,学习到对弈局面的价值函数和对弈的策略,并且利用深度学习模型在博弈树上进行决策,从而能够达到最大限度利用计算资源,有效搜索当前局面的最优动作的目的。

 

下面介绍一下基于深度学习模型的蒙特卡洛树搜索算法。

 

从算法的基本原理上看,AlphaGo算法和AlphaGoZero/AlphaZero算法有一定的区别,其主要表现在是否使用人工收集的数据进行模型训练。

 

为了简便起见,这里叙述的是AlphaGoZero和AlphaZero使用的蒙特卡洛树搜索算法。这两个算法使用的都是自我对弈的方法进行训练,即使用一个模型来获取当前状态的价值估计和动作的概率估计。

 

2 算法的基本步骤

 

一个蒙特卡洛树搜索算法的示意图如下图所示。

 

其中,博弈树的每个结点代表当前棋局所处的状态,包含当前状态的价值估计、当前结点被选择的先验概率、当前结点被选择的次数、当前结点的父结点(Parent)和当前结点的子结点(Children)。

 

跟一般的树一样,我们可以定义树的根结点(Root)和叶结点(Leaf),根结点定义为搜索开始的结点,叶结点定义为没有子结点的结点。

 

从图中可以看出,蒙特卡洛树搜索算法主要可以分四步:

 

选择(Select)

 

扩展和求值(Expand and Evaluate)

 

回溯(Backup)

 

最后的决策(Play)

 

 

3 算法使用的模型

 

下面介绍如何使用PyTorch来实现一个用于五子棋的蒙特卡洛树搜索算法。

 

为了能够执行蒙特卡洛树搜索算法,首先需要一个五子棋的强化学习环境。这里使用的是Gym Gomoku,读者可以使用pip install gym-gomoku命令进行安装。

 

因为五子棋的强化学习环境比较简单,有兴趣的读者也可以尝试自己实现一个五子棋的强化学习环境,可以参考前面介绍的“井字棋”的代码,将其扩展到更大的棋盘和更多的连续棋子。

 

由于蒙特卡洛树搜索算法会用到自我对弈的方法,这个强化学习环境的使用方法和一般的OpenAI Gym强化学习环境有所不同。我们会在用到Gym Gomoku强化学习环境时介绍具体的使用方法。

 

 

4 算法的博弈树表示

 

 

可以看到,我们定义了一个TreeNode类来描述对应的博弈树的结点,除了价值函数等计算中需要用到的信息,还定义了父结点的信息和子结点的信息,其中父结点是一个TreeNode的实例,子结点的信息是一个字典,字典的键是执行的动作,值是动作对应的结点。

 

有了这些信息之后,我们就可以计算前面介绍的PUCT分数,这个分数的值由式(1)决定,通过score方法计算得到。

 

在得到PUCT分数之后,算法就可以根据这个分数来选择分数最高的子结点,对应的方法是select。

 

除了select方法,TreeNode类还定义了expand方法,这个方法输入所有的动作actions和动作对应的先验概率priors,根据这些值来对叶子结点进行扩展,另外还有backup方法,这个方法获得当前结点的价值估计,并且递归地对到达这个结点的路径上的其他结点进行访问次数和价值函数的更新。

 

为了判断结点的性质,我们还需要有两个方法is_root和is_leaf,分别代表当前的结点是否是根结点和是否是叶子结点。

 

5 算法的搜索执行过程

 

在定义完博弈树结点后,我们需要考虑的是如何从博弈树出发执行蒙特卡洛树搜索算法,具体可以参考以下代码。

 

 

整个算法的主体定义在mcsts_search方法中,根据这个方法,我们从根结点出发,不断进行选择,直到到达叶结点,同时使用模型pvnet获取叶结点所在状态的价值和所有可能的子结点的先验概率。

 

在获取对应的价值后,根据价值进行反向传播,更新对应决策路径上的所有结点,即可完成一次蒙特卡洛搜索。

 

在完成多次蒙特卡洛搜索之后,我们可以计算根结点的所有子结点的概率,这个概率具体的计算在式(3)中介绍过了。具体计算对应概率的代码在alpha方法中。

 

需要注意的一点是,在这个方法中并没有直接使用式(1),而是先对所有的访问次数进行对数计算,除以温度的值,然后计算Softmax的归一化概率。

 

之所以要这幺做,是因为当访问次数太多,而温度太小的时候,直接使用式(1)计算概率会导致浮点数溢出,使用Softmax能够有效地避免对应情况的发生。在获取每个子结点(动作)的概率之后,我们可以根据概率采样获取单步的动作,不断进行决策,直到到达最终状态,对应执行决策的方法是step方法。

 

以上就是蒙特卡洛树搜索算法的整体代码,由于篇幅所限,这里不再详细介绍对应的数据采样和模型训练代码,这部分代码和前面介绍的其他强化学习算法构造损失函数,反向传播并且训练模型的代码类似。有兴趣的读者可以阅读代码ex_6_5.py查看对应的算法实现细节。

 

本文节选自 《深度强化学习算法与实践:基于PyTorch的实现》 一书,想要了解更多相关内容,欢迎阅读本书!

 

《深度强化学习算法与实践:基于PyTorch的实现》

 

张校捷 着

 

Be First to Comment

发表评论

您的电子邮箱地址不会被公开。