2016-08-02 9 views
1

私はXOR演算子のように動作するプログラムで作業しています。人工知能(ニューラルネットワーク) - 実際の出力が正しい出力に近づくことはありません

重みを調整するために、私は背景を使用します。

私は深い学習(これはほぼ同じように動作しますが、ここでも同じ苦闘)を含んでいますが、これは重要ではありません。 (場合-句

if(hiddenNeurons.size() > 1) 
{ 
..... 
} 

のような複数の隠されたニューロンを使用する場合に重要である場合、このコードでは、ただそこにあるよりがある場合。(この質問ではそうではありません))

闘争:出力は入力が何であっても、ほとんど常に同じです(約0.5)。

重量とバイアスが調整されます。ここで

がコードである(以上ありますが、他のコードは重要ではありません):

public void learnFromData(int iterations) //this method learns from the ArrayList 'inputs' and 'outputs' 
{ 
      if(inputs.size() == outputs.size()) 
      { 
       //Collections.shuffle(inputs); 
       for(int j = 0;j<iterations;j++) 
       { 
       for(int i = 0;i<inputs.size();i++) 
       { 

        double actualOutput = computeOutput(inputs.get(i))[0]; 
        double expectedOutput = outputs.get(i)[0]; 


        //System.out.println(String.format("Input: %.3f /\\ Ouput: %.4f Expected: %.4f",inputs.get(i)[0], actualOutput, expectedOutput)); 
        double error = 0; 
        if (actualOutput > expectedOutput) { 
         error = actualOutput - expectedOutput; 
        } else { 
         error = expectedOutput - actualOutput; 
        } 
        if(i == 0){ 
        System.out.println(String.format("Error: %.10f", error));} 
        learn(outputs.get(i)); 
       } 
      } 
     } 
     else{ 
      System.out.println("\nERROR: the number of inputs and outputs have to match!\n"); 
     } 
    } 
