Posts Tagged‘Python’

Simple 3D Collision Detection with Python Scripting in Blender

by Paul Balzer on 8. Juni 2016

No Comments

If you are looking for a very simple way to check, if two objects touch each other in Blender, maybe this might be a solution. The field of collision detection is very popular in game development and these guys have a lot of special algorithms for fast and/or exact collision between circles & circles, rectangles & circles, triangles & circles and so on…

Most of these are based on the Seperating Axis Theorem, which is simply the mathematical solution of the question: Is it possible to look ‚between‘ the two objects from any direction? If so, they are not colliding. Things get much simpler, if you just check the bounding boxes of two objects. In case of a cube, the bounding box is exactly the object itself. To check if two cubes touch each other, you have to check a collision between two bounding boxes. To make it even easier, one of the boxes is axis aligned (not rotated). We are talking about AABB (axis aligned bounding box) 3D collision check in Python. For visualization, we are using Blender. In Blender, you can run Python scripts.

Continue Reading

[Tutorial] Neuronale Netze einfach erklärt

by Paul Balzer on 19. März 2016

7 Comments

Es fehlt eindeutig an deutschsprachigen Beginner-Tutorials zum Thema Neuronale Netze. Es gibt ausgesprochen gute – ich meine wirklich herausragend gut! – Tutorials zum Thema, welche man diesem hier unbedingt vorziehen sollte. Bitteschön:

Doch was soll ich sagen, diese Tutorials sind umfangreich und gleich die große Kanone. Wenn man nur Spatzen haben möchte, dann hilft es vielleicht, ein einfaches Tutorial zum Einstieg zu nutzen, in dem großzügig auf Ausnahmen, Feinheiten und Randbedingungen verzichtet wird. Das versuche ich mit dem folgenden Beitrag.

Prolog

Neuronale Netze ([engl.] Neural Networks) sind schon ziemlich alt und in der Wissenschaft schon lange Thema. Seit einigen Jahren erleben sie in praktischen (medienwirksamen und leicht verständlichen) Anwendungsfällen allerdings eine unglaubliche Renissance. Ein wichtiger Grundstein war sicherlich, dass NVIDIA Ende der 2000er Jahre mit ihren CUDA Grafikkarten eine unglaubliche Rechenpower zur Verfügung stellte. Warum? Neuronale Netzwerke lernen im Grunde mit simplen Multiplikationen bzw. Faltungen, welche sich prima parallel abarbeiten lassen. Hat man mehr Prozessorkerne, hat man in überschaubarer Zeit bessere Lernkurven. Eine Quad-Core CPU stellt dabei keine relevante Anzahl Kerne dar. Das wäre, wie mit einem 50ccm Roller zu einem DTM Rennen zu kommen.

Keine Chance also, auf dem heimischen Laptop ein auch nur ansatzweise konkurrenzfähiges Neuronales Netzwerk in überschaubarer Zeit (heißt: Wochen/Monate) zu trainieren!

Was können die überhaupt so?

Am beeindruckendsten finde ich, sind derzeit folgende Neuronalen Netze (welche noch kombiniert mit so genannten Reinforcement Learning Algorithmen funktionieren und die Q-Values lernen):

Not bad, right? Steigen wir ein.

Begriffe

Deep Learning Wordcloud, made with https://www.jasondavies.com/wordcloud/ with wordbase from http://cs231n.github.io CC-BY-SA2.0 Lizenz

Deep Learning Wordcloud, made with https://www.jasondavies.com/wordcloud/ with words based on http://cs231n.github.io
CC-BY-SA2.0 Lizenz

Alle Begrifflichkeiten zu erläutern würde zu weit führen, aber die Wichtigsten im Überblick:

Neuron

Spricht man über ein Neuronales Netz, so ist natürlich die Frage, was ein Neuron ist. Angelehnt an die Biologie ist ein Neuron ein ‚Ding‘, welches auf einen Reiz mehr oder weniger reagiert, d.h. diesen Reiz ‚durch lässt‘. Je nachdem wie stark es aktiviert ist, lässt es mehr oder weniger Reiz durch.

Schematische Darstellung eines Neurons aus der Biologie (links) und mathematische Darstellung für Neuronale Netze in der Computerwelt (rechts) Source: http://cs231n.github.io/neural-networks-1/

Schematische Darstellung eines Neurons aus der Biologie (links) und mathematische Darstellung für Neuronale Netze in der Computerwelt (rechts)
Source: http://cs231n.github.io/neural-networks-1/

Dabei werden Eingangswerte \(x_0, x_1, x_2, …\) mit Gewichten \(w_0, w_1, w_2, …\) multipliziert, alle Produkte summiert, noch ein Offset \(b\) hinzu addiert und alles geht als Eingang in die Aktivierungsfunktion \(f\). Resultat ist der Ausgang des Neurons, die Aktivierung. Diese kann auch wieder Mehrdimensional sein, denn wenn danach noch ein Layer folgt, so benötigt man ja für die nächste Ebene wieder Eingänge.

Neuronales_Netz_Layer

Aktivierungsfunktion / Activation Function

