A Very Stable Genius

Automa­tische Zahlen­erkennung

Auf dieser Seite wird die Muster­erkennung mit einem neuronalen Netz zum automati­sierten Erkennen von hand­geschriebenen Ziffern angewendet. Die Grundlage bildet ein so­genanntes Hopfield-Netz. Es speichert zehn Muster­ziffern, die aus den 60 000 hand­geschriebenen Ziffern der MNIST-Sammlung gemittelt wurden. Die gespei­cherten Muster­ziffern werden selbst dann noch zuver­lässig wieder­hergestellt, wenn bis zu 30 Prozent ihrer Felder zufällig gestört sind. Hand­geschriebene Ziffern weichen jedoch nicht zufällig, sondern in ihrer Form von diesen Mustern ab. Hier erkennt das Netz rund zwei Drittel der Ziffern richtig.

Zum Vergleich wird die Ziffer zusätzlich mit einem modernen Hopfield-Netz erkannt. Statt zehn Muster­ziffern in einer gemeinsamen Gewichts­matrix zu überlagern, speichert es 5000 hand­geschriebene Ziffern aus der MNIST-Sammlung einzeln. Die Eingabe wird mit allen verglichen, und je ähnlicher ihr ein gespei­chertes Muster ist, desto stärker zählt seine Stimme für die eigene Ziffer. So werden rund neun von zehn Ziffern richtig erkannt. Die Prozent­angabe hinter dem Ergebnis ist der Stimmen­anteil der erkannten Ziffer. Sie lässt sich näherungs­weise als Wahr­schein­lichkeit lesen, dass die Erkennung stimmt, ist in Tests allerdings leicht zu optimis­tisch.

Noch bessere Ergebnisse liefern aufwen­digere Ansätze wie ein «Multilayer-Perceptron» zusammen mit «Supervised Learning». Dabei lernt das Netz gezielt, an welchen Merkmalen sich die Ziffern unter­scheiden.

Die Program­mierung erfolgte in JavaScript (siehe Atwood's Law: «Any application that can be written in JavaScript, will eventually be written in JavaScript») unter Verwendung der jQuery-Bibliothek und des umfang­reichen Vektor­graphik-Skripting-Pakets Paper.js («The Swiss Army Knife of Vector Graphics Scripting»). Die Auf­bereitung der Ziffern (Pre­processing) erfolgt in Python, die eigent­liche Erkennung mit den beiden Hopfield-Netzen ist in PHP program­miert.

      Python

Alle Programme bzw. Skripte wurden im Visual Studio Code-Texteditor geschrieben.

Bei allen verwen­deten Programmier­werkzeugen und -sprachen handelt es sich um um sog. «open source»-Produkte.

Papier­block und Stift

Bitte hier – möglichst unter Ausnutzung der voll­ständigen Fläche – eine Ziffer (0, 1, …, 9) schreiben, anschlies­send die Taste «erkennen» drücken:

Das karierte Notiz­papier oben hat eine Auflösung von 28 × 28 = 784 binären Bild­punkten, ungefähr so viele, wie ein Facetten­auge der Taufliege Einzel­augen besitzt. Die Sehzellen der Fliege – wie jene in der Netzhaut des Menschen mit ihren über 120 Millionen Sinnes­zellen – sind dagegen helligkeits­empfindlich und können Farben unter­scheiden.

Vor der Erkennung mit dem neuronalen Netz wird die gezeichnete Ziffer als normierter Strecken­zug auf­bereitet: Sie wird leicht geglättet, bei schräger Schrift gerade gedreht und anhand eines umgebenden Rechtecks (sog. Bounding Box) unter Wahrung des Seiten­verhältnisses auf die volle Fläche des Notiz­papiers vergrössert. Zum Schluss wird sie mit ihrem Schwer­punkt in die Mitte gerückt und mit gleich­mässig dickem Strich neu gezeichnet.

Es gibt keine Radier­gummi-Funktion. Um die Zeichnung zu löschen, muss entweder der Knopf «löschen» gedrückt oder die Seite neu geladen werden.

Beim schnellen Zeichnen werden bei der Rasterung nicht alle über­strichenen Felder blau markiert, weil nur die Punkte geprüft werden, welche die Maus tatsächlich meldet. Auf die Erkennung hat dies keinen Einfluss, da sie mit dem voll­ständigen Strich arbeitet.

Auswertung

Die einge­gebene Zahl:

Zentriert und skaliert:

Die erkannte Zahl:

klassisches Hopfield-Netz:

modernes Hopfield-Netz: