Benutzer-Werkzeuge

Webseiten-Werkzeuge


Seitenleiste

ss19:exkurs_genetische_algorithmen

Genetische Algorithmen und neuronale Netze

Einführung:

Das Miniprojekt: „Genetische Algorithmen und neuronale Netze“ beschäftigt sich mit einfacher algorithmischer Evolution.
Anhand eines evolutionären Programms werden wir zwei verschiedene Strukturen betrachten.
Zum einen wird das Modell: Cartpole Ausgewertet, und zum anderen werden wir am Modell: Bipedal-Walker herumprobieren.
Stefan hat hierfür eine Übersicht und Aufgaben zur Verfügung gestellt, welche sich inklusive Code (jupyter-Notebook) am Ende des Exkurs' in der .zip-Datei befinden.
Auf diese Arbeitsblätter wird sich auch diese Doku stützen, aber zunächst erstmal:

Definition: Machine Learning
Machine Learning ist ein Teilbereich der Künstlichen Intelligenz.
Auf Grundlage zur Vefügung gestellter Daten, den sogenannten Testdaten, und dem gegebenen Algorithmus werden mithilfe des maschinellen Lernens Gesetzmäßigkeiten und Muster erkannt.
Anhand dieser Gesetzmäßigkeiten ist das System nun in der Lage Lösungen zu entwickeln.
Diese Lösungen können verallgemeinert werden und nun jene Probleme auch mit unbekannten Daten lösen.
Quelle: https://www.bigdata-insider.de/was-ist-machine-learning-a-592092/

Einführende Sätze des ipython-Notebooks:

Bei den beiden von uns betrachteten Modellen (Cartpole und Bipedal Walker) handelt es sich um folgende Situation:
Es existieren Wesen in einer Umwelt.
Diese Wesen besitzen sowohl Gestalt, als auch bestimmtes Verhalten.
Je nach dem wie gut das Wesen in der Umwelt überlebt (und die festgelegten Bedingungen erfüllt um z.B. Belohnungen zu erhalten), so wird auch der numerische Score des Wesens festgelegt.

Für eine „algorithmische Evolution“ muss man die Eigenschaften der Wesen so Codieren, dass sie flexibel genug sind um sich interessant Anpassen zu können, jedoch nicht so flexibel, dass die Wesen völlig unsinniges Verhalten entwickeln.
Die „evolutionären Algorithmen“ hingegen sehen anstatt Wesen ein bestimmtes Optimierungsproblem. Sie haben die Paramter, welche das Verhalten beschreiben und die Codierung der Umwelt gegeben.

Wir greifen in beiden Modellen auf einen evolutionären Algorithmus zurück.
Bedeutet: Wir wollen die Lösung zu einem Optimierungsproblem.
Hierbei greifen wir auf Mutation und Selektion zurück.

Erstes Modell: Cartpole

Das Modell Cartpole verwendet das Paket openAI-gym im ipython-Notebook.
Dieses wird verwendet um einen Wagen zu Simulieren, auf dem sich ein senkrecht gestellter Balken befindet.
Dieser Balken ist drehbar, bzw. er kann zu den Seiten kippen –> umfallen.
Der Zustand des Balkens wird durch vier Zahlen beschrieben.
Hinter diesen Zahlen verstecken sich die Informationen zu: Ort, Geschwindigkeit, Winkel des Balkens und Winkelgeschwindigkeit des Balkens. Zu jedem betrachteten Zeitpunkt gibt es genau zwei Handlungsmöglichkeiten.
Entweder man lässt eine kleine Kraft nach links oder nach rechts auf den Wagen wirken.

Ziel ist es also den Balken auf dem Wagen so auszubalancieren, dass er sich nicht mehr als 12 Grad zu einer Seite neigt und sich der Wagen nicht zu weit nach rechts oder links in der Ebene bewegt.