Spricht man nun davon, dass ein Neuron ‚aktiviert‘ wird (d.h. das Netzwerk lernt), so muss man eine mathematische Funktion \(f\) hinterlegen, die diese Aktivierung modelliert. Typisch und oft genutzt ist die Sigmoid Funktion oder auch der Tangens Hyperbolicus. Großer Beliebtheit erfreut sich die ReLu (Rectifier Linear Unit) Funktion, welche eine simple \(f(x)=max(0, x)\) Funktion ist. Alle 3 sind nachfolgend dargestellt. Alle 3 sind nichtlinear, was deren Sinn ist.

Typische Aktivierungsfunktionen: Sigmoid Funktion, Tangens Hyperbolicus und ReLu Funktion

Typische Aktivierungsfunktionen: Sigmoid Funktion, Tangens Hyperbolicus und ReLu Funktion

Sie geben für einen Input (in der Abbildung beispielhaft -6…+6) je nach Aktivierung einen Output. Der funktionelle Zusammenhang ist nichtlinear. Je nachdem wie stark das Neuron aktiviert ist, gibt es ein Signal unterschiedlich stark weiter. Zu Beginn des Lernprozesses, muss jedes Neuron initialisiert werden.

Initialisierung

Wie man an den Aktivierungsfunktionen sehen kann, ist es von elementarer Bedeutung, ob ein Neuron mit 0 oder -1 oder +1 aktiviert ist. Je nach Aktivierungsfunktion lässt es ein Signal gar nicht oder teilweise oder stark durch. Zu Beginn weiß das Neuronale Netz noch gar nichts, man muss es aber initialisieren. Wenn man ein Netzwerk mit 100 Neuronen hat, sollte man 100 verschiedene Aktivierungen initialisieren.

Die Initialisierung kann im einfachsten Fall gleichverteilt erfolgen. Aber auch normalverteilt oder mit etwas ausgeklügelterer Logik. Auf keinen Fall jedoch alle mit exakt der gleichen Zahl (z.B. 0,0). Das würde dazu führen, dass jedes Neuron exakt gleich ist und beim Lernen ergäbe sich durch die Mathematik hinter dem Lernprozess, dass Fehler bzw. Korrekturen auf jedes Neuron gleich angewendet werden. Das Neuronale Netzwerk würde so nicht schlauer werden, denn es hätte ja dann nur 100 identisch dumme Neuronen.

Zielfunktion / Loss / Objective Function

Das Wichtigste am Lernen ist, dass man weiß, wann etwas richtig oder falsch war. Möchte man z.B. etwas vom Neuronalen Netz klassifziert haben (Ziffern, Buchstaben, Tiere, …), so gibt es nur ein richtig oder falsch. Eine Zielfunktion für ein Klassifizierungsproblem würde im einfachsten Fall nur die korrekt erkannten Dinge zählen. Umso mehr korrekt erkannt wurde, umso besser gelernt. Mit etwas mehr drüber nachdenken kommt man auf die Idee Softmax als Zielfunktion zu nehmen.

Es gibt aber auch Anwendungsfälle, da soll das Neuronale Netzwerk einen Wert schätzen und keine Klasse. Diese Anwendungsfälle nennt man Regressionsprobleme. Dafür ist eine andere Zielfunktion notwendig. Im einfachsten Fall berechnet man, wieviel das Netzwerk und die korrekte Funktion auseinander liegen. Diese Zielfunktionen werden L1 oder L2 Norm genannt, wobei bei letzterer der Fehler quadriert wird. In einigen Anwendungsfällen empfiehlt sich auch die Cross-Entropy als Loss Function.

Eine Zielfunktion kann aber z.B. auch ein Punktestand in einem Spiel (umso mehr, umso besser), die Anzahl an geschlagenen Figuren (umso mehr, umso besser), die erreichte Distanz (umso weiter, umso besser) oder die Entfernung zu einem Hindernis (umso dichter/weiter, umso besser). Je nach Anwendungsfall, welches das Netzwerk lösen soll.

Lernen

Kommen wir nun zum elementaren und kompliziertesten Teil: Das Lernen! Nicht nur bei Kindern ist das kompliziert, auch bei Neuronalen Netzen muss man da clever sein, um ihnen etwas beizubringen. Die Neuronen sind im ersten Schritt ja initialisiert mit zufälligen Aktivierungen. Das Netzwerk berechnet die Ausgabegröße und wird von der Zielfunktion (Loss) gnadenlos bestraft. Der Fehler den es gemacht hat, wird über so genannte Backpropagation auf die jeweiligen Neuronen zurück verteilt, die ihn verursacht haben.

Nun könnte man auf die Idee kommen, dass man die verschiedenen Neuronen einfach nach und nach einzeln durch geht und mit verschiedenen Aktivierungen (z.B. -6…6) probiert (Bruteforce), bis das Netzwerk die beste Zielfunktion ausgibt. Glückwunsch, so viel Rechenpower hat selbst Google nicht, das für halbwegs reale Anwendungsfälle durch zu spielen.

Eine etwas bessere Idee ist, zu schauen, ob der Fehler größer oder kleiner wird, wenn man die Aktivierung erhöht. Mathematisch gesehen wird die Steigung der Fehlerfunktion bestimmt. Idealer Weise gibt es eine Richtung in die man optimieren kann, sodass die Fehlerfunktion minimiert wird.

