如何为国际象棋编写神经网络?

Posted

技术标签:

【中文标题】如何为国际象棋编写神经网络?【英文标题】:How to program a neural network for chess? 【发布时间】:2010-10-19 17:32:53 【问题描述】:

我想编写一个国际象棋引擎来学习如何走好棋并与其他棋手对抗。我已经编写了棋盘的表示和输出所有可能移动的函数。所以我只需要一个评估函数来说明董事会的给定情况有多好。因此,我想使用一个人工神经网络来评估给定的位置。输出应该是一个数值。数值越高,白棋的位置就越好。

我的方法是构建一个由 385 个神经元组成的网络:棋盘上有 6 个独特的棋子和 64 个区域。因此,对于每个字段,我们需要 6 个神经元(每块 1 个)。如果有白棋,则输入值为 1。如果有黑棋,则值为 -1。如果该字段上没有这种类型的块,则值为 0。除此之外,还应该有 1 个神经元供玩家移动。如果轮到白方,则输入值为1,如果轮到黑方,则值为-1。

我认为神经网络的配置相当不错。但是缺少主要部分:如何将这个神经网络实现为编码语言(例如 Delphi)?我认为每个神经元的权重在开始时应该是相同的。然后根据比赛结果调整权重。但是怎么做?我想我应该让 2 个电脑玩家(都使用我的引擎)互相对抗。如果白方获胜,黑方会得到反馈,称其权重不好。

因此,如果您能帮助我将神经网络实现为编码语言(最好是 Delphi,否则是伪代码),那就太好了。提前致谢!

【问题讨论】:

感谢您到目前为止的回答。我意识到用神经网络下棋是困难的或不可能的。但我的问题的第二部分是:你如何编写神经网络(例如我的配置)?我不知道,所以我期待得到一些建议。 检查这个:chesscircle.net/forums/…! 由于 SOTA 自 2009 年以来发生了显着变化,因此需要对此有更新的答案!使用深度 NL 与强化学习相结合当然可以学习下棋! @KeirSimmons 欢迎您发帖,或添加赏金。 我想指出,用一个神经元来指示必须移动的玩家并不是一个好主意,你会遇到一些问题,因为对棋盘的评估不会是均匀的。如果是黑转,我建议你反转所有值,这样它就不会考虑黑与白,而是考虑玩家和对手。 【参考方案1】:

万一有人偶然发现了这个页面。鉴于我们现在所知道的,OP 的提议几乎肯定是可能的。事实上,我们设法为状态空间更大的游戏——围棋(https://deepmind.com/research/case-studies/alphago-the-story-so-far)做到了这一点。

【讨论】:

;) 他们从国际象棋开始,然后是围棋,使用几乎相同的神经网络架构【参考方案2】:

如果您还使用 alpha-beta 修剪进行一些经典的 mini-max 前瞻,我不明白为什么不能为静态评估器使用神经网络。许多国际象棋引擎使用极小极大和脑死的静态评估器,它只是将棋子或其他东西相加;如果您有足够的极小极大水平,这并不重要。我不知道网络会带来多大的改进,但几乎没有什么可失去的。训练它会很棘手。我建议使用一个可以向前看很多动作的引擎(并且需要大量的 CPU 等)来训练评估器,以获得一个向前看更少动作的引擎。这样一来,您最终会得到一个不占用太多 CPU 的引擎(希望如此)。

编辑:我在 2010 年写了以上内容,现在是在 2020 年 Stockfish NNUE has done it。 “该网络在中等搜索深度对数百万个位置的 [经典 Stockfish] 评估进行了优化和训练”,然后用作静态评估器,在初始测试中,当使用此静态评估器而不是他们的前一个(或者,等效地,相同的 elo,CPU 时间少一点)。所以是的,它确实有效,你甚至不必像我最初建议的那样在高搜索深度下训练网络:中等搜索深度就足够了,但关键是要使用数百万个位置。

【讨论】:

