Neuronales Netz - Aufbau und Wirkungsweise

Allgemeines

Die verwendeten Netze sind beide mehrlagige Perzeptrons (multilayer perceptron, MLP). Ein MLP ist ein Neuronales Netz, bestehend aus Neuronen der Eingabeschicht (Inputschicht), der Ausgabeschicht (Outputschicht) und einer oder mehrerer verborgener Schichten (Hiddenschicht). Dabei sind alle Neuronen einer Schicht vollständig mit den Neuronen der nächsten Schicht verbunden (feed-forward). Das Netz wird mit Hilfe des Backpropagation-Algorithmus trainiert, bis es die gewünschte Qualität erreicht hat.

Einen guten Einstieg in Aufbau und Funktion Neuronaler Netze findet man hier (Uni Münster).

Das Pacecar-Netz

Das Pacecar-Netz ist die "Steuereinheit", die es dem Neuroauto ermöglicht, stets einen ausreichenden Abstand zum Vordermann zu halten. Es soll also das Verhalten eines Autofahrers nachbilden, der - je nachdem, wie hoch seine Geschwindigkeit ist, welchen Abstand er gerade zum Vordermann hat und ob sich dieser Abstand gerade verringert oder vergrößert - sein Auto abbremst oder beschleunigt. Sein Ziel ist es, schnell voranzukommen, ohne aber dabei zu dicht aufzufahren und damit womöglich einen Unfall zu riskieren. Dieses "Verfolgen" des Vorgängers kennt man auch von Autorennen, z.B. Formel 1, wo ein Pacecar voranfährt und die Rennwagen auf ihre Startplätze leitet. Daher leitet sich auch der Name Pacecar-Netz ab.

Pacecar-Netz Das Netz hat somit folgende Ein- und Ausgaben:

Eingabeneuron realer Wertebereich transformierter Wertebereich
Eigengeschwindigkeit (EG) [0 ; 50] m/s [0.1 ; 0.9]
Geschwindigkeit des Pacecars (GP) [0 ; 50] m/s [0.1 ; 0.9]
Abstand zum Pacecar (AP) [0 ; 800] m [0.1 ; 0.9]
     
Ausgabeneuron Wertebereich  
Beschleunigung (A) 0 | 0.5 | 1 [0.1 ; 0.9]

Es wird angenommen, dass der Fahrer bis zu 120 m nach vorn ein Fahrzeug erkennen kann. Ist kein Fahrzeug in diesem Sichtbereich, wird als Abstandswert 800 m genommen, um eine unendliche Entfernung des Pacecars abbilden zu können.

Transformation des Abstands

Aus simulationstechnischen Gründen wird die Beschleunigung nicht stetig, sondern diskret beschrieben, wobei 0 → bremsen und 1 → beschleunigen bedeutet. Die Beschleunigung a ist dabei immer ±1 m/s². Für A = 0.5 wird nicht beschleunigt.

Für das Pacecar-Netz hat sich eine Netzstruktur mit 1 Hiddenschicht à 10 Neuronen als günstig erwiesen. Weniger Neuronen hätten das Erlernen deutlich erschwert bzw. unmöglich gemacht, wohingehen zu viele Neuronen die Generalisierungsfähigkeit beeinträchtigt hätten. Als Aktivierungsfunktion wird die logistische Funktion

logistische Funktion

verwendet. Sicherlich ließen sich auch andere Aktivierungsfunktionen wie z.B. tanh(x) verwenden.

Trainingsdaten

Anders als beim SpeedLane-Netz lernt das Pacecar-Netz nicht das Verhalten des Testfahrers. Der Sollwert für den optimalen Sicherheitsabstand zum Vordermann ist vorgegeben: Er ist ähnlich der bekannten Daumenregel "Halber Tacho" definiert: Abstand = 3 × Geschwindigkeit [m/s]
Zur Ermittlung des Outputs (Beschleunigung) wird eine Fallunterscheidung genutzt. Diese enthält Fälle wie z.B.
Wenn EG == GP und AP > 3*EG, dann sei A := 1
Wenn...

Training

Zum Trainieren des Netzes wird der Backpropagation-Algorithmus eingesetzt. Dabei wird der Fehler an der Ausgabeschicht ermittelt und die Gewichte werden rückwärts bis zur Eingabeschicht korrigiert. Für das Pacecar-Netz wird ein tolerierter Fehler, d.h. der maximale Netzfehler, von 0.1 festgelegt. Das Training wird nun solange fortgesetzt, bis der tolerierte Fehler unterschritten oder die max. Anzahl an Trainingsschritten erreicht ist.
In Abhängigkeit von der Qualität der angelegten Muster führte eine Lernrate von 0.4 gleichmäßig und schnell zur Konvergenz. Nicht gleichmäßig, dafür aber schneller konnte das Netz mit Zuhilfenahme eines Momentums angelernt werden. Dieser Faktor berücksichtigt die Gewichtskorrektur des vorherigen Trainingsschritts und sollte möglichst größer als die Lernrate gewählt werden. Für das Pacecar-Netz eignete sich ein Momentum von 0.9 in Verbindung mit einer Lernrate von 0.1.