Fehlerminimierung

Diese Suche nach der idealen Aktivierung bedeutet mathematisch das Finden von Minimalwerten im Fehlerraum. Gibt es nur zwei Parameter, so kann man eine Fehlerfunktion wunderschön visualisieren. Dabei können verschiedene mathematische Suchen implementiert werden. Der Klassiker ist sicherlich die Stochastic Gradient Descent (SGD) Methode, welche numerisch einen Anstieg der Funktion bestimmt und in die abfallende Richtung optimiert. Es gibt andere Verfahren wie Nesterov Momentum, Adagrad und Adadelta oder Rmsprop. Alle haben Vor- und Nachteile sowie Parameter, welche einzustellen sind.

Animation credit: Alec Radford.

Animation credit: Alec Radford.

Backpropagation

Der Fehler \(e\), den das Netzwerk bei einer Schätzung des Ausgangswertes macht, wird zurück an das Netzwerk gegeben. Dabei wird dieser anteilig auf das Neuron verteilt, welches maßgeblich am Fehler \(e\) beteiligt war. Das mathematische Verfahren ist die Backpropagation. Man kann es sich bildlich so vorstellen:

Fehler Backpropagation, Animation by WelchLabs

Fehler Backpropagation, orange=Input Layer, grau=Hidden Layer,  grün=Output Layer, Animation by WelchLabs

Das funktioniert auch, wenn man mehr als einen Layer hat.

Layer – ab wann wird es Deep?

Ein Neuronales Netzwerk besteht aus mehreren Neuronen. Dabei gibt es verschiedene Architekturen. Es gibt aber immer einen Input- und ein Output-Layer (im GIF oberhalb orange und grün). Bei der Bezeichnung des Netzwerkes wird der Input Layer nicht mit gezählt.

Ein 3-Layer Neuronales Netzwerk hat

  • Input Layer
  • Hidden Layer
  • Hidden Layer
  • Output Layer

Quelle: http://neuralnetworksanddeeplearning.com/chap1.html, by Michael Nielsen

usw. Die Layer sind nacheinander (Sequentiell) angeordnet und verbunden. Ab einer gewissen Anzahl an Layern (10…20) spricht man von Deep Neural Networks.

Wenn jedes Neuron mit jedem Neuron des nächsten Layers verbunden ist, dann spricht man von ‚Fully Connected Layer‘ (auch ‚Dense-Layer‘). Es gibt dann so viele Gewichte \(w\), wie es Verbindungen gibt.

Soll das Netzwerk irgendwelche Informationen aus Bildern (oder Videospielen, YouTube Videos, Kamera, …) lernen, werden zur Extraktion von Features Layer eingesetzt, welche eine Faltungsoperation ausführen. Faltung (oder Englisch: Convolution, die Netzwerke heißen dann Convolutional Neuronal Network oder kurz ConvNets), ist eine relativ simple Funktion, welche in einem gleitenden Fenster das Produkt von zwei Funktionen berechnet. Es zeigt sich aber, dass dieses Vorgehen so mächtig ist, dass ein Layer damit relevante Erkennungsmerkmale für viele reale Gegenstände aus dem Bild heraus arbeitet..

Gewichte

Nun kommen wir zum eigentlichen Teil. Ein Gewicht \(w\) ist eigentlich das Elementare in einem neuronalen Netzwerk, denn es sagt, wie stark ein Neuron mit einem anderen verbunden ist. Der Ausgangswert eines Neurons, multipliziert mit dem Gewicht \(w\) und addiertem Offset \(b\), ergibt den Eingangswert für die Aktivierungsfunktion des Neurons! Mathematisch beschrieben, sieht das so aus:

\[out=f\left(\sum_iw_ix_i + b\right)\]

Wobei \(w_i\)=Gewicht, \(x_i\)=Eingangswert (bzw. Ausgangswert des Neurons des vorhergehenden Layers), \(b\)=Offset des Layers und \(f\)=Aktivierungsfunktion (z.B. Sigmoid). Der Index \(i\) bezieht sich darauf, wieviel Verbindungen auf das Neuron kommen. Besteht der Layer aus 10 Neuronen, wäre \(i=10\). Der Offset \(b\) ist ohne Index, dieser ist pro Layer für jedes Neuron konstant.

Im Code liegt die Wahrheit, hier ist also welcher, Quelle: CS231n

# forward-pass of a 3-layer neural network:
f = lambda x: 1.0/(1.0 + np.exp(-x)) # activation function (use sigmoid)
x = np.random.randn(3, 1) # random input vector of three numbers (3x1)
h1 = f(np.dot(W1, x) + b1) # calculate first hidden layer activations (4x1)
h2 = f(np.dot(W2, h1) + b2) # calculate second hidden layer activations (4x1)
out = np.dot(W3, h2) + b3 # output neuron (1x1)

Im Code oberhalb sind die Variablen \(W1, W2, W3, b1, b2, b3\) das, was das Neuronale Netzwerk ‚lernen‘ muss (wobei die Dimension von \(W_i\) und \(b_i\) von der Dimension der Eingangsdaten abhängt). D.h. die Backpropagation muss den Fehler so auf die \(W_i\) und \(b\) verteilen, dass der Fehler zwischen \(out\) und dem korrekten Wert minimal wird.