public double[] computeOutput(double[] inputValues) 
    { 

    for(int i = 0;i<inputValues.length;i++) //giving the inputNeurons a value 
    { 
     inputNeurons[i] = inputValues[i]; 
    } 
    for(int i = 0;i<hiddenNeurons.get(0).length;i++) 
    { 
     hSums.get(0)[i] = 0.0; 
    } 
    for(int i = 0;i<aOutputNeurons.length;i++) 
    { 
     hoSums[i] = 0.0; 
    } 
    for(int i = 0;i<inputNeurons.length;i++) //calculating the sums of the hidden neurons (Input-function) 
    { 
     for(int b = 0;b<hiddenNeurons.get(0).length;b++) 
     { 
      hSums.get(0)[b] += inputNeurons[i] * ihWeights[i][b]; 
     } 
    } 
    for(int i = 0;i<hiddenNeurons.get(0).length;i++) //Each bias-value has to be added to its associated sum 
    { 
     hSums.get(0)[i] += hBiases.get(0)[i]; 
    } 


    for(int i = 0;i<hiddenNeurons.get(0).length;i++) 
    { 
     hiddenNeurons.get(0)[i] = Helper.sig(hSums.get(0)[i]); //output-function = sigmoid 
    } 

    //calculating the hSums 
    if(hiddenNeurons.size()>1) 
    { 
     for (int layer = 0;layer<hiddenNeurons.size()-1;layer++) 
     { 
      //calculating the sums of the layer 
      for(int neuron_nextLayer = 0; neuron_nextLayer < hiddenNeurons.get(layer+1).length;neuron_nextLayer++) 
      { 
       hSums.get(layer+1)[neuron_nextLayer] = 0; 
       for(int neuron_actualLayer = 0;neuron_actualLayer < hiddenNeurons.get(layer).length;neuron_actualLayer++) 
       { 
        hSums.get(layer+1)[neuron_nextLayer] += hiddenNeurons.get(layer)[neuron_actualLayer] * hhWeights.get(layer)[neuron_actualLayer][neuron_nextLayer]; 
       } 
      } 
     } 
    } 
    // calculating the sums of the output neurons (Input-function) 
    int lastHiddenLayer = hiddenNeurons.size()-1; 
    for(int i = 0;i<aOutputNeurons.length;i++) 
    { 
     hoSums[i] = 0; 
     for(int b = 0;b<hiddenNeurons.get(lastHiddenLayer).length;b++) 
     { 
      hoSums[i] += hiddenNeurons.get(lastHiddenLayer)[b] * hoWeights[b][i]; 
     } 
     hoSums[i] += hoBiases[i]; 
     aOutputNeurons[i] = Helper.sig(hoSums[i]); 
    } 
    //weightToString(); 
    return aOutputNeurons; 
    } 
    public void learn(double[] cValues) //correctValues 
    { 
    // calculating the output-gradients 
    for(int i = 0;i<aOutputNeurons.length;i++) 
    { 
     oGradients[i] = (cValues[i]-aOutputNeurons[i])*Helper.invSig(aOutputNeurons[i]); 
    } 

    //calculating the hidden-gradients 
    double sum; //sum of all multiplications between gradients of the output layer and the weights between the hidden neuron and each output neuron. 
    int lastHiddenLayer = hiddenNeurons.size()-1; 
    for(int i = 0;i<hiddenNeurons.get(lastHiddenLayer).length;i++) 
    { 
     sum = 0; 
     for(int b = 0;b<aOutputNeurons.length;b++) 
     { 
      sum += oGradients[b] * hoWeights[i][b]; 
     } 
     hGradients.get(lastHiddenLayer)[i] = Helper.invSig(hiddenNeurons.get(lastHiddenLayer)[i]) * sum; 
    } 

    if(hiddenNeurons.size() > 1) 
    { 
     for(int layer = lastHiddenLayer;layer > 0;layer--) 
     { 

      for(int neuron_actualHiddenLayer = 0; neuron_actualHiddenLayer < hiddenNeurons.get(layer-1).length;neuron_actualHiddenLayer++) // neuron_actualHiddenLayer is more in the direction of the input neurons and neuron_nextHiddenLayer more in the direction of the output neurons 
      { 
       sum = 0; 

       for(int neuron_nextHiddenLayer = 0;neuron_nextHiddenLayer < hiddenNeurons.get(layer).length;neuron_nextHiddenLayer++) 
       { 
        sum += hGradients.get(layer)[neuron_nextHiddenLayer] * hhWeights.get(layer-1)[neuron_actualHiddenLayer][neuron_nextHiddenLayer]; 
       } 
       hGradients.get(layer-1)[neuron_actualHiddenLayer] = Helper.invSig(hiddenNeurons.get(layer-1)[neuron_actualHiddenLayer]) * sum; 
      } 
     } 
    } 


    //calculating weight- and biasdeltas of input- to hidden neurons 
    for(int i = 0;i<inputNeurons.length;i++) 
    { 
     for(int b = 0;b<hiddenNeurons.get(0).length;b++) 
     { 
      ihPrevWeightsDeltas[i][b] = eta * hGradients.get(0)[b] * inputNeurons[i]; 
      ihWeights[i][b] += ihPrevWeightsDeltas[i][b]; 
     } 
    } 
    // calculating weight- and biasdeltas of hidden- to hidden neurons 
    if(hiddenNeurons.size() > 1) 
    { 
     for(int layer = 0;layer < hiddenNeurons.size()-1;layer++) 
     { 
      for(int neuron_actualHiddenLayer = 0; neuron_actualHiddenLayer < hiddenNeurons.get(layer).length;neuron_actualHiddenLayer++) // neuron_actualHiddenLayer is more in the direction of the input neurons and neuron_nextHiddenLayer more in the direction of the output neurons 
      { 
       for(int neuron_nextHiddenLayer = 0;neuron_nextHiddenLayer < hiddenNeurons.get(layer+1).length;neuron_nextHiddenLayer++) 
       { 
        hhPrevWeightDeltas.get(layer)[neuron_actualHiddenLayer][neuron_nextHiddenLayer] = eta * hGradients.get(layer+1)[neuron_nextHiddenLayer] * hiddenNeurons.get(layer)[neuron_actualHiddenLayer]; 
        hhWeights.get(layer)[neuron_actualHiddenLayer][neuron_nextHiddenLayer] += hhPrevWeightDeltas.get(layer)[neuron_actualHiddenLayer][neuron_nextHiddenLayer]; 
        hhPrevBiasDeltas.get(layer)[neuron_actualHiddenLayer] = eta*hGradients.get(layer)[neuron_actualHiddenLayer]; 
        hBiases.get(layer)[neuron_actualHiddenLayer] += hhPrevBiasDeltas.get(layer)[neuron_actualHiddenLayer]; 
       } 
      } 
     } 
    } 
    for(int i = 0;i<hiddenNeurons.get(0).length;i++) 
    { 
     ihPrevBiasDeltas[i] = eta*hGradients.get(0)[i]; 
     hBiases.get(0)[i] += ihPrevBiasDeltas[i]; 
    } 
    for(int i = 0;i<aOutputNeurons.length;i++) 
    { 
     hoPrevBiasDeltas[i] = eta*oGradients[i]; 
     hoBiases[i] += hoPrevBiasDeltas[i]; 
    } 
    for(int i = 0;i<hiddenNeurons.get(0).length;i++) 
    { 
     for(int b = 0;b<aOutputNeurons.length;b++) 
     { 
      hoPrevWeightsDeltas[i][b] = eta * oGradients[b] * hiddenNeurons.get(lastHiddenLayer)[i]; 
      hoWeights[i][b] += hoPrevWeightsDeltas[i][b]; 
     } 
    } 

} 
+0

