Das Projekt libsnnl ist im meine Belegarbeit im Fach Neuroinformatik des Studiengangs Informatik (6. Semester) an der HTW-Dresden.
Die Aufgabe bestand darin, ein neuronales Feed Forward Netz in einer C++ Bibliothek zu implementieren. Als Lernalgorithmus sollte Backpropagation umgesetzt werden.
Die dabei entstandene libsnnl implementiert ein Multilayer Perceptron Netzwerk in Form einer statisch linkbaren Bibliothek. Simple Network Library deswegen, weil sich die Bibliothek meiner Meinung nach sehr einfach benutzen lässt (siehe Beispiele).
Die Anzahl der Netzwerk-Schichten und die Anzahl der darin enthaltenen Neuronen können variabel bestimmt werden. Es werden drei Arten von Schichten unterschieden, Input, Hidden und Output. Für jeden Schichtentyp können verschiedene Aktivierungsfunktionen gesetzt werden. Die Lernfunktionalität ist in eine extra Klasse Teacher ausgelagert. Diese Klasse enthält auch Funktionalität zum Umgang mit Trainingssätzen, zum Beispiel Laden, Speichern, Shuffeln und so weiter.
Das Projekt ist voll und ganz unter Zuhilfenahme von freier Software entwickelt worden und liegt GNU-konform vor. Das heißt das sich die Bibliothek auf jedem unixoiden Betriebssystem übersetzen und benutzen lässt. Für Windows Nutzer sind außerdem entsprechende Visual Studio Projekte enthalten. Was kann die Bibliothek im Detail?
Die Dokumentation wurde mit Doxygen direkt aus dem Quellcode heraus erstellt. Das hat den Vorteil das sich die Dokumentation direkt im Quellcode befindet. Doxygen wurde so konfiguriert, dass der Quellcode mit in die Dokumentation aufgenommen wurde. Somit hat man die Funktionalität verbal beschrieben und sieht gleichzeitig wie es praktisch umgesetzt wurde. Als Sprache wurde Englisch gewählt. An geeigneter Stelle wird in der Dokumentation auch die mathematische Beschreibung des implementierten Algorithmus abgebildet.
Zusätzlich liegt ein Klassendiagramm in UML-Notation vor.
Wie im Klassendiagramm ersichtlich besteht das Projekt hauptsächlich aus 5 Klassen. Dabei stellt die Klasse Network das eigentliche Netz dar. Wenn das Netz einmal trainiert und einsatzbereit ist, stellt diese Klasse die alleinige Schnittstelle zum Nutzer dar. Mit den Klassen Layer und Neuron kommt man als Nutzer der Bibliothek nicht in Berührung. Die Lernfunktionalität ist in der Klasse Teacher implementiert. Diese Klasse wird nur zum Trainieren eines Netzes benötigt. Dies ist auch der Grund warum die Lernfunktionalität ausgelagert wurde. So wird erreicht, dass eine trainierte Netz-Instanz nur den minimal benötigten Code enthält. Außerdem ist es so auch möglich, dass eine Teacher-Instanz mehrere Netze trainieren kann. Die Benutzung an sich, so denke ich, wird am Besten durch die Beispiele klar die im Folgenden beschrieben werden.
Alle Beispiel befinden sich im Unterverzeichnis test des Projektes. Sie werden automatisch beim Übersetzen der Bibliothek mit gebaut. Die Beispiele sollen zum einen den Umgang mit der Bibliothek verdeutlichen, dienen aber gleichzeitig zum verifizieren der korrekten Arbeitsweise. Zum experimentieren mit den Beispielen ist keine Installation der Bibliothek nötig. Will man selbst Änderungen im Code vornehmen, genügt ein simples "make" zum neu bauen der geänderten Teile. Zum Visualisierung der Ausgaben ist die Installation von gnuplot und graphviz empfehlenswert. Im test-Verzeichnis liegt ein entsprechendes Perl-Script vor, was die Ausgaben der Beispiele zur Visualisierung vorbereitet.
libtest_create (Code)
Dieses Beispiel zeigt kurz und prägnant wie man sich Instanzen der Klassen Network und Teacher erzeugen kann und wie diese Klassen mit einander interagieren. Es werden 3 Netzwerke auf unterschiedliche Art und Weise erzeugt. Zum Schluss werden diese "gedumpt", sprich im graphviz Format gespeichert. Im Header des Quellcodes befindet sich, wie bei jedem anderen Beispiel auch, eine kurze Gebrauchsanweisung.
libtest_xor (Code)
Das obligatorische xor-Beispiel darf auch hier nicht fehlen. Es wird ein bereits trainiertes Netz geladen und benutzt. Die Funktionalität der Teacher-Klasse wird in diesem Beispiel nicht benötigt. Der Netzwerk-Graph wird auch hier in eine Datei geschrieben und sieht visualisiert folgendermaßen aus.