Die `numpy dot` Funktion bedeutet elementweise Multiplikation von Matrix-Elementen, denn was in der Formel als Summe dargestellt ist, kann natürlich effizient als elementweise Matrixmultiplikation in einem Rutsch ausgeführt werden. Es ist keine zeitaufwendige Schleife für die Summe notwendig.

Ein Neural Network ist im Prinzip eine wiederholte Matrixmultiplikation mit eingearbeiteter Aktivierungsfunktion.

Nun haben wir alles beisammen, was man benötigt, um ein Neuronales Netzwerk aufzusetzen.

Einfaches Neuronales Netzwerk mit Python und Keras

Wie im ersten Teil erwähnt, bringt es nichts auf dem heimischen Laptop ein Netzwerk aufzusetzen, was Super Mario spielen lernt. Es ist prinzipiell möglich, doch die Lernzeit ist so lang, dass bis zum Erreichen eines respektablen Erfolges viele Sommer vergehen werden.

Wir nehmen ein sehr einfaches Beispiel.

Eine beliebige Funktion approximieren mit einem Neuronalen Netzwerk

Ein Neuronales Netz ist per Definition ein universeller Approximator. Das bedeutet, dass es bereits mit einem Hidden Layer prinzipiell (und mit gewissem Fehler) jede Funktion nachahmen kann. Voraussetzung ist, dass es genügend Neuronen in dem Layer gibt und diese eine nichtlineare Aktivierungsfunktion haben.

Wir könnten den Code prinzipiell selbst in Python aufsetzen [siehe z.B. hier], doch das ist uneffizient und nicht sehr clever.

Besser ist es, eine Bibliothek zu verwenden, die das perfekt macht. Da kann man endlos durch probieren: What is the best deep learning library at the current stage for working on large data?

Theano, Lasagne, TensorFlow, Keras – Welche Bibliothek sollte ich nutzen?

Das Feld der Neuronalen Netze ist so populär, dass ca. täglich neue Bibliotheken und Wrapper für C++, Lua, Python oder Java auf Github erscheinen, welche mehr oder weniger Beta sind und mehr oder weniger Dokumentation besitzen. Auch die Big Player wie facebook oder Google veröffentlichen ihre Bibliotheken. Wer die Wahl hat, hat die Qual.

Als Anfänger sollte man darauf achten, dass man nicht erst 2 Wochen mit dem Setup für GPU und AWS Cloud zubringt, bevor man überhaupt das 1. mal anfängt rumzuspielen. Daher empfehle ich: Python > Theano > Keras!

Neural_Net_Python_Theona_Keras

HowTo: Funktion approximieren mit Neuronalem Netz in Python

Man kann natürlich gleich mit realen Fragestellungen beginnen, doch da lässt sich schwerlich verstehen, worum es im Kern geht. Daher als Beispiel eine gaaaaaanz einfache Sache: Es gibt eine Funktion \(f(x)\), welche dem Netzwerk nicht bekannt ist. Es soll ein neuronales Netzwerk \(g(x)\) aufgesetzt und angelernt werden, was diese Funktion approximiert.

Michael Nielsen hat dazu eine schöne Spielwiese programmiert: A visual proof that neural nets can compute any function.

Wie bekommen wir das nun mit Python, Theano und Keras aufgesetzt?

# Import Keras and Numpy Stuff we need
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.optimizers import Adadelta
import numpy as np

f = lambda x: 0.2+0.4*x**2+0.3*x*np.sin(15*x)+0.05*np.cos(50*x)
x = np.linspace(0, 1, 101)
y = f(x)
Funktion f(x), welche das Neuronale Netz lernen soll zu approximieren

Funktion f(x), welche das Neuronale Netz lernen soll zu approximieren

Der Eingangsvektor \(x\) (kann auch eine Matrix sein, z.B. wenn mit mehreren Trainingsdaten gleichzeitig gelernt werden soll) des Neuronalen Netzwerkes besteht nun einfach aus 100 Zahlen zwischen 0…1. Der Vektor hat die Dimensionen [1, 100]:

\[x=\left[0, 0.01, 0.02, …, 1.0\right]\]

Damit die schöne Matrixstruktur und einfachen Multiplikationen funktionieren, wird der Vektor auf die Dimension [100, 1] umgestellt (also 100 lang, nicht breit). Pro Spalte in \(x\) sollte ein Trainingsdatensatz, pro Zeile ein Wert des Trainingsdatensatzes sein. Da wir nur einen Trainingsdatensatz mit 100 Werten haben, hat unser \(x\) die Form [100, 1].

X = x.reshape((-1, 1))
print(np.shape(X)) # (100, 1)
print(np.shape(y)) # (100, )

Jetzt bauen wir das Neuronale Netzwerk mit Keras auf.

model = Sequential() # Sequentielles Netz, d.h. Layer nach Layer...

model.add(Dense(input_dim=1, output_dim=300, init="uniform"))
model.add(Activation("relu"))
model.add(Dense(output_dim=1, init="uniform"))

