Liebe Community
vor zwei Monaten habe ich mich in das Thema Künstliche Neuronale Netze eingearbeitet,
Bis zuletzt habe ich mich durch ein existierendes in Java programmiertes fully connected Neuronales Netz durchgearbeitet und verstehe auch wie es funktioniert.
Nun wollte ich dieses Netzwerk nachbauen. Jedoch nicht so, dass jedem Neuron ein Array an Gewichtungen zugeteilt wird, sondern dass Objekte mit Gewichtungen die Verbindung zwischen zwei Neuronen darstellen.
Das Ziel dieser Architektur ist es, dass ich beispielsweise Verbindungen löschen kann und so das Netz verändern kann.
Leider lernt das Netzwerk nicht richtig, da der Error nicht abfällt sondern gleich bleibt.
Getestet habe ich mein Netzwerk mit folgendem Aufbau:
- 2 Input Neuronen
- 2 Hidden Neuronen
- 2 Output Neuronen
- Fully Connected
- Trainingsdaten 1: Input: {0.1f,0.5f}, Erwarteter Output: {0.99f,0.01f});
- Trainingsdaten 2: Input: {0.3f,0.9f}, Erwarteter Output: {0.01f,0.99f});
Im folgenden der Backpropagation Algorithmus:
public void backwardPropagation(float learning_rate,TrainingData tData) {
//Update the output neurons for each output
Layer current_layer = layer_array[outputLayer_index];
for(Neuron current_neuron : current_layer.neuron_array) {
float output = current_neuron.value;
float target = tData.expectedOutput[current_neuron.neuron_index];
float delta = output-target; //Calculate difference between currect and expected output
float derivative = delta*output*(1-output);
current_neuron.gradient = derivative;
}
for(Connection current_connection : current_layer.connection_array) {
float previous_output = current_connection.from_neuron.value;
float error = current_connection.to_neuron.gradient*previous_output;
current_connection.cache_weight = current_connection.weight - learning_rate*error;
}
//Update all the subsequent hidden layers
for(int i = outputLayer_index-1; i > 0; i--) {
Layer higher_layer = layer_array[i+1];
current_layer = layer_array[i];
sumGradient(higher_layer);
for(Neuron current_neuron : current_layer.neuron_array) {
float output = current_neuron.value; //Aktuellen Outputwert holen
float gradient_sum = current_neuron.gradient_sum;
float derivative = gradient_sum*output*(1-output);
current_neuron.gradient = derivative;
current_neuron.gradient_sum = 0; //to reset the value
}
// For all connections in that layers
for(Connection current_connection : current_layer.connection_array) {
float previous_output = current_connection.from_neuron.value;
float error = current_connection.to_neuron.gradient*previous_output;
current_connection.cache_weight = current_connection.weight - learning_rate*error;
total_error += error; //only for testing
}
}
// Here we do another pass where we update all the weights
for(Layer curr_layer : layer_array) {
for(Connection current_connection : curr_layer.connection_array) {
current_connection.update_weight();
}
}
public static void sumGradient(Layer currentLayer){
for(Connection current_connection : currentLayer.connection_array) {
current_connection.from_neuron.gradient_sum +=
current _connection.weight*current_connection.to_neuron.gradient;
}
}
}
Was läuft da falsch?
Für Debugging-Informationen gerne fragen.
Vielen Dank schonmal
Euer Moo