2016-09-29 16 views
-2

XORを学ぶことができるはずの多層パーセプトロンを書きました。しかし、私が何をしても、入力(1,1)、(0,1)、(1,0)に対しては0.5の出力に収束します。入力(0,0)に対しては、それはゼロに収束する。誰かが私のミスがどこにあるのか考えていますか?ニューラルネットワークがXORを学習しない(0.5出力に収束する)

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) 

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++ファイル:http://pastebin.com/8URZAHSy ヘッダファイル:http://pastebin.com/YiMXpmZX

+2

コードを小さなサンプルに縮小し、リンクを提供する代わりに質問にインラインで挿入できますか? – Hayt

+0

@Hayt:いいえ - 小さなC++の例で訓練可能なニューラルネットワークを書くことはできません。 – MSalters

+0

上記のコードで重要な部分を追加しました。私はpastebinを使って完全なファイルを追加します。見ていただきありがとうございます。 – Stefan1993

答えて

1

全くランダムな初期化はありません。これは対称性を破壊するために必要です。さもなければ、あなたのすべてのニューロンは正確に同じ値を学びます。これは事実上1つのニューロンを有するのと同じであり、1つのニューロンはXORにとって不十分である。

+0

したがって、ウェイトをランダムに初期化する必要がありますか?例えば-0.5と0.5の間? – Stefan1993

+1

これを行うと、出力は次のようになります。0.5 0.5 0.8 0.0。 XORの場合は0 1 1 0でなければならない。これは100000エポックである。私は3つの隠れたノードでそれを修正していますが、バイアスなしでXORを学ぶことができるはずですか? – Stefan1993

+1

間違いなく改善ですが、3つのノードで十分です。 – MSalters

関連する問題