kramann.info
© Guido Kramann

Login: Passwort:










Robuste Systemintegration
1 Grundlagen
..1.1 Newton
....1.1.1 LinearSchwinger
....1.1.2 Daempfung
....1.1.4 ODE
....1.1.5 Saaluebung
..1.2 NewtonEuler
....1.2.1 Traegheitsmomente
....1.2.2 Modellgleichungen
....1.2.3 Einfachpendel
..1.3 Scilab
....1.3.1 Erste_Schritte
....1.3.2 Skripte
....1.3.3 Funktionen
..1.4 Laplace
....1.4.1 Eigenwerte
....1.4.2 PT1
..1.5 Regleroptimierung
....1.5.1 Guetefunktion
....1.5.2 Heuristiken
....1.5.3 Scilab
..1.6 Einstellregeln
....1.6.1 Totzeit
....1.6.2 Methode1
....1.6.3 Methode2
....1.6.4 Scilab
..1.7 Zustandsregler
..1.8 Polvorgabe
..1.8 Polvorgabe_alt
..1.9 Beobachter
....1.9.1 Haengependel
..1.10 Daempfungsgrad
..1.11 Processing
....1.11.1 Installation
....1.11.2 Erste_Schritte
....1.11.3 Mechatronik
....1.11.4 Bibliotheken
....1.11.5 Uebung
....1.11.6 Snippets
......1.11.6.1 Dateioperationen
......1.11.6.2 Bilder
......1.11.6.3 GUI
......1.11.6.4 Text
......1.11.6.5 PDF
......1.11.6.8 Maus
......1.11.6.10 Zeit
......1.11.6.13 Animation
......1.11.6.15 Simulation
....1.11.7 Referenzen
..1.12 Breakout
2 Beispiel
3 Beispielloesung
4 Praxis
5 javasci
6 Fehlertoleranz1
7 Reglerentwurf
..7.1 Sprungantwort
..7.2 Messdaten
..7.3 Systemidentifikation
..7.4 Polvorgabe
..7.5 Beobachter
..7.6 Robuster_Entwurf
..7.7 SIL
8 Systementwicklung
9 Arduino
..9.1 Lauflicht
..9.2 Taster
..9.3 Sensor
..9.12 Motor_PWM1
..9.13 Motor_PWM2_seriell
..9.14 Motor_PWM3_analogWrite
..9.15 Scheduler
..9.20 AV
..9.21 Mikrofon
..9.22 Universal
....9.22.1 Laborplatine
....9.22.2 LED_Leiste
....9.22.3 Motortreiber
....9.22.4 Sensoreingaenge
....9.22.5 Taster
....9.22.6 Tests
....9.22.7 Mikrofon
....9.22.8 Lautsprecher
....9.22.9 Fahrgestell
..9.23 Zauberkiste
..9.24 OOP
....9.24.1 Uebungen
..9.25 AVneu
....9.25.1 Tests
..9.26 DA_Wandler
..9.27 CompBoard
....9.27.1 Tastenmatrix
....9.27.2 ASCIIDisplay
..9.28 CTC
..9.29 Tonerzeugung
10 EvoFuzzy
..10.1 Fuzzy
....10.1.1 Fuzzylogik
....10.1.2 FuzzyRegler
....10.1.3 Uebung9
....10.1.5 Softwareentwicklung
......10.1.5.1 AgileSoftwareentwicklung
......10.1.5.2 FuzzyRegler
......10.1.5.3 Uebung
....10.1.6 Umsetzung
......10.1.6.1 FuzzyRegler
......10.1.6.2 Simulation
......10.1.6.3 Optimierung
......10.1.6.4 Uebung
....10.1.7 Haengependel
......10.1.7.1 Haengependel
......10.1.7.2 Simulation
......10.1.7.3 FuzzyRegler
......10.1.7.4 Optimierer
......10.1.7.5 Genetisch
....10.1.8 Information
....10.1.9 Energie
..10.2 Optimierung
....10.2.1 Gradientenverfahren
....10.2.2 Heuristiken
....10.2.3 ModifizierteG
....10.2.4 optim
..10.3 Genalgorithmus
..10.4 NeuronaleNetze
....10.4.1 Neuron
....10.4.2 Backpropagation
....10.4.3 Umsetzung
....10.4.4 Winkelerkennung
..10.5 RiccatiRegler
11 Agentensysteme
12 Simulation
20 Massnahmen
21 Kalmanfilter
..21.1 Vorarbeit
..21.2 Minimalversion
..21.3 Beispiel
30 Dreirad
31 Gleiter
..31.1 Fehlertoleranz
80 Vorlesung_2014_10_01
81 Vorlesung_2014_10_08
82 Vorlesung_2014_10_15
83 Vorlesung_2014_10_22
84 Vorlesung_2014_10_29

10.4.3 Umsetzung eines Backpropagation Algorithmus