%> ./libtest_xor x y net_output 0 0 0 0 1 1 1 0 1 1 1 0
libtest_binclassify (Code)
In diesem Beispiel geht es darum ein Netz Binärzahlen lernen und erkennen zu lassen, sprich Binärzahlen in die entsprechende dezimale Form umzuwandeln. Es wird in diesem Beispiel speziell der Umgang mit der Teacher-Klasse ersichtlich. Die Programmausgabe.:
%> ./libtest_binclassify train network ... errorfile activated (dump/libtest_binclassify_error.dat) done, need 8 epoch's network output: dec input opt_output net_output 0 0000 000000000 000000000 1 0001 100000000 100000000 2 0010 110000000 110000000 3 0011 111000000 111000000 4 0100 111100000 111100000 5 0101 111110000 111110000 6 0110 111111000 111111000 7 0111 111111100 111111100 8 1000 111111110 111111110 9 1001 111111111 111111111
libtest_sin (Code)
Dies ist ein etwas größeres Beispiel, in dem es darum geht einem Netz die Sinus-Funktion zu lernen. Bei diesem Beispiel ist es möglich etwas mit den Lernparametern zu experimentieren. Diese kann man dem Programm per Kommandozeile übergeben. Es werden 10 Durchläufe zu je 10 Epochen gelernt. Nach Jedem der 10 Durchläufe wird das Netz geprüft. Die Ausgabe kann man sich mittels gnuplot visualisieren lassen.

libtest_encoder_decoder (Code)
In diesem Beispiel ist ein 8-3-8 Bit Encoder-Decoder realisiert. Das Trainset wird von Datei geladen. Während der Lernphase wird Protokoll über den Verlauf des Fehlers geführt. Diesen kann man sich anschließend mit gnuplot visualisieren lassen.

%> ./libtest_encoder_decoder errorfile activated (dump/libtest_encoder_error.dat) train network ... need 30 epoch's network output: --------+-------+-------- 00100000|->-3->-|00100000 00000100|->-3->-|00000100 00000010|->-3->-|00000010 00001000|->-3->-|00001000 10000000|->-3->-|10000000 01000000|->-3->-|01000000 00010000|->-3->-|00010000 00000001|->-3->-|00000001
libtest_two_spirals (Code)
Das Problem der zwei Spiralen ist ein bekanntes und oft herangezogenes Beispiel wenn es darum geht Netzarchiteturen und Lernalgorithmen zu vergleichen beziehungsweise zu benchmarken. Es geht bei diesem Problem darum ein Netz mit x-y-Koordinaten (194 Datensätze) von zwei Spiralen anzulernen um später klassifizieren zu können, zu welcher Spirale eine Koordinate gehört. Dazu existieren 770 Testdatensätze. Die Spiralen sind 3 mal in einander verwickelt. Es handelt sich hierbei um eine sehr schwierige Aufgabe für Backpropagation-Netzwerke da die Daten hochgradig nicht-linear sind.



%> ./libtest_spirals errorfile activated (dump/libtest_spiral_error.dat) train network ... 9678 epoch's needed network saved to dump/spiral_network.net --- verifing with test-data-set --- x y optout network network - analog value 6.50 0.00 1 1 | 0.87 -6.50 -0.00 0 0 | -0.03 6.48 0.32 1 1 | 0.95 -6.48 -0.32 0 0 | -0.90 6.44 0.63 1 1 | 0.97 ... -0.52 0.03 0 0 | -0.02 0.50 0.00 1 1 | 0.84 -0.50 -0.00 0 0 | 0.05 accuracy: 97.8%
Download
Das komplette Projekt ist als Quellcode-Packet mit Dokumentation
unter folgendem Link erhältlich.
Unix typisch erfolgt die Übersetzung im gewohnten Kommando-Tripel im Rootverzeichnis des Projektes.:
$> ./configure [--prefix ...] $> make $> make installWie gewohnt kann über den Prefix-Schalter das Installationsziel angegeben werden. Installiert werden die Bibliothek und die benötigen Header-Dateien, nicht jedoch die Testprogramm.
Das Projekt wurde erfolgreich auf FreeBSD, NetBSD, SuSE Linux und Windows Systemen übersetzt und getestet.
Für die Benutzung der Bibliothek ist eine Installation nicht zwingend notwendig. Es reicht auch dem Compiler den entsprechenden Library-Pfad mit zu teilen. Ebenfalls muss dem Compiler der Include-Pfad zu den Header-Dateien mitgeteilt werden. Das könnte zum Beispiel so aus sehen.
$> c++ -L../src -I../src/include libtest.cpp -lsnnl -o libtestFür die Benutzung auf Windows Systemen stehen im Verzeichnis MSVS7 entsprechende Visual Studio Projekte zur Verfügung. Das Projekt lib ist dabei als erstes zu übersetzen.
Interessante Links zum Thema Neuronale Netze.