Um dieses Ziel zu erfüllen muss das System eine Handlungsfunktion (Policy) erlernen, die in jedem Zustand eine Handlung empfiehlt. Diese Handlungsfunktion muss möglichst viele Belohnungen sammeln um den Score des Wesens, hier: des Cartpoles zu erhöhen.

Die Handlungsfunktion wird so modelliert, dass die möglicherweise eintretenden Ereignisse (hier: der Zustand des Balkens, beschrieben mit 4 Zahlen) jeweils eine Zufallskomponente enthalten, welche diese 4 Zahlen mehr oder weniger beeinflussen können.
Man sollte Anfangs also eine ausreichend Große Population wählen, damit einige der Wesen mit der Zufallskomponente im Bereich des Optimums sind.
Indem in der Population immer die Besten jeder Generation herauspickt werden und diese dann mutieren, kommt das Optimum immer näher.

Erste Aufgabe: Cartpole

1.
Im ipython-Notebook ist die Funktionsfamilie durch ein sogenanntes künstliches neuronales Netz mit einem hidden layer mit h Knoten gegeben.
Ein neuronales Netz mit einer genutzen hidden layer Funktion kann jede stetige Funktion auf einer kompakten Menge beliebig genau näherungsweise bestimmen, wenn die Zahl der verborgenen Knoten groß genug ist.

a)
Ersetzen Sie die Funktion make_model durch eine Funktion make_model_2, die ein Netz ohne verborgene Knoten erzeugen soll.
Dieses Modell ist auch als logistische Regression bekannt. Es besteht nur aus der Verknüpfung von sigma mit einer linearen Funktion.
Probieren Sie aus ob dieses Modell ausreicht um den Cartpole zu steuern.
Dokumentieren Sie außerdem wie schnell dieses Modell im Vergleich zum anderen lernt.

Lösung:

Zusätzlich fügen wir unter make_model, make_model_2 ein:

 
def make_model_2(ein=4, hidden=1, aus=1):
    
    model = SequentialModel()
    model.add_layer(DenseLayer(ein, hidden))
    model.add_layer(SigmaActivation())
    return model

Als nächstes Vergleichen wir beide Funktionen:

Merkmale make_model make_model_2
200er-Counter
Mittelwert
Varianz
Standardabweichung
Maximum
Minimum

Im direkten Vergleich erkennt man, dass make_model_2 durchaus funktioniert und somit ausreicht um das Cartpole zu steuern.
Zu erkennen ist jedoch auch, dass es nicht ganz so schnell lernt wie die make_model Funktion.

b)

Lassen Sie beide Modelle mit unterschiedlich starker Mutation lernen. Probieren Sie verschiedene Werte von sigma aus und dokumentieren Sie wie schnell das Modell jeweils lernt.
Probieren Sie ebenfalls aus was passiert, wenn der Mutationsparameter von Generation zu Generation kleiner wird.

Lösung:

Wir Vergleichen beide Modelle mit sigma = 0.5:

Merkmale make_model make_model_2
200er-Counter
Mittelwert
Varianz
Standardabweichung
Maximum
Minimum

Erstaunlicher Weise scheint das sehr hohe sigma für die Einfache Funktion des make_model_2 besser zu funktionieren. Ein weiteres Beispiel mit sigma = 0.01 findet sich in den jweiligen DokuStats der ipython-Notebooks.

Wir Vergleichen beide Modelle mit sigma = 1/(i+10):

Merkmale make_model make_model_2
200er-Counter
Mittelwert
Varianz
Standardabweichung
Maximum
Minimum

Wir erkennen, dass die Abweichungen innerhalb der jeweiligen Modelle sehr stark ausgeprägt sind.
Die Idee besteht sehr stark darauf, am Anfang den Parameterraum weit zu durchforschen,
sollte dabei jedoch die ganze Population entgegen des Optimums laufen, so ist es in späteren Generationen nichtmehr möglich stark dagegen zu wirken, da die Mutation mit dem sigma klein gehalten wird.

c)

Ändern Sie ebenfalls den Parameter k. Er bestimmt wieviele Wesen einer Generation auf die nächste übergehen und mutiert werden.