这种方法的一个问题是,如果你使用极小值和 alpha-beta 剪枝启发式,你已经接受了你的 NN 不如你的评估者。现在我同意这样做只是为了让一个国际象棋下NN很酷,实际好处(除了你将获得的经验)不会太多。 @AtillaFiliz 否。使用手动(由程序员编写)评估器 + 深度搜索来训练 NN,希望 NN + 浅层搜索优于手动评估器 + 浅层搜索。如果有效,那么 NN 比人工评估器要好。【参考方案3】:

去过那里,做到了。由于您的问题没有连续性(一个位置的值与另一个位置的关系并不密切,一个输入的值只有 1 个变化),因此 NN 工作的可能性很小。在我的实验中从未出现过。

我宁愿看到一个带有临时启发式(其中有很多)的模拟退火系统来评估位置的价值......

但是,如果您打算使用 NN,则相对容易表示。一般的 NN 只是一个图,每个节点都是一个神经元。每个神经元都有一个当前激活值和一个转换公式,用于根据输入值计算下一个激活值,即所有与其链接的节点的激活值。

一个更经典的 NN,即具有一个输入层、一个输出层、每一层的相同神经元,并且没有时间依赖性,因此可以由一个输入节点数组、一个输出节点数组和一个连接这些节点的链接图。每个节点都拥有一个当前激活值,以及它转发到的节点列表。计算输出值只是将输入神经元的激活值设置为输入值,然后依次迭代每个后续层,使用转换公式计算前一层的激活值。当您到达最后一个(输出)层时,您就有了结果。

【讨论】:

但是 TD-Gammon 也学会了仅使用神经网络来玩西洋双陆棋。所以它必须以某种方式工作,不是吗? Blackgammon 是一种与国际象棋截然不同的游戏......它用随机性取代了规则的复杂性和广泛的可能性分支。但是神经网络非常擅长处理统计预测,而不是修剪可能的解决方案树。 如果有足够的内部节点(对于反向传播 NN)和训练数据,连续性不会成为问题。问题在于所需的节点数量和训练量使其不可行。我同意 NN 不是解决问题的好方法。 投反对票,因为答案只关注前馈网络。今天有几十种不同的型号。例如,卷积神经网络应该适用于国际象棋中的模式识别,它可以为您提供一些配置的解决方案。毕竟循环神经网络已经完成了巡回演出,因此理论上可以下棋。 Alpha Zero 和 Leela Zero 基于 NN 并优于所有经典国际象棋引擎,证明这个答案是错误的。【参考方案4】:

这是可能的,但绝不是微不足道的。

https://erikbern.com/2014/11/29/deep-learning-for-chess/

为了训练他的评估功能,他使用了大量的计算能力。

概括地说,您可以按照以下方式进行。您的评估函数是前馈神经网络。让矩阵计算得出一个标量输出来评估移动的好坏。网络的输入向量是棋盘上所有棋子表示的棋盘状态,比如白兵是 1,白马是 2...,空白区域是 0。棋盘状态输入向量示例是简单的 0 序列-12 的。对于许多游戏,可以使用大师级游戏(例如在 fics 数据库中提供)对这种评估进行训练,从而最大限度地减少当前参数所说的最高估值与大师级移动(应该具有最高估值)之间的损失。这当然假设大师的动作是正确和最优的。

【讨论】:

【参考方案5】:

你需要训练一个 ANN 类似 backpropagation learning 或某种形式的 genetic algorithm。但国际象棋是如此复杂的游戏,一个简单的人工神经网络不太可能学会下棋——如果学习过程是无监督的,情况就更糟了。

此外,您的问题没有说明层数。您想使用 385 个输入神经元对当前情况进行编码。但是你想如何决定做什么呢?每个场的神经元?最高激发获胜?但通常有不止一种可能的举动。

此外,您还需要几个隐藏层 - 可以用一个输入层和一个没有隐藏层的输出层来表示的功能真的很有限。

所以我不想阻止您尝试它,但在一年左右的时间内成功实施和培训的机会几乎为零。