Was haben wir jetzt aufgesetzt? Ein Dense Layer ist ein Fully Connected Layer, d.h. jedes Neuron soll mit jedem des nächsten verbunden werden. Input hat die Dimension 1. Unser Inputvektor \(x\) hat die Form [100, 1]. Wie bereits beschrieben, bedeutet die Länge 100, dass wir 100 Werte haben, welche aber die Dimension 1 haben. Die Output Dimension wurde mit 300 initialisiert, das bedeutet, dass das Netzwerk 300 Neuronen bekommt im 1. Layer. Die Initialisierung soll ‚uniform‘, d.h. gleichverteilt erfolgen.

Als Aktivierungsfunktion wird die ReLu Funktion hinzugefügt.

Anschließend, als Output-Layer wieder ein Fully-Connected Layer mit einer Output Dimension, d.h. das Netzwerk soll keine Klassifizierung o.ä. machen, sondern eine reale Zahl ausgeben. Diese müssen wir nun irgendwie mit dem Sollwert, d.h. der Funktion \(f(x)\) vergleichen und dem Netzwerk eine Loss-Funktion mitteilen.

model.compile(loss='mean_squared_error', optimizer=Adadelta())

In Keras wird das aufgesetzte Modell mit Loss Funktion (in dem Fall der mittlere quadratische Fehler oder auch L2 Norm genannt) und Optimizer (in dem Fall Adadelta) gleich kompiliert, d.h. wenn möglich als optimierter GPU Code im Hintergrund erzeugt.

Künstliches Neuronales Netz lernen lassen

Nun ist alles aufgesetzt und in Code gegossen. Nun kann man es lernen lassen.

model.fit(X, y, batch_size=15, nb_epoch=10000)

Das Lernen erfolgt mit jeweils 15 der 100 Werte aus dem Eingangsvektor \(x\). Die Fehlerfunktion wird 10.000x die gemachten mittleren quadratischen Fehler via Backpropagation auf die Gewichte \(w\) und \(b\) zurück verteilen. Je nach Initialisierung und Loss Funktion und Aktivierungsfunktion und gewählter Hyperparameter, lernt das Netzwerk schneller oder langsamer.

Hier kann man für einfachere Funktionen beim Lernen zusehen.

Die Loss Funktion sieht beispielsweise so aus (logarithmische y-Achse).

Loss

Nach 10.000 Lernvorgängen (auf einem MBP 2.9GHz, Intel Core i5 dauert das knapp 1 Minute), hat das Netzwerk die Funktion \(g(x)\) gefunden, welche \(f(x)\) approximiert.

g=model.predict(X)

f_x_g_x

Gar nicht schlecht für 1 Minute lernen mit einem Layer mit 300 Neuronen, oder? Allerdings nicht perfekt. Vor allem der erste Teil der Funktion ist relativ schlecht approximiert. Da könnte man nun anfangen zu optimieren. Ist die Schrittweite zu groß, die Loss Funktion die richtige, die Lerndauer zu kurz, …

Bei einer Lerndauer von nur 1 Minute kann man viel rum probieren und mal schnell wieder neu anlernen. Bei einem sehr komplexen Netzwerk, mit 10 Layern und mehreren Millionen Neuronen, dauert das Lernen, selbst in Rechenzentren, einige Tage. Da ist ein gewisses KnowHow notwendig, um in die richtige Richtung zu optimieren.

Fazit

Artificial Neural Networks sind aus der modernen Machine Learning Welt nicht mehr weg zu denken. Von der Sortierung der facebook Timeline, Siris Spracherkennung oder auch Fahrspur- und Kollisionserkennung in kamerabasierten Fahrerassistenzsystemen – überall helfen sie uns im Alltag.

Die kommende Superintelligenz?

Sofern man eine Zielfunktion aufstellen kann, ist das Lernen parallel und relativ schnell (weil der Rechner schnell prüfen kann ob es stimmt und wie groß der Fehler war) möglich. In eng eingegrenzten Szenarien (z.B. Go spielen, Atari spiele spielen, …) können sie menschliche Fähigkeiten durchaus nachahmen oder sogar besser werden als der beste Mensch in der Disziplin.

Doch ein Neuronales Netz, was Atari spielt, kann keine Sprache verstehen. Es sind keine universellen Profis. Allerdings sind die derzeit bestehenden Netzwerke auch noch wesentlich kleiner als das menschliche Gehirn. Die Biochemie im menschlichen Gehirn ist auch wesentlich komplexer als eine einfache ReLu oder Sigmoid Funktion mit ein paar Gewichten. Dennoch: Es gibt nicht wenige Gelehrte dieser Tage, die die Gefahr kommen sehen.

Ein schöner Beitrag dazu: The AI Revolution.

Künstliche Intelligenz: Gefahr für die Menschheit?

Haben wir damals in Science Fiction Filmen (Minority Report) noch über die Vorhersage von Verbrechen geschmunzelt, so ist es heute Realität.

Haben wir damals in Science Fiction Filmen (Terminator) noch über Skynet gelacht, einem Neuronalen Netz, was alle Informationen sammelt, so haben Firmen wie Google, facebook oder Geheimdienste wohl im Ansatz vergleichbare Architekturen aufgebaut.