Als Beispiel für die Umsetzung des Backpropagation-Verfahrens zum Belernen eines Neuronalen Netzes wird ein Netz mit zwei Einangsneuronen, einer Zwischenschicht mit vier Neuronen und einer Ausgangsschicht mit einem Neuron verwendet.

Das Netz soll entsprechend den vorangegangenen Ausführungen die Antivalenz-Logik lernen. Es werden folgende Bezeichnungen verwendet:

  • in0, in1: Eingänge
  • w0..w15: Gewichte der Netzverbindungen
  • u0..u6: Summierte Eingangssignale
  • n10, n11: Ausgangs-Aktivierung der Neuronen der Eingangsschicht
  • n21, n22, n23, n24: Ausgangs-Aktivierung der Neuronen der Zwischenschicht
  • n30: Ausgangs-Aktivierung der Neuronen der Ausgangsschicht
Netz für das der Backpropagation Algorithmus umgesetzt werden soll.

Bild 10.4.3-1: Netz für das der Backpropagation Algorithmus umgesetzt werden soll.

  • Dass die Zwischenschicht nun vier Neuronen besitzt, sorgt mit dafür, dass die notwendige Information zur Realisierung des Antivalenz-Gatters im Netz repräsentiert werden kann.

Das Backpropagatioverfahren wird für das Netz direkt innerhalb einer Klasse umgesetzt werden, um die Komplexität der Darstellung möglichst gering zu halten. Ebensowenig werden Verknüpfungstabellen verwendet, um die Vernetzung darzustellen, sondern die Verknüpfung wird unmittelbar in der Ausgangsberechnung und beim Backpropagationschritt sichtbar. Der folgende Quellcode stellt also obiges Neuronale Netz dar und einen auf diesem Netz wirkenden Backpropagation-Algorithmus.