Lösung:

Wir vergleichen beide Funktionen mit k = 50 (sigma = 0.1):

Merkmale make_model make_model_2
200er-Counter
Mittelwert
Varianz
Standardabweichung
Maximum
Minimum

Hier scheint die Funktion der make_model besser mit den 50 Wesen umgehen zu können, welche pro Generation weiter mutiert werden. Make_model_2 hingegen funktioniert deutlich schlechter.
Ein weiteres Beispiel mit k = 5 findet sich in den jeweiligen DokuStats der ipython-Notebooks.

d)

Lassen Sie für eines der Modelle und feste Parameterwerte das Modell 20 Mal lernen, den Pfahl zu stabilisieren.
Alle 20 Durchläufe sind hier gemittelt

Lösung:

Wir betrachten make_model mit k = 3, sigma = 0.1

Merkmale make_model
200er-Counter
Mittelwert
Varianz
Standardabweichung
Maximum
Minimum
Mittelwert & Standardabweichung

Viele Durchläufe zu mitteln schafft ein klareres Bild darüber, wie gut der Algorithmus tatsächlich ist.
Wichtig ist hier besonders die generelle Standardabweichung vom Mittelwert.
Je geringer die Abweichung, desto zuverlässiger ist auch, dass er Algorithmus in allen Durchläufen ca. ähnlich funktioniert.

Zweites Modell: Bipedal Walker

Bei diesem Modell arbeiten wir mit der openAI-gym „BipedalWalker-v2/.“.
Hierfür müssen wir das Paket box2d installieren. –> Bei mir hat das auf einem Windows 64-Bit System per „pip install box2d“ nicht funktioniert –> daher werde ich das win64 Paket auch in die .zip packen. Genaueres ist in der readMe.txt zu finden.

Das Modell des Bipedal Walker besitzt einen 24-dimensionalen Zustandsraum.
Dieser beschreibt die möglichen Stellungen der Gelenke und Körperteile.
Im Handlungsraum haben wir nun 4 mögliche Handlungen statt eine.
Diese beeinflussen die Drehmomente an Knien und Hüfen des Walkers.

Zweite Aufgabe: Bipedal Walker

Versuchen Sie sich daran den zweibeinigen Gang evolutionär zu lernen und wählen sie ein geeignetes Modell, Mutationsparameter etc. .

Lösung:

Zunächst benötigen wir ein neues Modell:

def make_model_3(ein=24, hidden=16, aus=4): #hidden = beliebig viele layer

    model = SequentialModel()
    model.add_layer(DenseLayer(ein, hidden))
    model.add_layer(ReLUActivation())
    model.add_layer(DenseLayer(hidden, aus))
    model.add_layer(TanhActivation())
    return model

Als erstes habe ich mir den Simulierten Ablauf des Walkers angesehen und Referenzwerte erfasst.
Die Bewertung des Walkers geschieht hier durch einen reward. Je besser der Walker die Schritte tätigt und dabei vorwärts kommt, desto höher wird der reward.
Wenn der Walker fällt ist er gescheitert und sein Durchlauf beendet.

In der Grafik erkennt man, dass der zu erreichende Wert gegen 300 reward-Punkte streben sollte.

Jetzt können wir das iphython-Notebook beliebig bearbeiten. Es wird sich auch in der .zip befinden.

Mein erster Versuch: sigma = 0.1, k = 3, population = 100, Durchläufe = 3, Generationen = 100, hidden = 10

Auswertung:

Der erste Versuch war wie zu erwarten nicht der beste.
Der Mittelwert ging nicht über -30 hinaus und der maximal erreichte Wert ging zum Ende der 100 Generationen gerade einmal auf 30 zu.

Mein zweiter Versuch: sigma = 0.07, keep_best = 18, population = 200, Durchläufe = je 3, Generationen = 100, hidden = 16

