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.