【问题标题】:How to code an artificial neural network (Tic-tac-toe)? [closed]如何编写人工神经网络(井字游戏)? [关闭]
【发布时间】:2010-10-20 03:50:09
【问题描述】:

我想使用人工神经网络玩井字游戏。我的网络配置如下: 对于 9 个字段中的每一个,我使用 2 个输入神经元。所以我当然有 18 个输入神经元。对于每个字段,我有一个用于玩家 1 的输入神经元和一个用于玩家 2 的神经元。除此之外,我还有 1 个输出神经元,用于评估当前棋盘位置。输出值越高,玩家 1 的位置越好。输出值越低,玩家 2 的位置越好。

但我的问题是:我如何编码该神经网络?我的想法是使用 Array[1-18] 作为输入神经元。该数组的值是输入权重。我会使用循环遍历数组。每当有神经元被激活时,我都会将权重添加到输出值中。所以输出值为激活的输入神经元的权重之和:

Output = SUM(ActivatedInputNeurons)

您认为这是对网络进行编程的好方法吗?你有更好的想法吗?

我希望你能帮助我。提前致谢!

【问题讨论】:

    标签: artificial-intelligence neural-network game-ai


    【解决方案1】:

    这是一个出色的 AI 编码入门项目,但提出一个完整的解决方案将是解决 SO 的重要途径。

    与大多数软件一样,我建议使用面向对象的设计。例如:定义一个Neuron 类,它具有输入、权重和输出函数。然后,创建几个 Neuron 对象以构建您的网络。

    请参阅artificial neural networks 上的维基百科文章以获得良好的起点。

    祝代码好运!听起来很有趣。

    【讨论】:

      【解决方案2】:

      添加权重后,您需要使用函数对总和进行归一化,如果您想允许负数,人们通常使用 TANH。

      编辑:

      Here is a java multilayer perceptron 几年前我工作的实现。这个是用于跳棋的,但输入较少,您也可以将其用于跳棋。

      另外,你可能需要想办法教它赢,但这是另一个问题

      【讨论】:

      【解决方案3】:

      这不是您问题的直接答案,但您应该查看以下框架/工具:SNNS 或其 Java 对应物 JavaNNS。我很确定你会在那里找到问题的答案。

      【讨论】:

      • 谢谢!两者似乎都是非常好的链接。不幸的是,我既没有 C++ 也没有 Java。我只有 Delphi/Pascal。
      • 您应该能够找到有关如何完成工作的示例。最后你想学习或用人工神经网络做smthg,所以语言是次要的,不是吗?
      【解决方案4】:

      我认为您应该使用传递函数实现“传统”feed-forward ANN,因为这允许您使用反向传播来训练它。这些代码通常以几行代码结束,如下所示:

      SetupInputs();
      for (l = 1 .. layers.count)
          for (i = 0 .. layers[l].count)
              sum = 0
              for (j = 0 .. layers[l-1].count)
                  sum += layers[l-1][j] * weights[l-1][j]
              layers[l][i] = TransferFunction(sum)
      

      【讨论】:

      • 非常感谢。但这将是多层神经网络的代码,不是吗?
      • 是的。您将无法仅使用感知器(单层)计算可用分数。我在大学也遇到过同样的问题,我什至无法使用反向传播在井字游戏上训练多层网络。
      【解决方案5】:

      我不太明白您希望如何从一个输出神经元中获得对电路板情况的有意义的总结。我会更多地考虑拥有:

          I I I             O O O
          I I I      x      O O O
          I I I             O O O
      9 input neurons  9 output neurons
      

      在完全连接的网络中,即 81 个权重。然后训练输出神经元在该位置上的相对期望。

      【讨论】:

      • 后续一点:我认为您可以使用 9 个输入神经元而不是 18 个,因为您可以使用 0 表示“未占用”,1 表示“自占用”,-1 表示“对手占用”。跨度>
      • 只有 9 个输入......也许吧。使用一些隐藏的神经元,您肯定能够提取所需的信息。否则,未占用的场地将被视为自己占用和对手占用的平均值,这听起来很错误。尽管如此,对于这样一个微不足道的游戏来说,它可能已经足够好了。
      【解决方案6】:

      嗯,你有一个 18 个神经元的输入层和一个 1 个神经元的输出层。没关系。但是,您需要让您的神经网络有机会将输入关联起来。为此,您至少需要一个中间层。我建议在中间层使用 9 个神经元。这些中的每一个都应该连接到每个输入神经元,输出神经元应该连接到每个中间神经元。每个这样的连接都有一个权重,每个神经元都有一个激活级别。

      然后,您遍历所有神经元,一次一层。输入层刚刚使用板状态激活。对于所有其他神经元,您将遍历其所有各自的连接,并对连接的神经元的激活水平和连接权重的乘积求和。最后,通过对该总和应用 sigmoid 函数来计算激活水平。

      这是工作原理。现在,您需要训练这个网络以获得更好的结果。有几种算法可以解决这个问题,你必须做一些谷歌搜索和阅读。最后,当结果不够快时,您可能需要调整神经元和层数。例如,您可以将输入层减少到 9 个神经元,并使用 +1 表示 X 和 -1 表示 O 激活它们。也许添加另一个中间层会产生更好的结果,或者增加一层的神经元数量。

      【讨论】:

        【解决方案7】:

        看看我的 Tic 项目。我已经用神经网络和遗传算法解决了这个问题。源代码免费提供。

        http://www.roncemer.com/tic-tac-toe-an-experiment-in-machine-learning

        【讨论】:

          【解决方案8】:

          如果您使用 FANN 或 Neuroph 等神经网络库,您将节省时间。

          编码输入的一种方法是使用 9 个输入神经元。输出也可以是 9 个神经元。我在其他回放中没有看到隐藏层的大小。我想您将使用具有传统 3 层的 MLP。隐藏层的大小始终是个谜。我会尝试 10 个隐藏的神经元。

          如果传递函数是 sigmoid,您可以按如下方式对输入进行编码:

          0.0 - O 玩家。

          1.0 - X 播放器。

          0.5 - 空。

          ANN 的输出将是 9 个实数。在这种情况下,一些单元格将被占用。您可以搜索与空单​​元格对应的最高输出值。

          【讨论】:

            猜你喜欢
            • 2017-06-07
            • 1970-01-01
            • 2012-07-15
            • 2016-01-17
            • 2013-10-01
            • 2017-04-11
            • 2013-03-01
            • 2017-04-15
            • 1970-01-01
            相关资源
            最近更新 更多