Das SpeedLane-Netz

SpeedLane-Netz Das SpeedLane-Netz soll es dem Neuroauto ermöglichen, bei ausreichend sicherer Verkehrslage den Vordermann zu überholen. Dafür sind eine Reihe von Eingaben nötig:

Eingabeneuron realer Wertebereich transformierter Wertebereich
Eigengeschwindigkeit (EG) [0 ; 50] m/s [0.1 ; 0.9]
Abstand zum Vorgänger der eigenen Spur (AVE) [0 ; 800] m [0.1 ; 0.9]
Abstand zum Vorgänger der Gegenspur (AVG) [0 ; 800] m [0.1 ; 0.9]
Abstand zum Nachfolger der eigenen Spur (ANE) [0 ; 800] m [0.1 ; 0.9]
Abstand zum Nachfolger der Gegenspur (ANG) [0 ; 800] m [0.1 ; 0.9]
Geschwindigkeit des Vorgängers der eigenen Spur (GVE) [0 ; 50] m/s [0.1 ; 0.9]
Geschwindigkeit des Vorgängers der Gegenspur (GVG) [0 ; 50] m/s [0.1 ; 0.9]
Geschwindigkeit des Nachfolger der eigenen Spur (GNE) [0 ; 50] m/s [0.1 ; 0.9]
Geschwindigkeit des Nachfolger der Gegenspur (GNG) [0 ; 50] m/s [0.1 ; 0.9]
eigene Spur (S) 0 | 1 [0.1 ; 0.9]
     
Ausgabeneuron Wertebereich  
Spurwechsel (W) 0 | 1 [0.1 ; 0.9]

Die zwei Autobahnspuren sind nummeriert, wobei die rechte Spur 0 und die linke Spur 1 ist. Das Ausgabeneuron Spurwechsel liefert einen bool'schen Wert: 1 → Spur wechseln, 0 → Spur beibehalten

Für das SpeedLane-Netz hat sich ebenfalls 1 Hiddenschicht mit 10 Neuronen als eine günstige Variante erwiesen. Aber auch ein Netz mit zwei Hiddenschichten (1. Schicht 6 Neuronen, 2. Schicht 5 Neuronen) liefert gute Ergebnisse. Zu wenige Neuronen veranlassten das Neuroauto bei stärkerem Verkehr zu ständigem Wechseln der Fahrspur. Ebenso wechselte das Auto bei freier Fahrbahn nicht von der linken auf die rechte Spur.

Trainingsdaten

Ein weiteres Problem war die Beschaffung repräsentativer Trainingsdaten. Da das Ziel war, dem Netz den Fahrstil des Testfahrers anzulernen, mussten dessen Überholentscheidungen als Output gespeichert werden. Dies geschieht beim Drücken der Pfeiltasten ← und →. Entscheidet sich der Fahrer aber, nicht zu überholen, drückt er auch keine Taste und somit wird kein Datensatz aufgezeichnet.

Umsetzung in Java™

Folgende Klassen wurden erstellt:

Net Das Netz. Enthält Trainingseinstellungen sowie Input-, Output- und Hiddenlayer und Funktionen zum Laden und Speichern im PMML-Format.
Layer Ein Layer, der eine Anzahl an Neuronen enthält.
InputLayer Der erste Layer im Netz. Er nimmt die Netzeingaben entgegen.
OutputLayer Der letzte Layer im Netz. Hier wird der Netzfehler berechnet und von hier aus beginnt die Gewichtskorrektur. Dabei wird das Fehlersignal jeweils an den vorhergehenden Layer weitergegeben.
ConnectionMatrix Die Verbindungsmatrix zwischen zwei Layern. Hält sämtliche Verbindungen zwischen Neuronen, die Gewichte, die Biasgewichte sowie die Gewichtskorrekturen des vorherigen Lernschrittes (für Momentum-Einfluss). Die Gewichtskorrekturen werden ebenfalls in dieser Klasse vorgenommen.
Activation Hauptklasse für die Aktivierung. Sie definiert lediglich das Gerüst für eine Aktivierungsfunktion. Ableitende Klassen XxxActivation implementieren eine Aktivierungsfunktion und deren Ableitung. (siehe Strategiemuster)
Utils Stellt Funktionen zur Transformation von Vektoren und Matrizen in einen anderen Wertebereich bereit.

Beispiel für die Erstellung eines Neuronalen Netzes:

 Net net = new Net("My Neural Network");
 net.setInputLayer(new InputLayer(3));
 net.addHiddenLayer(new Layer(5));
 net.setOutputLayer(new OutputLayer(1));
 net.connectLayers(true);
 net.setLearningRate(0.5);
 net.setToleratedError(0.1);
Nachdem das Netz erstellt worden ist, kann es genutzt werden:
 net.propagate(inputPattern[]);                   // liefert den Output für ein Pattern
 net.train(1000, inputPatterns[][], targets[][]); // trainiert das Netz (1000 Schritte)
 net.saveToXML("myneuralnet.xml");                // speichert das Netz im PMML-Format