Handschrifterkennung - Beleg Neuronale Netze / Projektseminar
Kristian Hermsdorf / Daniel Flemming






Einleitung
Funktionsweise
Java-Realisierung
Bedienung
Beispiel Applet
Download

Einleitung


Wer schon einmal auf einem Palm Handheld probiert hat, Buchstaben mit der eingebauten Schrifterkennung einzugeben, weiß wie mühsam das ist. Man muss erst einen bestimmten Schriftsatz erlernen, damit überhaupt etwas erkannt werden kann.
So mühsam dieses Verfahren auch ist - die Idee die hinter dieser Buchstabenerkennung liegt, ist genial. Wir haben den Grundalgorithmus aufgegriffen und die Werte die dieser liefert, an ein neuronales Netz übergeben (Palm Handhelds nutzen keine neuronalen Netze).

Funktionsweise


Wenn man einen Buchstaben oder eine Zahl schreibt, so ist der Linienzug der sich ergibt immer charakteristisch. Man kann zur Auswertung und Erkennung der Buchstaben und Zahlen den Linienzug in kleine Geraden zerlegen und die Geraden auf die Länge 1 skalieren. Legt man nun den Anfangspunkt dieser Geraden in den Nullpunkt eines Koordinatensystems, so beschreiben alle auf diese Weise möglichen Geraden den Einheitskreis. Die Idee ist nun, den Sinus und den Kosinus des Winkel zwischen Gerade und X-Achse des Koordinatensystems zu bestimmen. Jeder Buchstabe, jede Zahl und jedes Zeichen hat einen charakteristischen Verlauf dieser sin/cos-Werte. Nimmt man nun noch zusätzlich den Druck den der Schreiber an den einzelnen Abtastpunkten ausübt auf, so bekommt man eine ziemlich genaue mathematische Repräsentation des Zeichens.
Der Vorteil dieses Verfahrens ist, das der Sinus/Kosinus-Verlauf immer gleich ist, egal wie groß der Buchstabe geschrieben wird. Der Nachteil ist, das man z.B. ein großes "O" nicht mehr von einem kleinen "o" unterscheiden kann. Aber dies ist ja selbst von einem Menschen (fast) unmöglich, wenn der Kontext in dem dieser Buchstabe auftritt unbekannt ist.
Unser Programm zeichnet nun den Sinus/Kosinus-Verlauf auf (bei Benutzung eines druckempfindlichen Stiftes zusätzlich noch den Druck) und übergibt dies als Input an ein neuronales Netz.
Das Netz wertet diesen Kurvenverlauf aus, abstrahiert und kategorisiert und gibt den ASCII-Wert des Zeichen und auch den Schreiber des Zeichen aus. Um dies zu bewerkstelligen, muss aber das Netz vorher mit Beispiel-Zeichen verschiedener Personen trainiert werden.

Java-Realisierung


