0

Ich versuche, ein einfaches neuronales Netzwerk zu implementieren. Ich weiß, dass da draußen schon eine Menge Bibliotheken vorhanden sind, darum geht es nicht.Backpropagation für neuronales Netzwerk

My Netzwerk hat nur 3 Schichten: eine Eingangsschicht eine verborgene Schicht eine Ausgangsschicht

die Ausgabeschicht ist mit 8 Neuronen jeweils eine andere Klasse repräsentiert.

Ich habe verstanden, wie man den feedfoward algorythm einführt, aber ich kämpfe wirklich für die backpropagation.

hier ist, was ich mit so weit habe kommen:

private void backPropagation(List<List<Input>> trainingData) 
{ 
    List<Input> trainingSet = new ArrayList<Input>(); 
    for (int row = 0; row < trainingData.size(); row++) {   
     trainingSet = trainingData.get(row); 
     //we start by getting the output of the network 
     List<Double> outputs = feedFoward(trainingSet); 

     //Im using the Iris dataset, so here the desiredOutput is 
     //the species where 
     // 1 : setosa 
     // 2 : versicolor 
     // 3 : virginica 
     double desiredOutput = getDesiredOutputFromTrainingSet(trainingSet);  
     //We are getting the output neuron that fired the highest result 
     //like if we have 
     //Ouput layer : 
     //Neuron 1 --> 0.001221513 
     //Neuron 2 --> 0.990516510 
     //Neuron 3 --> 0.452221000 
     //so the network predicted that the trainingData correspond to (2) versicolor 
     double highestOutput = Collections.max(outputs); 
     //What our neuron should aim for 
     double target = 0; 

     List<Double> deltaOutputLayer = new ArrayList<Double>(); 
     List<List<Double>> newWeightsOutputLayer = new ArrayList<List<Double>>(); 
     for (int j = 0; j < outputs.size(); j++) { 
      double out = outputs.get(j); 
      //Important to do j + 1 because the species classes start at 1 (1 : setosa, 2: versicolor, 3:virginica) 
      if(out == highestOutput && (j + 1) == desiredOutput) 
       target = 0.99; //1 
      else 
       target = 0.01; //0 

      //chain rule 
      double delta = (out - target) * LogisticFonction.sigmoidPrime(out); 
      deltaOutputLayer.add(delta); 


      //get the new weigth value from delta and neta 
      List<Double> newWeights = new ArrayList<Double>(); 
      for (int weightIndex = 0; weightIndex < _outputLayer.get(j).get_weigths().size(); weightIndex++) { 
       double gradient = delta * _outputsAfterActivationHiddenLayer.get(weightIndex); 
       double newWeight = _outputLayer.get(j).get_weigths().get(weightIndex) - (_learningRate * gradient); 
       newWeights.add(newWeight); 
      } 
      newWeightsOutputLayer.add(newWeights); 
     } 

     //hidden layer 
     double totalError = 0; 
     for (int i = 0; i < _neuronsHiddenLayer.size(); i++) { 
      for (int j = 0; j < deltaOutputLayer.size(); j++) { 
       double wi = _outputLayer.get(j).get_weigths().get(i); 
       double delta = deltaOutputLayer.get(j); 
       double partialError = wi * delta; 
       totalError += partialError; 
      } 

      double z = _outputsAfterActivationHiddenLayer.get(i); 
      double errorNeuron = LogisticFonction.sigmoidPrime(z); 

      List<Double> newWeightsHiddenLayer = new ArrayList<Double>(); 

      for (int k = 0; k < _neuronsHiddenLayer.get(i).get_weigths().size(); k++) { 
       double in = _neuronsHiddenLayer.get(i).get_inputs().get(k); 
       double gradient = totalError * errorNeuron * in; 
       double oldWeigth = _neuronsHiddenLayer.get(i).get_weigths().get(k); 
       double newWeigth = oldWeigth - (_learningRate * gradient); 
       _neuronsHiddenLayer.get(i).get_weigths().set(k, newWeigth); 
       newWeightsHiddenLayer.add(newWeigth); 
      } 
     } 


     //then update the weigth of the output layer with the new values. 
     for (int i = 0; i < newWeightsOutputLayer.size(); i++) { 
      List<Double> newWeigths = newWeightsOutputLayer.get(i); 
      _outputLayer.get(i).set_weigths(newWeigths); 
     } 
    } 
} 

Ich versuche Tests mit dem Iris-Datensatz haben: https://en.wikipedia.org/wiki/Iris_flower_data_set

aber mein Ergebnis sehr inkonsistent sind führende mich dort zu glauben ist ein Fehler in meinem backpropagation algorythm.

Wenn jemand einige größere Fehler sehen kann, sagen Sie mir bitte!

vielen Dank.

Antwort

0

In diesem Teil des Codes:

if(out == highestOutput && (j + 1) == desiredOutput) 
    target = 0.99; //1 
else 
    target = 0.01; //0 

Das Ziel Ausgabe des Neurons ist, wenn die Bedingung 0.99(out == highestOutput && (j + 1) == desiredOutput). Das bedeutet, dass Sie nur erwarten würden, dass die Ausgabe des Neurons 0.99 ist, wenn der Feedforward das gleiche Neuron wie das Trainingsbeispiel ausgibt. Das ist falsch.

Die Bedingung für diesen Teil des Codes sollte nur (j + 1) == desiredOutput sein. Entfernen Sie out == highestOutput Zustand. Die Zielausgabe sollte 0.99 für das gewünschteAutorneuron sein, egal ob die Vorwärtskopplung in diesem Neuron resultiert oder nicht. Dies ist also der korrigierte Code:

if((j + 1) == desiredOutput) 
    target = 0.99; //1 
else 
    target = 0.01; //0