Wann wird also der Moment gekommen sein, in dem die SciFi Vision beginnt und eine allumfassendes KI auf die Idee kommt, sich selbst zu trainieren und eigene Zielfunktionen aufzustellen? Eventuell sogar mit einem End-to-End trainierten Neuronalen Netz, welches auch gleich die Stellsignale für Elektromotoren mit lernt und physisch in Erscheinung tritt?

Ein interessantes Interview zum Thema: Jürgen Schmidhuber – Intelligente Roboter werden vom Leben fasziniert sein.

Bald werden eben die klügsten Bestandteile der Zivilisation nicht mehr die Menschen sein. – Jürgen Schmidhuber

TimeSeries Decomposition in Python with statsmodels and Pandas

by Paul Balzer on 3. Januar 2016

1 Comment

A lot of data is recorded in time domain, which means you will have a datapoint in the form of

timestamp: value

A useful approach to get insights into the data is, to decompose the timeseries. That usually means, you seperate your data into

  • seasonal
  • trend
  • residual

This famous library from R (`decompose`) is available in Python via statsmodel since version 0.6. Yeah! Let’s take a look into it with the parking lot data of city of Dresden.

Continue Reading

Alpha-Beta-Filter – der kleine Bruder vom Kalman Filter

by Paul Balzer on 22. Dezember 2015

4 Comments

Mit Abstand am häufigsten gelesen hier im Blog, sind die Beiträge zum Kalman Filter (Teil 1 & Teil 2 & EKF). In den Kommentaren und Emails, die ich dazu bekomme, zeigt sich allerdings, dass da mit Kanonen auf Spatzen geschossen wird. Einige Probleme, die der Algorithmus lösen soll, sind gar nicht so kompliziert, dass man einen Kalman Filter oder Extended Kalman Filter aufsetzen muss.

Ich möchte in diesem Beitrag den kleinen Bruder vom Kalman Filter, den Alpha-Beta-Filter, vorstellen. Dieser ist zwar im Grunde ein Kalman-Filter, allerdings mit einigen Vereinfachungen, sodass er leichter zu implementieren ist.

Continue Reading

Loading Video...

[Tutorial] Rotationsmatrix und Quaternion einfach erklärt in DIN70000 ZYX Konvention

by Paul Balzer on 8. Juli 2014

8 Comments

Play Video Hide Video

Die Rotation eines Körpers im Raum ist ein Thema, welches einen Ingenieur in vielen Einsatzbereichen tangiert. Es gibt auch schon unzählige Webseiten dazu und auch die Wikipedia lässt sich zum Thema Drehmatrix oder Eulersche-Winkel ausführlich aus.

Doch so richtig gepasst hat bisher keine Beschreibung. Deshalb an dieser Stelle noch einmal eine ausführliche und einfache Beschreibung der 3D Rotation eines Körpers/Vektors mit Euler-Winkeln nach ZYX-Konvention im DIN70000 Koordinatensystem des Fahrzeugs.
Continue Reading

Die FFT mit Python einfach erklärt

by Paul Balzer on 29. April 2014

12 Comments

Dieser Beitrag wurde aus dem IPython Notebook konvertiert, ich bitte um etwas Nachsicht bezüglich der Formatierung.

Was macht der FFT Algorithmus?

CC-BY-SA2.0

CC-BY-SA2.0

Continue Reading

Loading Video...

Das Extended Kalman Filter ausführlich erklärt [Video]

by Paul Balzer on 3. März 2014

3 Comments

Play Video Hide Video

Da die Beiträge zum Kalman Filter (Teil1 und Teil2) sowie der Beitrag zum Extended Kalman Filter die am Häufigsten gelesenen des Motorblogs sind, habe ich zum Extended Kalman Filter noch mal einen etwas detaillierteren Screencast aufgezeichnet, welcher recht ausführlich erläutert, wie dieser aufgesetzt wird und arbeitet.

Extended Kalman Filter with CTRV Vehicle Model in Python from Paul Balzer on Vimeo.

Continue Reading

Perfektes Python Setup für MATLAB liebende Ingenieure

by Paul Balzer on 25. November 2013

1 Comment

Als Ingenieur ist man von der Informatik meilenweit entfernt. Im Studium wird man manchmal an Mathworks Matlab herangeführt, versteht es aber im Allgemeinen erstmal nicht. In Fleisch und Blut geht es ohnehin nie über, weil es nahezu unbeschränkte Möglichkeiten bietet, das Studium aber nur eine kurze Zeit dauert.

Während man die ersten Semester Diagramme und Protokolle lieber mit Excel erstellt, reduziert sich die Zeit, in welcher man sich mit Matlab beschäftigen kann, noch weiter. In den letzten Semestern, vielleicht erst in der Diplomarbeit, merkt man dann aber, dass es echt gut ist! Warum nicht eher?

Kommt man aus dem Uni-Umfeld heraus, wird es leider sehr teuer mit Matlab! Eine Standard Einzelplatz Lizenz ohne eine einzige Toolbox kostet 2.000€ Netto. Nur um ein paar Diagramme zu erstellen?

