【问题标题】:Connect 4 with neural network: evaluation of draft + further steps用神经网络连接 4:草稿评估 + 进一步步骤
【发布时间】:2011-05-30 21:22:37
【问题描述】:

我想构建一个使用人工神经网络工作的 Connect 4 引擎 - 只是因为我对 ANN 很着迷。

我创建了以下 ANN 结构草案。它会起作用吗?这些连接是否正确(甚至是交叉连接)?

你能帮我为这个 ANN 起草一个 UML 类图吗?

我想向 ANN 提供董事会代表作为其输入。输出应该是选择的移动。

稍后应使用reinforcement learning 完成学习,并应应用sigmoid function。该引擎将与人类玩家对战。然后根据比赛结果调整权重。

我在寻找什么......

...主要是编码问题。它越是从抽象思维转向编码 - 它就越好。

【问题讨论】:

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


    【解决方案1】:

    以下是我在处理神经网络时如何组织设计和代码的。这里的代码(显然)是伪代码,大致遵循面向对象的约定。

    从下往上,你将拥有你的神经元。每个神经元都需要能够保存它对传入连接的权重、一个用于保存传入连接数据的缓冲区以及一个其传出边的列表。每个神经元需要能够做三件事:

    • 一种从传入边缘接受数据的方法
    • 一种处理输入数据和权重以制定该神经元将发出的值的方法
    • 一种在传出边缘发送此神经元值的方法

    在代码方面,这转化为:

    // Each neuron needs to keep track of this data
    float in_data[]; // Values sent to this neuron
    float weights[]; // The weights on each edge
    float value; // The value this neuron will be sending out
    Neuron out_edges[]; // Each Neuron that this neuron should send data to
    
    // Each neuron should expose this functionality
    void accept_data( float data ) {
        in_data.append(data); // Add the data to the incoming data buffer
    }
    void process() {
        value = /* result of combining weights and incoming data here */;
    }
    void send_value() {
        foreach ( neuron in out_edges ) {
            neuron.accept_data( value );
        }
    }
    

    接下来,我发现最简单的方法是创建一个包含神经元列表的 Layer 类。 (很可能跳过这个类,只让你的 NeuralNetwork 保存一个神经元列表。我发现有一个 Layer 类在组织和调试方面更容易。)每一层都应该暴露以下能力:

    • 使每个神经元“激发”
    • 返回此层环绕的原始神经元数组。 (当您需要在神经网络的第一层手动填充输入数据时,这很有用。)

    在代码方面,这转化为:

    //Each layer needs to keep track of this data.
    Neuron[] neurons;
    
    //Each layer should expose this functionality.
    void fire() {
        foreach ( neuron in neurons ) {
            float value = neuron.process();
            neuron.send_value( value );
        }
    }
    Neuron[] get_neurons() {
        return neurons;
    }
    

    最后,您有一个 NeuralNetwork 类,其中包含层列表、使用初始数据设置第一层的方法、学习算法以及运行整个神经网络的方法。在我的实现中,我通过添加由单个假神经元组成的第四层来收集最终输出数据,该神经元只是缓冲所有传入数据并返回。

    // Each neural network needs to keep track of this data.
    Layer[] layers;
    
    // Each neural network should expose this functionality
    void initialize( float[] input_data ) {
        foreach ( neuron in layers[0].get_neurons() ) {
            // do setup work here
        }
    }
    void learn() {
        foreach ( layer in layers ) {
            foreach ( neuron in layer ) {
                /* compare the neuron's computer value to the value it
                 * should have generated and adjust the weights accordingly
                 */
            }
        }
    }
    void run() {
        foreach (layer in layers) {
            layer.fire();
        }
    }
    

    我建议从反向传播开始作为您的学习算法,因为它被认为是最容易实现的。当我研究这个时,我很难找到一个非常简单的算法解释,但我的笔记列表this site 是一个很好的参考。

    我希望这足以让你开始!

    【讨论】:

      【解决方案2】:

      您的设计将高度依赖于您计划使用的特定强化学习类型。

      最简单的解决方案是使用反向传播。这是通过将误差反馈回网络(以相反的方式)并使用(sigmoid)函数的逆来确定对每个权重的调整来完成的。经过多次迭代后,权重将自动调整以适应输入。

      遗传算法是反向传播的替代方法,它可以产生更好的结果(虽然有点慢)。这是通过将权重视为可以轻松插入和删除的模式来完成的。该模式会多次替换为变异版本(使用自然选择原则),直到找到合适的版本。

      如您所见,每一个的实现都会大不相同。您可以尝试使网络足够通用以适应每种类型的实现,但这可能会使它过于复杂。一旦投入生产,您通常只会接受一种形式的培训(或者理想情况下,您的网络已经经过培训)。

      【讨论】:

        【解决方案3】:

        我之前实现过神经网络,发现您提出的架构存在一些问题:

        1. 典型的多层网络具有从每个输入节点到每个隐藏节点以及从每个隐藏节点到每个输出节点的连接。这允许将来自所有输入的信息组合起来并贡献给每个输出。如果您将 4 个隐藏节点专用于每个输入,那么您将失去一些网络识别输入和输出之间关系的能力。

        2. 您将如何提出训练网络的值?您的网络会在棋盘位置和最佳下一步移动之间创建映射,因此您需要一组提供此信息的训练示例。游戏结束的动作很容易识别,但你如何判断游戏中期的动作是“最佳”的呢? (强化学习可以在这里提供帮助)

        最后一个建议是使用双极输入(-1 表示错误,+1 表示正确),因为这样可以加快学习速度。 Nate Kohl 提出了一个很好的观点:每个隐藏和输出节点都将受益于偏置连接(将其视为另一个具有固定值“1”的输入节点)。

        【讨论】:

          【解决方案4】:

          有很多不同的方法可以实现神经网络,从简单/易于理解到高度优化。您链接到的Wikipedia article on backpropagation 具有指向C++C#Java 等中的实现的链接,如果您有兴趣了解其他人是如何做到的,这些可以作为很好的参考。

          一种简单的架构会将节点和连接建模为单独的实体;节点可能具有到其他节点的传入和传出连接以及激活级别和错误值,而连接将具有权重值。

          或者,有更有效的方法来表示这些节点和连接——例如,作为按层组织的浮点值数组。这使得代码变得有点棘手,但避免了创建如此多的对象和指向对象的指针。

          注意:人们通常会包括a bias node——除了正常的输入节点——它为每个隐藏和输出节点提供一个常数值。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-06-30
            • 2018-04-30
            • 1970-01-01
            • 2019-05-03
            • 2016-11-04
            • 2018-08-04
            • 2012-05-06
            • 2017-04-13
            相关资源
            最近更新 更多