C++ 超极小异或神经网络无法学习。。。我做错了什么?

C++ 超极小异或神经网络无法学习。。。我做错了什么?,c++,machine-learning,neural-network,C++,Machine Learning,Neural Network,在自学神经网络的基础知识后,我决定尝试一下学习XOR函数的超最小网络。它由两个输入神经元、两个隐藏神经元和一个输出神经元组成。问题是它不能学习。。所以我一定是在我的背上做错了什么?该代码是超小型的,应该使用任何支持c++11的编译器进行编译 #include <stdio.h> #include <stdlib.h> #include <vector> #include <cmath> #include <algorithm> #inc

在自学神经网络的基础知识后,我决定尝试一下学习XOR函数的超最小网络。它由两个输入神经元、两个隐藏神经元和一个输出神经元组成。问题是它不能学习。。所以我一定是在我的背上做错了什么?该代码是超小型的,应该使用任何支持c++11的编译器进行编译

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <cmath>
#include <algorithm>
#include <numeric>

using namespace std;

float tanh_activate(float x) { return (exp(2*x)-1)/(exp(2*x)+1); }
float tanh_gradient(float x) { return 1-x*x; }

vector<float> input = { 0.0f, 0.0f };
vector<float> hiddenW = { 0.5f, 0.5f };
vector<float> hidden = { 0.0f, 0.0f };
vector<float> output = { 0.0f };

void forward()
{
    float inputSum = accumulate( input.begin(), input.end(), 0.0f );
    hidden[0] = tanh_activate( inputSum ) * hiddenW[0];
    hidden[1] = tanh_activate( inputSum ) * hiddenW[1];
    output[0] = tanh_activate( accumulate( hidden.begin(), hidden.end(), 0.0f ) );
}

void backward( float answer )
{
    auto outputError = answer - output[0];

    auto error = outputError * tanh_gradient( output[0] );

    auto layerError = accumulate( hiddenW.begin(),
                                  hiddenW.end(),
                                  0.0f,
                                  [error]( float sum, float w ) {
                                      return sum + (w * error);
                                  } );

    // Calculating error for each activation in hidden layer but this is unused
    // currently since their is only one hidden layer.
    vector<float> layerE( hidden.size() );

    transform( hidden.begin(),
               hidden.end(),
               layerE.begin(),
               [layerError]( float a ) {
                   return tanh_gradient( a ) * layerError;
               } );

    // update weights
    for( auto wi = hiddenW.begin(), ai = hidden.begin(); wi != hiddenW.end(); ++wi, ++ai )
        *wi += *ai * error;
}

int main( int argc, char* argv[] )
{
    for( int i = 0; i < 10000000; ++i )
    {
        // pick two bits at random...
        int i1 = ((random() % 2)==0)?1.0f:0.0f;
        int i2 = ((random() % 2)==0)?1.0f:0.0f;

        // load our input layer...
        input[0] = (float)i1;
        input[1] = (float)i2;

        // compute network output...
        forward();

        // we're teaching our network XOR
        float expected = ((i1^i2)==0) ? 0.0f : 1.0f;

        if( i % 10000 == 0 )
        {
            printf("output = %f\n",output[0]);
            printf("expected = %f\n",expected);
        }

        // backprop...
        backward( expected );
    }

    return 0;
}

我丢失了偏差treshold,你神经元模型中的基本信号

您可能也不希望在反向传播中进行如此剧烈的更正

从权重中减去渐变的比率百分比


比率可能低于100%。

我缺少偏差treshold,即神经元模型中的基本信号

您可能也不希望在反向传播中进行如此剧烈的更正

从权重中减去渐变的比率百分比


比率可能低于100%。

给定足够的迭代次数,输出应与传递给backward的预期输出相匹配。如果迭代次数足够多,输出应该与传递给backward的预期输出匹配。永远不会。所有层都需要偏差吗?@dicroce在本例中仅隐藏一个。所有层都需要偏差吗?@dicroce在本例中仅隐藏一个。