我在 16 岁左右的时候尝试构建和训练一个人工神经网络来玩井字游戏……但我失败了。我建议先试试这么简单的游戏。

【讨论】:

神经网络应该只评估一个位置。其他函数计算所有可能的移动。然后对于每一步,将得到的位置提供给神经网络,神经网络给出一个数值作为评估。例如,白方宁愿采取导致 4.5 而不是 -6.2 的一步。 正如 Varkhan 指出的那样,得分函数会非常波动,很难用 ANN 表示。 我也无法编程井字游戏。我缺乏专业知识。因此,我在这里问如何实现这样的神经网络。在我看来,神经网络是一个非常抽象的东西。我可以想象它是如何工作的,但我不知道如何编码。所以我希望这里有人可以帮助我。【参考方案6】:

我在这里看到的主要问题之一是培训。你说你希望你的 ANN 占据当前的董事会位置并评估它对玩家有多好。 (我假设您会为玩家采取所有可能的动作,将其应用于当前的棋盘状态,通过 ANN 进行评估,然后采用输出最高的动作 - 即:爬山)

在我看来,您的选择是:

开发一些启发式函数来评估棋盘状态并以此训练网络。但这引出了一个问题,即当您可以使用启发式算法时,为什么还要使用 ANN。

使用一些统计量度,例如“在这个棋盘配置中,白棋或黑棋赢得了多少场比赛?”,这将为您提供介于白棋或黑棋之间的适应度值。困难在于您的问题空间大小所需的训练数据量。

使用第二个选项,您始终可以为其提供来自大师级游戏的棋盘序列,并希望有足够的覆盖范围供 ANN 开发解决方案。

由于问题的复杂性,我想尽可能地投入最大的网络(即:大量内部节点),而不会过多地减慢训练速度。

【讨论】:

谢谢。我已经测试过了。它会起作用,但你需要大量的训练数据——正如你已经写的那样。在国际象棋中,大约有 2,28x10^46 个可能的位置,因此您永远不会为每个位置提供足够的训练数据。 是的,尽管神经网络的想法是它应该能够在给定有限的训练集的情况下进行泛化。很大程度上取决于您要拟合的函数的复杂性,在国际象棋的情况下,这将是疯狂的。 好吧,你说服了我。但是你怎么能编码呢?我很想测试它,尽管我现在知道我的引擎永远不会成为职业玩家。【参考方案7】:

您的输入算法是正确的 - 所有位置、所有棋子以及两个玩家都被计算在内。您可能需要为游戏板的每个过去状态提供一个输入层,以便将过去的事件再次用作输入。

输出层应该(以某种形式)给出要移动的棋子,以及要移动到的位置。

使用包含所有神经元权重和突触强度的连接组编写遗传算法,并开始多个独立的基因库,每个基因池中都有大量连接组。

让他们互相玩,保留最好的少数,交叉和变异最好的连接组以重新填充池。

【讨论】:

【参考方案8】:

阅读 blondie24:http://www.amazon.co.uk/Blondie24-Playing-Kaufmann-Artificial-Intelligence/dp/1558607838。

它处理的是跳棋而不是国际象棋,但原理是一样的。

【讨论】:

【参考方案9】:

来这里是为了说出赛拉斯所说的话。使用极小极大算法,您可以预期能够向前看 N 步。使用 Alpha-beta 修剪,您可以将其扩展到理论上 2*N 的移动,但更实际的是 3*N/4 移动。神经网络在这里真的很合适。

也许可以使用遗传算法。

【讨论】:

被否决 - 这与这个问题有什么关系,具体询问 神经网络

以上是关于如何为国际象棋编写神经网络?的主要内容,如果未能解决你的问题,请参考以下文章

国际软件设计文档——软件需求说明书

Wicket中表单组件的国际化标签

国际软件设计文档——可行性研究报告

. 编写程序求解骑士巡游问题:在n行n列的棋盘上(如n=5),假设一位骑士(按象棋中“马走日”的行走法)从

如何为神经网络中的模式识别编写matlab代码

Android多人国际象棋 - 如何处理服务器连接?