Diesmal lag der Mittelwert zwar wieder nur im negativen Bereich, jedoch ist das Maximum deutlich angestiegen. Die Maximalen Werte erreichten zumindest zum Ende höhen Richtung 100 reward.
Da der Algorithmus vielversprechend aussah, habe ich zusätzlich noch einen zweiten Durchlauf gestartet.

Mein dritter Versuch: sigma = 0.3, keep_best = 26, population = 160, Durchläufe = 3, Generationen = 100, hidden = 18

Auch bei diesem Versuch erreichten die Werte bis zum Ende nur negative Mittelwerte. Das Maximum ist immerhin bis 80 angestiegen.
Im Vergleich zum oberen Algorithmus schneidet dieser jedoch schlechter ab.

Mein vierter versuch: sigma = 0.09, keep_best = 15, population = 200, Durchläufe = 3, Generationen = 100, hidden = 12

Der Mittelwert lag hier wieder im negativen Bereich, jedoch so schlecht wie bei meinem ersten Versuch.
Auch das Maximum erreichte nur schlechte Werte. in 100 Generationen ging der reward nicht über 40.
Dieser Algorithmus ist daher wie der Erste nicht zu gebrauchen.

Mein fünfter Versuch: sigma = 1/(i+10), keep_best = 20, population = 200, Durchläufe = 3, Generationen = 100, hidden = 16

Diesen Versuch habe ich auf Stefans Ratschlag hin ausprobiert. Interessant ist, dass der Algorithmus bei mir hier nicht vielversprechend aussieht, da das Maximum gerade mal auf 8 reward steigt.
Stefan meinte ,dass es bei ihm funktionierte, daher werde ich noch mehr Versuche machen.

Mein sechster Versuch: sigma = 1/(i+10), keep_best = 20, population = 200, Durchläufe = 1, Generationen = 1000, hidden = 16

Bei diesem Versuch habe ich den vorherigen einfach nur um seine Generationen erweitert. Interessant zu beobachten ist, dass der Mittelwert sich der 0 nähert, aber die Maxima immernoch bei 9 stagnieren. Das bedeutet im Umkehrschluss, dass nicht die Maxima höher werden, sondern die Minima ansteigen.

Mein siebter Versuch: sigma = 0.07, keep_best = 18, population = 200, Durchläufe = 3, Generationen = 1000, hidden = 16

Hier greife ich nochmal auf meinen zweiten Versuch zurück und erweitere wieder die Generationsanzahl.
Wieder gab es sehr vielversprechende Ergebnisse. Zwar komme ich nicht annähernd an die 300 reward, jedoch haben meine Walker die Hälfte davon erreichen können.
Leider stagniert sich dieser Wert jedoch auch über die Generationen und mag nicht so recht weiter ansteigen.

Mein achter Versuch: sigma = 1/(i+10), keep_best = 20, population = 200, Durchläufe = 1, Generationen = 10000, hidden = 16

Da mein Computer nach einem Tag Laufzeit den Algorithmus leider nichtmehr weitergeführt hat, sondern einfach abgebrochen hat, habe ich leider keine Aufzeichnungen davon.
Zu sagen ist jedenfalls, dass der Algorithmus einen reward bis 100 erreicht hat und danach auf dem Wert stagnierte.

Mein neunter Versuch: sigma = 0.07, keep_best = 18, population = 200, Durchläufe = 1, Generationen = 10000, hidden = 16

Auch hier hat mein Computer nach einem Tag Laufzeit den Algorithmus leider nichtmehr weitergeführt, sondern ihn einfach abgebrochen, daher habe ich leider keine Aufzeichnungen davon. Dieses Modell ist in der Laufzeit zu einem reward von ca 190-200 gekommen und sicherlich noch ausbaufähig.
Vermutlich könnte man hier an den Voreinstellungen herumschrauben und somit ein besseres Ergebnis erzielen.

(–> draufklicken zum Abspielen)

.zip mit allen Informationen

ss19/exkurs_genetische_algorithmen.txt · Zuletzt geändert: 2019/08/11 15:58 von feuerhahn