Neuronales Netz lernt nicht richtig, Error verringert sich nicht

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 Like

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 Like

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

Danke für deine ANtwort. Hier die Funktionsdefinition dazu in der
Connection Class:

public void update_weight() {
 this.weight = this.cache_weight;
}

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).

Dank Christas Mann. :wink: Reicht dir das, oder soll ich ihn noch etwas fragen?

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)

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.

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.

Hidden Neuronen erhöhen bewirkt nur, dass sich beide Werte der Outputneuronen gleichmäßig erhöhen

Hat sich erledigt, der Fehler war, dass ich die Inputfelder cor der forwardPropagation nicht befüllt habe

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 Like

Dieses Thema wurde automatisch 36 Stunden nach der letzten Antwort geschlossen. Es sind keine neuen Nachrichten mehr erlaubt.