これを[MCVE](http://stackoverflow.com/help/mcve)に変えて読みやすくすることができますか?特に、あなたが手元にある問題とは関係のないコードがあると言っているので、これは*たくさんのコードです。 –

+0

ええ、私は誰かがそれを言うと思った。 しかし、私はどのようにコードを読みやすくすることができますか?あなたはより良い概観(ここでは不可能)を持つコードが少ないか、問題を再現するのに必要なすべての部分を提供するために私が持っているコード全体を入れなければなりませんか? )? – asparagus

+0

'しかし、私はコードをより読みやすくすることができますか?それはあなたの問題です、私たちは既に質問を理解して答えています:)しかし、あなたは、無関係なビットがあると言います。書式を改善し、寛大な気持ちがある場合は、質問に編集して結果をアップロードし、実際に実行するために必要な追加の定型コード(Githubなど)をアップロードしますか? MCVE [here](http://stackoverflow.com/help/mcve)の定義を読んでください。 –

答えて

1

それは、独自のコードであるので、のようないくつかの成熟したプロジェクトを使用して同じネットワークをやってみてくださいNeurophライブラリと結果を比較すると、問題を絞り込むのに役立ちます。

XOR関数が非線形分類問題であることを覚えておいてください。非線形活性化関数で少なくとも2つのレイヤー(1つの入力と1つの非表示)が必要です。それは単に線形分類器が非線形分類を行うために調整することができないため、非線形分類子を持つ必要があります。

+0

私のネットワークが1つのレイヤーだけで構成されていることを、どのように認識しましたか? (たぶん私は質問に間違った何かを策定した)。 私は実際に1つの入力 - 、1つの隠し - と1つの出力層を持っているので。 – asparagus

+1

あなたのコードは本当ですか? Neurophライブラリで試してみて、同じことを試みてください。それは成熟したプロジェクトであり、あなたのコードが正しかったかどうかをテストすることができないので、あなたのコードが大丈夫かどうかを教えてくれるでしょう。それは非常に洗練されていて時間がないからです。 –

+0

私はかなり私が分を持っていると確信しています。 3層。 私は.csvファイルを持っています。ここでは、さまざまなレイヤー間にすべての重みとバイアスを保存しています。 コンストラクタには、実際には3つのレイヤがあることを誰もが見ることができます。 – asparagus

関連する問題