Ich habe mir daher vor einiger Zeit Python angesehen, welches nach einiger Zeit zunehmend Spaß macht! Da es zu Beginn relativ schwer war, einen Einstieg zu finden, möchte ich mein Setup mal vorstellen.

Python

Das Herz der Angelegenheit und bei Linux, Unix und MacOS schon von Haus aus an Board. Für Windows muss man es manuell nachinstallieren. Generell ist die einfachste Variante Anaconda zu installieren, weil dort so ziemlich alle Pakete (Plug-Ins) dabei sind, die wichtig werden für die tägliche Arbeit.

In der Kommandozeile oder im Terminal kann man nun Python nutzen.

python-console-mac

Plug-Ins

Python an sich ist nun schon mächtig, aber immernoch ein zahnloser Tiger, so lange es ohne Zusatzpakete auskommen muss. Zum installieren der Pakete kann man auf Paketmanager zurückgreifen, die die Arbeit in den meisten Fällen übernehmen. Hat man Anaconda installiert, sind die meisten Pakete schon dabei.

PIP Paketmanager

Der Paketmanager, welcher  nachfolgend die Arbeit der Installation/Upgrades übernimmt, ist PIP. Die Installation von PIP erfolgt betriebssystemabhängig. Am einfachsten mit der get-pip.py, welche dort herunter geladen werden kann. Da wir ja Python installiert haben, können wir einfach:

python get-pip.py

eingeben, dann müsste alles automatisch funktionieren. Da es nun für jedes Betriebssystem immer ein paar Unterschiede gibt, möchte ich aus diesem Beitrag kein Installationstutorial machen, sondern einfach nur zeigen, was meiner Meinung nach am besten geeignet ist, ohne Support.

Scipy

Das wichtigste Paket, wenn man in großen Schritten Richtung Matlab gehen möchte: Scipy. Es enthält viele elementare Pakete, wie z.b.

  • Matplotlib zum Erstellen von Plots
  • IPython zum angenehmen arbeiten
  • Numpy zur effizienten und einfachen numerischen Berechnung

Arbeitsumgebung IPython

Ich habe einige Python IDEs ausprobiert, aber bin nun bei IPython hängen geblieben. IPython kommt mit Scipy mit und ist sehr umfangreich. Gestartet wird die Arbeitsumgebung über die Kommandozeile mit

ipython notebook --script

Der Befehl notebook startet einen lokalen Server, welcher über den Browser unter localhost angesprochen werden kann. Auf der ‚Webseite‘ ist es dann möglich so genannte Notebooks zu öffnen, welche ähnlich wie MATLAB .m Files zu nutzen sind. Der Schalter –script sorgt dafür, dass immer parallel eine .py (also eine Python Datei) gespeichert wird, wenn man das Notebook (.ipynb) speichert.

ipython-start-mac

Import

Der große Unterschied zu MATLAB ist nun, dass man bei Python immer erst mal sagen muss, welche Plug-Ins man nutzen möchte im aktuellen Projekt (ähnlich der ‚path‘ Umgebung in MATLAB). Möchte man beispielsweise ein Plot erstellen, so ist vorher mitzuteilen, dass die mit Scipy gelieferte Bibliothek Pyplot zu verwenden ist.

import matplotlib.pyplot as plt

Danach stehen alle Funktionen von Matplotlib unter dem Objektnamen plt zur Verfügung.

Plot erstellen

Ein Plot lässt sich beispielsweise erstellen mit

x=range(5)
y=range(5)
plt.plot(x,y)
plt.show()

Diese Bibliothek ist sehr mächtig, wie die Beispiele zeigen!

Beispiel

import numpy as np
import matplotlib.pyplot as plt
import random
import time

n = 1100000
m=0.0
v=0.0
elapsed=[]
vals=[]
for i in xrange(0,n,1000):
    # Python reagiert auf Einrückungen (Leerzeichen oder <tab>)
    # Alles was eingerückt ist, gehört zur Schleife!

    #print 'Berechne für ' + str(i) + ' Werte.'
    values = np.random.sample(i)

    start = time.clock()
    m = np.mean(values)
    v = np.var(values)

    elapsed.append((time.clock() - start))
    vals.append(i)

fig = plt.figure(figsize=(12,5))
plt.plot(vals,elapsed, 'ro')
plt.xlabel(u'Anzahl Werte')
plt.grid()
plt.ylabel(u'Berechnungszeit [s]')
plt.title(u'Berechnungsdauer für var() und mean()')
plt.savefig('Berechnungsdauer.png',dpi=72)

plt.close()
print('Done.')

Berechnungsdauer

  Download IPython Notebook

 

Zusatzbibliotheken machen Python mächtig

Zwar gibt es für MATLAB unzählige Toolboxen und auch das Matlab Central, wo Zusatzfunktionen herunter geladen werden können, aber der große Vorteil an Python ist: Es ist kostenfrei!