import java.util.Random;
public class Backpropagation
{
    public static double[] u = new double[7];
    public static double n10,n11,n20,n21,n22,n23,n30;
    public static double sigmoid(double u)
    {
        return 1.0 / ( 1.0 + Math.exp(-u) );
    }
    public static double ableitung_sigmoid(double u)
    {
        return Math.exp(-u) / ( ( 1.0 + Math.exp(-u) )*( 1.0 + Math.exp(-u) ) );
    }
    public static double netz(double in0, double in1,double[] w)
    {
        u[0] = in0*w[0]+in1*w[1];
        u[1] = in0*w[2]+in1*w[3];
        n10 = sigmoid(u[0]);
        n11 = sigmoid(u[1]);
        u[2] = n10*w[4]+n11*w[5];
        u[3] = n10*w[6]+n11*w[7];
        u[4] = n10*w[8]+n11*w[9];
        u[5] = n10*w[10]+n11*w[11];
        n20 = sigmoid(u[2]);
        n21 = sigmoid(u[3]);
        n22 = sigmoid(u[4]);
        n23 = sigmoid(u[5]);
        u[6] = n20*w[12]+n21*w[13]+n22*w[14]+n23*w[15];
        n30 = sigmoid(u[6]);
        return n30;
    }
    public static double berechneFehler(double in0, double in1, double sollout, double[] w)
    {
        double ausgang = netz(in0,in1,w);
        return (ausgang-sollout)*(ausgang-sollout);
    }
    public static double berechneFehler(double[] w)
    {
        double ausgang;      
        double fehler = 0.0;
        double fehler_aktuell = 0.0;
        fehler_aktuell = berechneFehler(0.0,0.0,0.0,w);
        ausgang = netz(0.0,0.0,w);
        System.out.println("in: 0 0 sollout: 0, istwert:"+ausgang);
        fehler += fehler_aktuell;
        fehler_aktuell = berechneFehler(0.0,1.0,1.0,w);
        ausgang = netz(0.0,1.0,w);
        System.out.println("in: 0 1 sollout: 1, istwert:"+ausgang);
        fehler += fehler_aktuell;
        fehler_aktuell = berechneFehler(1.0,0.0,1.0,w);
        ausgang = netz(1.0,0.0,w);
        System.out.println("in: 1 0 sollout: 1, istwert:"+ausgang);
        fehler += fehler_aktuell;
        fehler_aktuell = berechneFehler(1.0,1.0,0.0,w);
        ausgang = netz(1.0,1.0,w);
        System.out.println("in: 1 1 sollout: 0, istwert:"+ausgang);
        fehler += fehler_aktuell;
        return fehler;
    }
    public static void backpropagation(double in0, double in1, double sollout,
                                       double lernfaktor, double[] w)
    {
//Übung: Korrektheit der Implementierung prüfen:
        double[] Q = new double[w.length];
        double istout = netz(in0,in1,w); //hier wird auch u[0..6] bstimmt!
        //Zuleitungen zu Ausgangsschicht:
        Q[12] = ableitung_sigmoid(u[6])*(sollout - istout);
        w[12] += lernfaktor*Math.abs(n20)*Q[12];
        Q[13] = ableitung_sigmoid(u[6])*(sollout - istout);
        w[13] += lernfaktor*Math.abs(n21)*Q[13];
        Q[14] = ableitung_sigmoid(u[6])*(sollout - istout);
        w[14] += lernfaktor*Math.abs(n22)*Q[14];
        Q[15] = ableitung_sigmoid(u[6])*(sollout - istout);
        w[15] += lernfaktor*Math.abs(n23)*Q[15];
        //Zuleitung zu Zwischenschicht:
        Q[4]  = ableitung_sigmoid(u[2])*(w[12]*Q[12]);
        w[4] += lernfaktor*Math.abs(n10)*Q[4]; //nur die hinführenden, nicht alle
        Q[5]  = ableitung_sigmoid(u[2])*(w[12]*Q[12]);
        w[5] += lernfaktor*Math.abs(n11)*Q[5];
        Q[6]  = ableitung_sigmoid(u[3])*(w[13]*Q[13]);
        w[6] += lernfaktor*Math.abs(n10)*Q[6]; //nur die hinführenden, nicht alle
        Q[7]  = ableitung_sigmoid(u[3])*(w[13]*Q[13]);
        w[7] += lernfaktor*Math.abs(n11)*Q[7];
        Q[8]  = ableitung_sigmoid(u[4])*(w[14]*Q[14]);
        w[8] += lernfaktor*Math.abs(n10)*Q[8]; //nur die hinführenden, nicht alle
        Q[9]  = ableitung_sigmoid(u[4])*(w[14]*Q[14]);
        w[9] += lernfaktor*Math.abs(n11)*Q[9];
        Q[10]  = ableitung_sigmoid(u[5])*(w[15]*Q[15]);
        w[10] += lernfaktor*Math.abs(n10)*Q[10]; //nur die hinführenden, nicht alle
        Q[11]  = ableitung_sigmoid(u[5])*(w[15]*Q[15]);
        w[11] += lernfaktor*Math.abs(n11)*Q[11];
        //Zuleitung zu Eingangsschicht:
        Q[0]  = ableitung_sigmoid(u[0])*(w[4]*Q[4]+w[6]*Q[6]+w[8]*Q[8]+w[10]*Q[10]);
        w[0] += lernfaktor*Math.abs(in0)*Q[0]; //nur die hinführenden, nicht alle
        Q[1]  = ableitung_sigmoid(u[1])*(w[5]*Q[5]+w[7]*Q[7]+w[9]*Q[9]+w[11]*Q[11]);
        w[1] += lernfaktor*Math.abs(in1)*Q[1]; //nur die hinführenden, nicht alle
        Q[2]  = ableitung_sigmoid(u[0])*(w[4]*Q[4]+w[6]*Q[6]+w[8]*Q[8]+w[10]*Q[10]);
        w[2] += lernfaktor*Math.abs(in0)*Q[2]; //nur die hinführenden, nicht alle
        Q[3]  = ableitung_sigmoid(u[1])*(w[5]*Q[5]+w[7]*Q[7]+w[9]*Q[9]+w[11]*Q[11]);
        w[3] += lernfaktor*Math.abs(in1)*Q[3]; //nur die hinführenden, nicht alle
    }
    public static void main(String[] args)
    {
        double[] w = new double[16];
        Random random = new Random(0);
        for(int i=0;i<w.length;i++)
            w[i] = 2.0*random.nextDouble()-1.0;  //[-1,+1]
        for(int i=0;i<2000;i++)
        {
            backpropagation(0.0,0.0,0.0,1.0,w);
            backpropagation(0.0,1.0,1.0,1.0,w);
            backpropagation(1.0,0.0,1.0,1.0,w);
            backpropagation(1.0,1.0,0.0,1.0,w);
            if(i%100==0)
                System.out.println("Fehler = "+berechneFehler(w));
        }
    }
}

Code 10.4.3-1: Neuronales Netz zur Realisierung eines NAND-Gatters mit Backpropagation Algorithmus.

Übung
  1. Testen Sie obiges Programm.
  2. Vollziehen Sie die Implementierung des Backpropagation-Algorithmus nach. Bilden Sie u.a. selber zur Kontrolle die Ableitung der verwendeten sigmoiden Schwellwert-Funktion.
  3. Variieren Sie die Lernrate: Ab welcher Lernrate konvergiert die Lösung nicht mehr?
  4. Versuchen Sie die Anzahl der Backpropagationschritte dadurch zu verringern, dass Sie eine automatische Anpassung der Lernrate implementieren. Wie kann diese aussehen? Wettbewerb: möglichst wenig Iterationsschritte verbrauchen, um einen maximalen Fehler beim Ausgang von einem Prozent zu erzielen.
  5. Entwerfen Sie möglichst konkret ein Neuronales Netz als Grundlage für ein Fahrzeug mit Linienverfolgung mittels einer USB-Kamera. Bedenken Sie, dass viele Netz-Verknüpfungen auch einen hohen Rechenaufwand bei der Auswertung und beim Belernen bedeutet.