连接4与神经网络:草案+进一步步骤的评估

我想构建一个使用人工神经网络工作的Connect 4引擎 - 仅仅因为我对ANN很着迷。 我创建了以下ANN结构草案。会有用吗?这些连接是否正确(即使是交叉连接)? 你能帮我起草这个ANN的UML类图吗? 我想将董事会代表作为其输入提供给ANN。输出应该是选择的举动。 以后应该使用强化学习来学习,并且应该应用sigmoid函数。该引擎将与人类玩家对抗。并且根据游戏的结果,应该调整权重。 我在找什么...... ......主要是编码问题。从抽象思维到编码越远,它就越好。     
已邀请:
以下是我在处理神经网络时如何组织我的设计和代码。这里的代码(显然)是伪代码,大致遵循面向对象的约定。 从下往上,你将拥有你的神经元。每个神经元需要能够保持它在传入连接上的权重,一个缓冲区来保存传入的连接数据,以及它的传出边缘列表。每个神经元都需要做三件事: 一种从传入边缘接受数据的方法 一种处理输入数据和权重以形成该神经元将发送出去的值的方法 一种在传出边缘发送神经元值的方法 代码方面,这意味着:
// 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类。)每个层都应该暴露出以下能力: 导致每个神经元'开火' 返回此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();
    }
}
我建议从Backwards Propagation开始作为你的学习算法,因为它应该是最容易实现的。当我在研究这个时,我很难找到一个非常简单的算法解释,但我的笔记列出这个网站是一个很好的参考。 我希望这足以让你开始!     
实现神经网络有很多不同的方法,从简单/易于理解到高度优化。关于你链接到的反向传播的维基百科文章有链接到C ++,C#,Java等的实现,如果你有兴趣了解其他人是如何做到的,那么这些实现可以作为很好的参考。 一个简单的架构将节点和连接建模为单独的实体;节点可能具有到其他节点的传入和传出连接以及激活级别和错误值,而连接将具有权重值。 或者,有更有效的方法来表示那些节点和连接 - 例如,作为由层组织的浮点值的数组。这使代码变得有点棘手,但避免创建如此多的对象和指向对象的指针。 需要注意的是:除了正常的输入节点之外,人们通常会包含一个偏置节点,它为每个隐藏和输出节点提供一个常量值。     
我之前已经实现了神经网络,并且看到了您提出的架构的一些问题: 典型的多层网络具有从每个输入节点到每个隐藏节点以及从每个隐藏节点到每个输出节点的连接。这允许组合所有输入的信息并对每个输出做出贡献。如果您为每个输入专用4个隐藏节点,那么您将失去一些网络能力来识别输入和输出之间的关系。 您将如何提出培养网络的价值观?您的网络会在电路板位置和最佳下一步之间创建映射,因此您需要一组提供此功能的培训示例。最终的游戏动作很容易识别,但是你怎么知道游戏中期的动作是“最佳的”? (强化学习可以帮到这里) 最后一个建议是使用双极输入(-1表示假,+1表示真),因为这可以加快学习速度。 Nate Kohl提出了一个很好的观点:每一个隐藏的&输出节点将受益于具有偏置连接(将其视为具有固定值“1”的另一输入节点)。     
您的设计将高度依赖于您计划使用的特定类型的强化学习。 最简单的解决方案是使用反向传播。这是通过将错误反馈回网络(以相反的方式)并使用(sigmoid)函数的反转来确定对每个权重的调整来完成的。经过多次迭代后,权重将自动调整以适应输入。 遗传算法是反向传播的替代方法,可以产生更好的结果(尽管速度稍慢)。这是通过将权重视为可以轻松插入和删除的模式来完成的。模式被替换为变异版本(使用自然选择原则)几次,直到找到拟合。 如您所见,每种方法的实施都会有很大不同。您可以尝试使网络足够通用以适应每种类型的实现,但这可能使其过于复杂。一旦你投入生产,你通常只会有一种形式的训练(或者理想情况下你的网络已经训练过了)。     

要回复问题请先登录注册