Ein Blick auf die kompilierten Windows Versionen der Pakete zeigt, dass man überhaupt nicht überblicken kann, was alles möglich ist. Die Pakete die ich bisher genutzt habe, sind folgende:

  • Pandas, der Allrounder und mit Abstand das wichtigste Paket, wenn es um Datenhandling (Zeitreihen usw.) geht
  • Numpy um Vektoren und Arrays effizient zu benutzen
  • requests um Anfragen an Server stellen zu können
  • BeautifulSoup um HTML Antworten einfach auslesen zu können
  • Basemap um Karten zu erstellen
  • simplekml um Google Earth .kml Dateien zu erstellen
  • Bokeh für schönere Plots, Interaktivität und HTML Export

Schönere Plots

Möchte man das Plot jetzt auch noch mal in „schön“ haben, so bietet sich Bokeh an. Es muss natürlich importiert werden

from bokeh.plotting import *

aber anschließend geht es sogar einfacher und ansehnlicher als mit Matplotlib:

scatter(vals, elapsed, title='Berechnungsdauer')
show()

DA-Martin-Laufzeit-Bokeh

Learning by Doing

Weiterführend ist der Kurs „Introduction to scientific computing with Python“ von   J.R. Johansson empfohlen! Hier insbesondere der Teil 4: matplotlib – 2D and 3D plotting in Python.

Nachteil ggü. MATLAB

Der Nachteil ist ganz eindeutig, dass viele viele viele verschiedene Menschen die Zusatzpakete erstellen und jeder so seine eigene Art hat, dies umzusetzen. Das führt dazu, dass zum einen die Webseiten, wo die Pakete zu bekommen sind, nicht einheitlich aussehen und teilweise wirklich schlecht gepflegt werden (Installationshinweise usw..) und zum anderen auch die Art, wie man die Pakete nutzen kann, verschieden ist.

Bei MATLAB ist alles zentral durch Mathworks organisiert, d.h. man kann sich drauf verlassen, dass es eine ordentliche Hilfe gibt, dass die Funktion genau so funktioniert wie dort dargestellt und das es vom Syntax her eindeutig ist.

Bei einigen Python Paketen ist es eher ein Rätselraten, wie man das nun so benutzt, dass es macht was man möchte. Da wird http://stackoverflow.com/ schnell der beste Freund!

Das Extended Kalman Filter einfach erklärt

by Paul Balzer on 21. Juni 2013

33 Comments

Continue Reading

Das Kalman Filter einfach erklärt [Teil 2]

by Paul Balzer on 11. Mai 2013

26 Comments

Nachdem wir im Teil 1 den Kern des Kalman Filters geklärt haben, widmen wir uns nun dem komplizierteren Teil. Die im Teil 1 genannte Vorgehensweise mit dem multiplizieren bzw. addieren der Mittelwerte und Varianzen funktioniert so nur im eindimensionalen Fall. \(\)

Das heißt, wenn der Zustand, den man messen möchte, mit nur einer Variablen vollständig beschrieben werden kann. Das Beispiel, welches eingangs genannt wurde, die Position eines Fahrzeugs im Tunnel zu bestimmen, kann aber nicht mehr mit einer Variablen vollständig beschrieben werden. Zwar interessiert nur die Position, aber diese ist genau genommen ja schon 2-Dimensional in der Ebene (\(x\) & \(y\)). Außerdem kann nur die Geschwindigkeit (\(\dot x\) & \(\dot y\)) gemessen werden, nicht die Position direkt. Dies führt zu einem 4D-Kalman-Filter, mit folgenden Zustandsvariablen:

$$x=\begin{bmatrix}
x \\
y \\
\dot x \\
\dot y
\end{bmatrix}=\begin{matrix}\text{Position X} \\ \text{Position Y} \\ \text{Geschwindigkeit in X} \\ \text{Geschwindigkeit in Y}
\end{matrix}$$

Herr Kalman hatte sich nun überlegt, wie man es schafft, trotz verrauschter Messung einzelner Sensoren, eine optimale Schätzung aller Zustände zu berechnen.

Continue Reading

OpenCV mit Python unter Windows 7

by Paul Balzer on 17. März 2012

No Comments

Durch meine berufliche Betätigung bin ich auf mehr oder weniger sinnvolle Anleitungen zur Inbetriebnahme der Open Computer Vision Bibliotheken mit Python unter Windows 7 gestoßen. Ich möchte eine schnelle und einfache Art noch mal festhalten, damit nicht jeder so viel Zeit in diese Sache investieren muss.

Benötigte Software um OpenCV/Python unter Windows7 zu nutzen

Obwohl ich ein 64bit Windows nutze, sind die 32bit Versionen der nachfolgenden Software zu nutzen, da OpenCV und 64bit keine richtigen Freunde sind.

  1. Python 2.7.2 Windows 32bit installer
  2. OpenCV 2.3.1 Win Superpack
  3. NumPy1.6.1  Win für Python 2.7
  4. SciPy 0.10.1 Win für Python 2.7

Nach der Installation aller Pakete muss Python noch der Zugriff auf OpenCV ermöglicht werden. Dazu im Installationsverzeichnis von OpenCV im Unterordner \build\python\2.7 die Dateien cv.py und cv2.pyd in den Python-Ordner \Lib\site-packages\ kopieren.

Wenn alles erfolgreich verlief, so kann man im Python mit import cv die komplette Computervision Biblitothek  importieren und nutzen.

Continue Reading