通过自我对战训练一个智能体掌握一个简单游戏

通过自我对战训练智能体掌握简单游戏

模拟游戏并预测结果。

一个机器人进行一些加法计算。图片由作者提供,借助DALL-E 2的帮助。

简介

令人惊奇的是,在完全信息游戏中,你需要在游戏规则中找到一切卓越的要素,而这些要素对每个人都是公开的。

不幸的是,对于像我这样的凡人来说,阅读一个新游戏的规则只是学会玩一个复杂游戏旅程中的一小部分。大部分时间都是花在实际对局中,最好是与一个实力相当的玩家对局(或者是一个耐心到足够帮助我们发现自己的弱点的更好的玩家)。经常输,希望偶尔赢,这些心理上的惩罚和奖励会引导我们逐渐提高。

也许,在不久的将来,一个语言模型将读取诸如国际象棋这样的复杂游戏的规则,并从一开始就以最高水平进行对局。与此同时,我提出一个更为谦虚的挑战:通过自我对局来学习。

在这个项目中,我们将训练一个智能体通过观察以前版本的自己进行的对局结果来学习玩“完全信息的两人游戏”。该智能体将对任何游戏状态进行估值(游戏的预期结果)。作为额外的挑战,我们的智能体将不被允许维护一个状态空间的查找表,因为对于复杂游戏来说,这种方法是无法管理的。

解决SumTo100

游戏规则

我们要讨论的游戏是SumTo100。游戏目标是通过在1到10之间的数字相加来达到总和为100。以下是规则:

  1. 初始化总和为0。
  2. 选择第一个玩家。两名玩家轮流进行。
  3. 当总和小于100时:
  • 玩家选择一个介于1和10之间的数。所选数字将被添加到总和中,但不能超过100。
  • 如果总和小于100,则另一名玩家进行下一步操作(即返回到步骤3的顶部)。

4. 添加最后一个数字的玩家(达到100)获胜。

两只蜗牛各自忙碌的状态。图片由作者提供,借助DALL-E 2的帮助。

从一个如此简单的游戏开始具有许多优势:

  • 状态空间只有101个可能的值。
  • 状态可以在一个1D网格上绘制。这种特殊性将使我们能够将智能体学习到的状态值函数表示为1D柱形图。
  • 最佳策略是已知的:- 达到11n + 1的总和,其中n ∈ {0, 1, 2, …, 9}

我们可以可视化最佳策略的状态值:

图1:SumTo100的最佳状态值。图片由作者提供。

游戏状态是智能体完成其回合后的总和。值为1.0意味着智能体肯定会赢(或已经赢了),而值为-1.0意味着智能体肯定会输(假设对手采取最佳策略)。中间值表示估计的回报。例如,状态值为0.2表示稍微积极的状态,而状态值为-0.8表示可能输掉的状态。

如果您想深入了解代码,执行整个训练过程的脚本是learn_sumTo100.sh,位于此存储库中。否则,请跟随我,我们将通过高级描述来了解我们的代理如何通过自我对弈来学习。

生成由随机玩家进行对战的游戏

我们希望我们的代理从由先前版本自己进行的游戏中学习,但在第一次迭代中,由于代理尚未学习任何内容,我们将不得不模拟由随机玩家进行的游戏。在每一轮中,玩家将从游戏管理机构(编码游戏规则的类)获取合法移动列表,给定当前游戏状态。随机玩家将从该列表中随机选择一个移动。

图2是由两个随机玩家进行的游戏的示例:

图2:随机玩家进行的游戏示例。图片由作者提供。

在这种情况下,第二位玩家通过达到100的总和赢得了游戏。

我们将实现一个代理,该代理可以访问一个神经网络,该神经网络将游戏状态(代理已经进行了游戏后)作为输入,并输出此游戏的预期回报。对于任何给定的状态(代理尚未进行游戏之前),代理会获取合法动作的列表以及它们对应的候选状态(我们仅考虑具有确定性转换的游戏)。

图3显示了代理、对手(其移动选择机制未知)和游戏管理机构之间的互动:

图3:代理、对手和游戏管理机构之间的互动。图片由作者提供。

在这种设置下,代理依靠其回归神经网络来预测游戏状态的预期回报。神经网络能够准确预测哪个候选移动产生最高回报,代理将会发挥得更好。