Der Beleg ist komplett in Java geschrieben und bietet über das Java-Native-Interface Anbindung an druckempfindliche Grafiktableaus. Die Methodenbeschreibungen sind der JavaDoc zu entnehmen.
Beim Start des Beleges übernimmt die Klasse de.cul8r.synapse.Synapse die Kontrolle und erzeugt die grafische Benutzeroberfläche. Diese wird mit Swing realisiert. Für die komplette Logic und für die Eventbehandlung ist dann die Klasse de.cul8r.synapse.Controller verantwortlich. Im folgenden werden kurz alle Packages vorgestellt und deren Aufgabe erläutert:
  • de.cul8r.synapse.gui:
  • Hier sind alle Klassen enthalten, die mit der Anzeige der GUI zusammenhängen. Die Pen* Klassen sind dafür verantwortlich, den druckempfindlichen Stift abzufragen und die Werte als Events an das Programm zu liefern.

  • de.cul8r.synapse.jni:
  • In diesem Package sind Klassen enthalten, die über Bibliotheken (dll's) auf die Hardware des Rechners zugreifen. Unter anderem, um den Stift abzufragen.

  • de.cul8r.synapse.neuro:
  • Hier sind alle Klassen enthalten, die zur Modellierung eines neuronalen Netzen notwendig sind. Alle neuronalen Netze die verwendet werden, implementieren das Interface NeuralNetwork. Außerdem gibt es noch einige andere Aktivierungsfunktionen, wie zum Beispiel TanH, die Logistische Funktion und die Identität.

  • de.cul8r.synapse.snns:
  • In diesem Package befinden sich Klassen, um Snns-Netzwerke einzulesen und Snns-Pattern-Files zu lesen und zu schreiben.

  • de.cul8r.synapse.tab:
  • Hier befinden sich zusätzliche Klassen um auf den druckempfindlichen Stift zuzugreifen. Außerdem ist hier auch ein kleines Testprogramm für den Stift vorhanden. Dieses kann mit java de.cul8r.synapse.tab.Test aufgerufen werden.

  • de.cul8r.synapse.tools:
  • Wie es in jedem Projekt ist, braucht man immer ein paar kleine Helper-Klassen. Diese befinden sich in diesem Package.

Bedienung


Das Programm ist in drei Bereiche untergliedert. 1. Files, 2. Settings, 3. Draw & Recall.
Nach dem Start mittels Synapse.bat landet man im Draw & Recall Bereich, in dem man sofort anfangen kann, Buchstaben oder Zahlen zu malen, die dann vom Programm erkannt werden. Man kann die Eingabe entweder mit der Mause machen oder auch - sofern vorhanden - ein Grafiktableau benutzen. Gemalt wird in das graue Feld am linken oberen Rand des Programmes.

Bei Eingaben mit der Maus wird nur die Form des Zeichens ausgewertet und daraufhin das Zeichen erkannt. Wird ein Grafiktableau verwendet, wird zusätzlich der Druck, der bei der Eingabe des Zeichens aufgetreten ist mit verwertet, was eine Erkennung der Person, die das Zeichen eingegeben hat, ermöglicht. Um jedoch die Person zu erkennen, muß diese vorher ein neuronales Netz trainiert haben.
Nachdem man ein Zeichen eingegeben hat, wird auf der rechten Seite des Programmes angezeigt, wie das Zeichen verarbeitet wurde. Am oberen Rand sieht man die Sinus/Kosinus/Druck-Repräsentation des eingebenen Zeichens. Darunter folgt dann die Ausgabe, ob das Zeichen / Eingabeperson erkannt wurde, oder nicht. Bei erkannten Zeichen wird das Zeichen am unteren Rand in das Textfeld übernommen.
Das Balkendiagramm zeigt die Werte der Ausgabeschicht des neuronalen Netzes an, gute Werte sind ganz leere, oder ganz volle Balken. Diese stehen für eindeutige Werte. Ist ein Balken nur halb gefüllt, ist sich das Netz an dieser Stelle nicht sicher und bei der Ausgabe der Erkennung steht auch da "... wahrscheinlich * erkannt".

Um ein neurobales Netz zu trainieren, ist die Eingabe von Beispielwerten (Patterns) notwendig. Das Programm unterstüzt die Erfassung dieser Patterns. Mit der Checkbox "Learn" wechselt man vom Erkennungsmodus in den Patterneingabemodus.
Nun kann man in den beiden Comboboxen einstellen, wer welches Zeichen eingeben wird. Dann kann man beginnen die Patterns einzugeben. Es hat sich bewährt jedes Zeichen 10 bis 15 mal einzugeben. Falls man ein Zeichen falsch eingeben hat, kann man das jeweils letzte Zeichen wieder löschen. Dazu gibt es einen Button "Delete Last Pattern" im Files Menu. Im Draw & Recall Bereich sieht man auch, wieviele Pattern schon eingegeben wurden. Wie im der Funktionsweise beschrieben wird das eingebene Zeichen in Sinus und Kosinuswerte zerlegt. Mit dem Resolution-Schieberegler kann man die Auflösung einstellen, die festlegt, in wie viele Werte das Zeichen unterteilt werden soll. Hierbei hat sich ein Wert um die 20 bewährt. Man kann die Resolution nur ändern, wenn gerade kein Netz geladen ist, damit man keine falschen Eingaben treffen kann. Möchte man also die Auflösung ändern, löscht man das aktuelle Netz mit "Delete Weights" im Files Menu.
Nachdem nun genügend Eingaben gemacht wurden, kann man die Patterns speichern. Dazu gibt es einen "Save Patterns"-Button im Files Menu. Der Dateiname, unter dem die Patterns gespeichert werden, wird im Settings-Bereich eingestellt.

Dann kann man im SNNS ein neuronales Netz trainieren, welches als "*.net" File gespeichert wird und in unserem Programm zur erkennung wieder eingeladen werden kann.
Im Files Menu gibt es die Möglichkeit vorhanden Patternfiles zu laden, die aktuellen Patterns zu speichern oder das letzte oder alles eingegeben Patterns zu löschen.
Außerdem kann man SNNS-Netze laden oder wieder löschen.

Im Settings-Bereich kann man Einstellen, welches Neuronale Netz zu Beginn des Programmes geladen werden kann (StdNetworkFile), und welches Netz geladen werden soll, wenn man auf "Load Weights" geht (NetworkFile).
Außerdem kann man dort einstellen, ob ein Grafiktableau oder die Maus als Eingabegerät verwendet werden soll. (InputDevice=Maus/Pen).
Die restlichen Einstellmöglichkeiten sind nur für die funktionsweise wichtig, also nicht vom Nutzer zu verändern.

Beispiel Applet


Hier geht's zum Applet

Download


SynapseJava.zip