C++ 神经网络不学习异或运算(收敛到0.5输出)

C++ 神经网络不学习异或运算(收敛到0.5输出),c++,neural-network,C++,Neural Network,我写了一个多层感知器,应该能够学习异或。然而,无论我做什么,对于输入(1,1),(0,1)和(1,0),它都收敛到0.5的输出。而对于输入(0,0),它收敛到零。有人知道我的错误在哪里吗 向前传球: void MLP::feedforward() { for(int hidden = 0; hidden < nHidden; hidden++) { hiddenNeurons.at(hidden) = 0; for(int input = 0 ; input < nIn

我写了一个多层感知器,应该能够学习异或。然而,无论我做什么,对于输入(1,1),(0,1)和(1,0),它都收敛到0.5的输出。而对于输入(0,0),它收敛到零。有人知道我的错误在哪里吗

向前传球:

void MLP::feedforward() {
  for(int hidden = 0; hidden < nHidden; hidden++) {
  hiddenNeurons.at(hidden) = 0;

  for(int input = 0 ; input < nInput; input ++) {

    hiddenNeurons.at(hidden) += inputNeurons.at(input)*weightItoH(input,hidden);
  }
}

//Propagate towards the output layer
for(int i =0; i< nOutput; i ++) {
  outputNeurons.at(i) = 0;

  for(int j = 0; j <nHidden; j++) {
     outputNeurons.at(i) += hiddenNeurons.at(j) * weightHtoO(j,i);
  }

   outputNeurons.at(i) = sigmoid(outputNeurons.at(i));
 }
}
C++文件:
头文件:

没有随机初始化。这是打破对称所必需的;否则你所有的神经元都会学习完全相同的值。这和一个神经元是一样的,一个神经元不足以用于XOR。

你能把你的代码收缩成一个小的例子,把它放在问题中而不是提供链接吗?@海特:不,你不能在一个小的C++例子中写一个可训练的神经网络。我在上面的代码中添加了重要的部分。我还将使用pastebin添加完整的文件。非常感谢您的光临。@MSalters是的,我会猜到的。我只是想指出为什么这个问题会被否决等等。如果你不能把它缩小到一定程度,它可能太宽了,不适合stackoverflow。所以权重需要随机初始化?例如,在-0.5和0.5之间?如果我这样做,输出将达到:0.5 0.5 0.8 0.0。其中,对于XOR,它应该是0 1 0。这是有10万个时代的。有了3个隐藏节点,它应该能够毫无偏见地学习XOR,这是对的吗?当然是一个改进,但是3个节点应该足够了。你可能知道为什么网络仍然没有找到正确的解决方案吗?@Stefan1993:不直接,但我知道如何调试它。我知道在训练中,我会遇到错误
(+0.5,0,5,-0.2,0)
,这些错误会传播回两个重量层。这将更新权重并将其移动到正确的方向,只需2个输入、3个隐藏节点和一个输出即可进行调试(因此2x3和3x1权重)
void MLP::backPropagation(int i) {
  float learningRate = 0.75;
  float error = desiredOutput[i] - outputNeurons[0];

// Calculate delta for output layer
for(int i=0; i<nOutput; i++) {
   outputDelta.at(i) = error * dersigmoid(outputNeurons[i]);
}

//Calculate delta for hidden layer
 for(int i = 0; i < nHidden; i++) {
  hiddenDelta.at(i) = 0;//zero the values from the previous iteration

  //add to the delta for each connection with an output neuron
  for(int j = 0; j < nOutput; j ++) {
      hiddenDelta.at(i) += outputDelta.at(j) * weightHtoO(i,j) ;
  }
 }

//Adjust weights Input to Hidden
for(int i = 0; i < nInput; i ++) {
  for(int j = 0; j < nHidden; j ++) {
      weightItoH(i,j) += learningRate * hiddenDelta.at(j);
  }
}

//Adjust weights hidden to Output
for(int i = 0; i < nOutput; i++) {
  for(int j = 0; j < nHidden; j ++) {
      weightHtoO(j,i) += learningRate * outputDelta.at(i) * hiddenNeurons.at(j);
  }
}

}
nInputPatterns = 4;

inputPatterns.assign(nInputPatterns, vector<int>(2));

inputPatterns[0][0] = 1;
inputPatterns[0][1] = 1;
inputPatterns[1][0] = 0;
inputPatterns[1][1] = 1;
inputPatterns[2][0] = 1;
inputPatterns[2][1] = 0;
inputPatterns[3][0] = 0;
inputPatterns[3][1] = 0;

desiredOutput = {0,1,1,0};
#define sigmoid(value)  (1/(1+exp(-value)));
#define dersigmoid(value) (value*(1-value));

//Macro's
#define weightItoH(input,hidden) weightsIH.at(nInput*hidden+input)
#define weightHtoO(hidden,output) weightsHO.at(nHidden*output+hidden)