我们随机进行的比赛列表将为我们提供第一轮训练的数据集。以图2中的示例游戏为例,我们希望惩罚玩家1所做的移动,因为它的行为导致了失败。最后一个动作导致的状态获得-1.0的值,因为它允许对手获胜。其他状态按γᵈ的因子以负值进行折扣,其中d是与代理到达的最后一个状态之间的距离。γ(gamma)是折扣因子,是一个 ∈ [0, 1] 的数字,表示游戏演变的不确定性:我们不希望像最后的决策那样严厉地惩罚早期决策。图4显示了玩家1所做决策的状态值:

图4:从玩家1的角度看的状态值。图片由作者提供。

随机游戏会生成具有目标预期回报的状态。例如,达到97的总和的目标预期回报为-1.0,达到73的总和的目标预期回报为-γ³。一半的状态从玩家1的角度来看,另一半从玩家2的角度来看(尽管在SumTo100游戏的情况下无关紧要)。当游戏以代理赢得胜利结束时,相应的状态获得类似的折扣正值。

训练代理预测游戏回报

我们拥有开始训练所需的一切:一个神经网络(我们将使用两层感知器)和一个(状态,预期回报)对的数据集。让我们看看预测的预期回报的损失如何变化:

图5:损失随着时代的演变而演化。图片由作者提供。

我们对于神经网络在由随机玩家进行的游戏结果的预测能力不强并不感到意外。

神经网络到底学到了什么?

幸运的是,由于状态可以被表示为0到100之间的一维数字网格,我们可以绘制神经网络在第一轮训练后的预测回报,并与图1中的最优状态值进行比较:

图6:在由随机玩家进行的游戏数据集上训练后的预测回报。图片由作者提供。

事实证明,在随机游戏的混乱中,神经网络学到了两个东西:

  • 如果你能够达到100的总和,那就去做。考虑到这是游戏的目标,这是很重要的。
  • 如果你达到99的总和,你肯定会输。确实,在这种情况下,对手只有一个合法的行动,并且该行动导致代理方失败。

神经网络本质上学会了完成游戏。

为了学会玩得更好,我们必须通过模拟代理方和他们新训练过的神经网络之间进行的游戏来重建数据集。为了避免生成相同的游戏,玩家们会有些随机地进行游戏。一个效果很好的方法是使用ε-贪心算法选择移动,对于每位玩家的第一次移动,ε = 0.5,然后对于游戏的其余部分,ε = 0.1。

重复训练循环,使玩家越来越好

由于现在两位玩家都知道他们必须达到100,因此达到90到99之间的总和应该受到惩罚,因为对手会抓住机会赢得比赛。这种现象在第二轮训练后预测的状态值中可见:

图7:经过两轮训练后的预测状态值。90到99之间的总和显示出接近-1的值。图片由作者提供。

我们看到了一个模式正在形成。第一轮训练向神经网络提供了关于最后一个动作的信息;第二轮训练提供了关于倒数第二个动作的信息,依此类推。我们需要重复游戏生成和预测训练的循环,至少与游戏中的动作数量相同次数。

以下动画展示了在25轮训练后预测状态值的演变:

图8:训练轮数中学到的状态值的动画。图片由作者提供。

预测回报的包络随着从游戏结束向游戏开始的方向呈指数衰减。这是一个问题吗?

有两个因素导致了这种现象:

  • γ直接减弱了目标期望回报,因为我们离游戏结束越远。
  • ε-贪心算法使玩家的行为注入了随机性,使结果更难以预测。有动机预测一个接近零的值以防止极高损失的情况。然而,随机性是可取的,因为我们不希望神经网络只学到一种行棋方式。我们希望神经网络能够看到失误和意外的好棋着法,无论是来自代理方还是对手。

在实践中,这不应该是一个问题,因为在任何情况下,我们都会在给定状态的合法移动中比较值,这些值具有可比较的规模,至少对于SumTo100游戏来说是如此。当我们选择贪婪移动时,值的规模并不重要。

结论

我们挑战自己创建一个能够学会掌握一个涉及两个玩家的完全信息游戏的代理程序,其中从一个状态到下一个状态的转换是确定性的,给定一个动作。不允许手工编码的策略或战术:一切都必须通过自我对弈来学习。

我们可以通过多轮将代理程序的副本相互对战,并训练一个回归神经网络来预测生成游戏的预期回报,来解决简单的SumTo100游戏。

获得的洞察力为我们在游戏复杂性方面的下一步提供了很好的准备,但这将成为我下一篇文章的内容!😊

谢谢您的阅读。