mooooo
8. April 2020 um 15:45
1
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
Hallo,
ja, was sagt denn der Debugger?
Als Mensch kann ich nichts sehen, da werden
Methoden aufgerufen, deren Quelltext ich hier nicht habe.
1 „Gefällt mir“
Ich habe nur eine Vorlesung „Neuronale Netze“ vor gut über 20 Jahren gehört, mein Mann hat aber längere Zeit welche programmiert (allerdings nicht in Java, aber das Prinzip bleibt gleich),deswegen habe ich ihn gefragt. Hier seine Antwort:
Auf dem ersten Blick liegt der Fehler an den bescheuerten Trainingsdaten.
Eingangswerte die nahezu gleich sind (0.1, 0.3) sollen diametrale
Ausgangswerte (0.99, 0.01) liefern!
Wenns diese Daten unbedingt sein müssen, dann sollte man die Anzahl der Neuronen
in der hidden-layer erhöhen. das könnte Besserung bringen.
Gruß
Christa
3 „Gefällt mir“
mooooo
9. April 2020 um 08:23
4
Hallo Christa,
danke, ich werde es dann mal mit XOR-Daten verauchen.
Die bisherigen Daten sind nur ganz einfache Testdaten. Bei dem anderen fully connected Network hat das ja auch geklappt und nach 10000 Trainingseinheiten sank der Fehler auf unter 0,004
mooooo
9. April 2020 um 08:25
5
Danke für deine ANtwort. Hier die Funktionsdefinition dazu in der
Connection Class:
public void update_weight() {
this.weight = this.cache_weight;
}
mooooo
9. April 2020 um 09:11
6
Dank Christa habe ich das Netzwerk mit besseren Daten trainiert:
Trainingsdaten 1: Input: {0.1f,0.9f}, Erwarteter Output: {0.99f,0.01f});
Trainingsdaten 2: Input: {0.9f,0.1f}, Erwarteter Output: {0.01f,0.99f});
Nach trainieren des Netzes für 10000 male habe ich es erneut mit den Inputdaten 0.1 und 0.9 getestet. Output: 0.49 and 0.50 (Da es ja exakt dem Trainingsdatum 1 entspricht, sollte 0.9 und 0.1 ausgegeben werden).
mooooo:
Dank Christa
Dank Christas Mann. Reicht dir das, oder soll ich ihn noch etwas fragen?
mooooo
9. April 2020 um 14:12
8
Hallo hroptayr, hier ein paar debug-Informationen, vielleicht helfen sie ja was (dies ist das Consolenoutput nach der 100sten Trainingsiteration):
> Neuron Index: 0; Output: 0.53727806; Target 0.01; derivative: 0.13108678
> Neuron Index: 1; Output: 0.67196816; Target 0.99; derivative: -0.070102796
> Current Connection: Connection 2.0 from neuron 1.0 (0.5633279) to neuron 2.0 (0.53727806) with weight of 0.005410646
> Calculate error: 0.07384484 (error) = 0.13108678 (gradient of to neuron) *0.5633279 (previous_output output of from value)
> Calculate new weight: 0.001718404 (cache_weight) = 0.005410646 (current weight) - 0.05 (learning rate) *0.07384484 (error)
> Current Connection: Connection 2.1 from neuron 1.1 (0.665891) to neuron 2.0 (0.53727806) with weight of 0.21976773
> Calculate error: 0.087289505 (error) = 0.13108678 (gradient of to neuron) *0.665891 (previous_output output of from value)
> Calculate new weight: 0.21540326 (cache_weight) = 0.21976773 (current weight) - 0.05 (learning rate) *0.087289505 (error)
> Current Connection: Connection 2.2 from neuron 1.0 (0.5633279) to neuron 2.1 (0.67196816) with weight of 0.19676349
> Calculate error: -0.03949086 (error) = -0.070102796 (gradient of to neuron) *0.5633279 (previous_output output of from value)
> Calculate new weight: 0.19873802 (cache_weight) = 0.19676349 (current weight) - 0.05 (learning rate) *-0.03949086 (error)
> Current Connection: Connection 2.3 from neuron 1.1 (0.665891) to neuron 2.1 (0.67196816) with weight of 0.9104461
> Calculate error: -0.04668082 (error) = -0.070102796 (gradient of to neuron) *0.665891 (previous_output output of from value)
> Calculate new weight: 0.91278017 (cache_weight) = 0.9104461 (current weight) - 0.05 (learning rate) *-0.04668082 (error)
> ---------------Backward Propagation - Update Hidden Layer----------------------
> Calculate Gradient Sum: Current Connection: Connection 2.0 from neuron 1.0 (0.5633279) to neuron 2.0 (0.53727806) with weight of 0.005410646
> Calculate gradient sum: 7.092642E-4 (gradient sum of of_neuron) += 0.005410646 (current weight) * 0.13108678 (gradient of to_neuron)
> Calculate Gradient Sum: Current Connection: Connection 2.1 from neuron 1.1 (0.665891) to neuron 2.0 (0.53727806) with weight of 0.21976773
> Calculate gradient sum: 0.028808646 (gradient sum of of_neuron) += 0.21976773 (current weight) * 0.13108678 (gradient of to_neuron)
> Calculate Gradient Sum: Current Connection: Connection 2.2 from neuron 1.0 (0.5633279) to neuron 2.1 (0.67196816) with weight of 0.19676349
> Calculate gradient sum: -0.013084406 (gradient sum of of_neuron) += 0.19676349 (current weight) * -0.070102796 (gradient of to_neuron)
> Calculate Gradient Sum: Current Connection: Connection 2.3 from neuron 1.1 (0.665891) to neuron 2.1 (0.67196816) with weight of 0.9104461
> Calculate gradient sum: -0.03501617 (gradient sum of of_neuron) += 0.9104461 (current weight) * -0.070102796 (gradient of to_neuron)
> Neuron Index: 0; Output: 0.5633279; gradient_sum -0.013084406; derivative: -0.0032186275
> Neuron Index: 1; Output: 0.665891; gradient_sum -0.03501617; derivative: -0.0077904044
> Current Connection: Connection 1.0 from neuron 0.0 (0.1) to neuron 1.0 (0.5633279) with weight of 0.36743715
> Calculate error: -3.2186275E-4 (error) = -0.0032186275 (gradient of to neuron) *0.1 (previous_output output of from value)
> Calculate new weight: 0.36745325 (cache_weight) = 0.36743715 (current weight) - 0.05 (learning rate) *-3.2186275E-4 (error)
> Current Connection: Connection 1.1 from neuron 0.1 (0.9) to neuron 1.0 (0.5633279) with weight of 0.24215068
> Calculate error: -0.0028967648 (error) = -0.0032186275 (gradient of to neuron) *0.9 (previous_output output of from value)
> Calculate new weight: 0.24229552 (cache_weight) = 0.24215068 (current weight) - 0.05 (learning rate) *-0.0028967648 (error)
> Current Connection: Connection 1.2 from neuron 0.0 (0.1) to neuron 1.1 (0.665891) with weight of 0.6522459
> Calculate error: -7.7904045E-4 (error) = -0.0077904044 (gradient of to neuron) *0.1 (previous_output output of from value)
> Calculate new weight: 0.65228486 (cache_weight) = 0.6522459 (current weight) - 0.05 (learning rate) *-7.7904045E-4 (error)
> Current Connection: Connection 1.3 from neuron 0.1 (0.9) to neuron 1.1 (0.665891) with weight of 0.6938156
> Calculate error: -0.0070113637 (error) = -0.0077904044 (gradient of to neuron) *0.9 (previous_output output of from value)
> Calculate new weight: 0.6941662 (cache_weight) = 0.6938156 (current weight) - 0.05 (learning rate) *-0.0070113637 (error)
mooooo
9. April 2020 um 14:15
9
naja er lernt leider mit den besseren Trainingsdaten auch nicht richtig
Hast du die Hidden Neuronen erhöht oder nicht? Wenn nicht, versuch’s doch mal.
mooooo
9. April 2020 um 14:20
11
Hi Christa,
die hidden Neuronen habe ich nicht erhöht, da er in dem neuronalen Netz, das ich nachbauen möchte, mit den selben Inputs den erwarteten Output liefert.
Das Netz was ich nachbauen möchte hat genau die selbe Architektur
Nur eben macht das mein neuronales Netz nicht.
mooooo
9. April 2020 um 18:27
12
Hidden Neuronen erhöhen bewirkt nur, dass sich beide Werte der Outputneuronen gleichmäßig erhöhen
mooooo
10. April 2020 um 21:01
13
Hat sich erledigt, der Fehler war, dass ich die Inputfelder cor der forwardPropagation nicht befüllt habe
Fronk
10. April 2020 um 21:45
14
Ja… da sieht man mal wieder, wie wichtig die very connected high-performance distribution ist. Von den Neuronen weiss ich nur, dass diese im high-performance room irre resistible sind…
1 „Gefällt mir“
system
Geschlossen,
12. April 2020 um 09:45
15
Dieses Thema wurde automatisch 36 Stunden nach der letzten Antwort geschlossen. Es sind keine neuen Nachrichten mehr erlaubt.