Male eine Ziffer — dein erstes CNN
Trainiere in deinem Browser ein eigenes Convolutional Neural Network auf 65.000 echten Handschrift-Ziffern — und lass es danach die Ziffern erkennen, die du selbst malst.
👋 HerrKI hier — heute baust du dir einen Postleitzahl-Leser
Jede Paket-Sortieranlage der Welt liest Postleitzahlen. Handgeschrieben. Schief. Mal Kugelschreiber, mal Filzstift, mal quer über die Klebekante. Zehntausende Sendungen pro Stunde, und irgendwo dazwischen deine krakelige 7. Dass das funktioniert, ist keine Magie — es ist ein kleines Netz aus ein paar tausend Zahlen. Und genau so eines baust du dir heute selbst: in diesem Browser-Tab, mit ungefähr einer Minute Rechenzeit.
Übungsmaterial brauchst du dafür — und da gibt es den Klassiker: MNIST. Ende der 1980er kritzelten Mitarbeiter des US-Volkszählungsamts und Highschool-Schüler Zehntausende Ziffern auf Formulare. Die wurden ausgeschnitten, auf 28×28 Pixel normiert, mittig ausgerichtet — und sind seit 1998 das „Hallo Welt“ der Bilderkennung: Jedes neue Verfahren muss zuerst hier antreten. 65.000 dieser Bilder liegen für dich bereit, echte fremde Handschriften, kein einziges davon erfunden.
- Wie aus einem Bild ein Tensor wird — du siehst die Zahlen selbst
- Was ein Conv-Filter abtastet und warum er einer Dense-Schicht bei Bildern überlegen ist
- Die komplette Form-Reise durchs Netz: [28,28,1] → … → [10]
- Ein echtes Training mit Loss und Genauigkeit, live mitzulesen
- Deine eigene Handschrift gegen dein eigenes Netz — samt der Fälle, in denen es danebenliegt
💡 Roter Faden: Anwendung → runter bis auf die einzelne Zahl → wieder hoch. Am Ende hältst du beides in der Hand: die gemalte Ziffer und die zehn Zahlen, die das Netz darüber sagt.
📦 Schritt 1: Die Übungsbilder holen
Alle 65.000 Bilder stecken in einer einzigen PNG-Datei — einem sogenannten Sprite: 784 Pixel breit, 65.000 Zeilen hoch. Jede Zeile ist ein komplettes Bild, ausgerollt zu einer Kette aus 28 × 28 = 784 Graustufenwerten. Ein Bild wandert also nicht als Bild über die Leitung, sondern als Zahlenreihe. Die Antworten („was steht drauf?“) liegen daneben in einer zweiten Datei: 10 Bytes pro Bild, davon genau eine 1 — die Position der 1 ist die Ziffer. Das ist die One-Hot-Kodierung aus Kapitel 230.
Zusammen 11 MB. Die laden wir erst auf deinen Klick — Datenvolumen ist nicht umsonst.
👀 Zwölf zufällige Bilder aus dem Stapel
Frisch aus dem Sprite gezogen, hochskaliert (deshalb die groben Pixel) — darunter steht jeweils, welche Ziffer laut Datensatz gemeint ist. Schau dir an, wie unterschiedlich Menschen eine 4 oder eine 9 schreiben. Genau diese Streuung muss dein Netz gleich verkraften.
🔢 Schritt 2: Runter zum Tensor — was das Netz wirklich sieht
Für das Netz ist ein Bild keine Zeichnung, sondern eine Tabelle: 28 Zeilen, 28 Spalten, in jeder Zelle eine Zahl zwischen 0.00 (schwarz) und 1.00 (weiß). Mehr ist da nicht. Links siehst du ein Beispiel als Bild, rechts einen 10×10-Ausschnitt aus seiner Mitte als das, was es in Wahrheit ist — jede Zeile rechts ist genau eine Zeile aus dem Bild links. Wenn du die Augen ein wenig zusammenkneifst, erkennst du die Ziffer im Zahlenrelief.
Noch keine Daten geladen — drück oben den Knopf.
[28, 28, 1]
Zeilen 10–19, Spalten 10–19 — 0.00 = schwarz, 1.00 = weiß:
Und jetzt die Reise dieser Tabelle durch das Netz, das du gleich baust. Lies sie von oben nach unten — rechts steht immer, welche Form (Shape) der Tensor nach dem Schritt hat:
Von [28,28,1] — 784 Zahlen — bis [10] — zehn Zahlen. Zwei Dinge fallen auf: Die Fläche schrumpft (28 → 24 → 12 → 8 → 4), die Tiefe wächst (1 → 8 → 16). Das Netz gibt Ortsauflösung auf und kauft dafür Bedeutung ein. Dass aus 28 nach dem ersten Conv nur 24 wird, ist übrigens kein Trick: Eine 5×5-Lupe passt am Rand nicht mehr vollständig aufs Bild, also fallen links und rechts je 2 Pixel weg.
🔍 Was tastet so ein Filter eigentlich ab?
Stell dir eine 5×5-Lupe vor, die Pixel für Pixel über das ganze Bild wandert und an jeder Stelle eine einzige Frage stellt: „Passt hier mein Muster?“ Der eine Filter schlägt bei senkrechten Kanten an, der nächste bei einer Rundung oben links, der dritte bei einem Strich-Ende. Diese Muster gibt niemand vor — sie entstehen im Training, so wie die Gewichte in „Was ist ein Neuronales Netz?“. Der entscheidende Kniff: Es ist überall dieselbe Lupe. Ein Muster einmal gelernt, im ganzen Bild erkannt — egal ob die Kante links oben oder rechts unten sitzt.
Das ist der ganze Unterschied zu einer normalen Dense-Schicht: Die bekäme 784 lose Zahlen serviert, ohne jede Ahnung, dass Pixel 100 und Pixel 101 nebeneinander liegen. Ein Conv-Filter weiß das per Bauart. (Wie so ein Bild-Tensor überhaupt aufgebaut ist, steht ausführlich in „Bilder als Tensoren“.)
🚀 Schritt 3: Trainieren
Wir nehmen 6.000 Bilder zum Üben und legen 1.000 zur Seite, die das Netz nie zu sehen bekommt — die Prüfung am Ende. Warum das so sein muss, steht in „Trainieren, prüfen, bestehen“: Auf den Übungsblättern ist jeder gut. Alle 7.000 Bilder werden zufällig aus den 65.000 gezogen, du bekommst also bei jedem Neuladen einen anderen Stapel.
🏁 Die Prüfung: 1.000 nie gesehene Bilder
Acht davon im Einzelnen — ehrlich, inklusive der Patzer
Oben die Vorhersage deines Netzes, darunter die richtige Antwort. Grün = getroffen, rot = danebengelegen. Bei rund 97 % Genauigkeit ist im Schnitt jedes 33. Bild ein Fehler — mit etwas Pech siehst du hier also einen.
✍️ Schritt 4: Jetzt du — male eine Ziffer
Male mit der Maus oder dem Finger eine Ziffer von 0 bis 9 — groß und mittig, so wie die Trainingsbilder aussehen. Sobald du den Strich absetzt, rechnet dein Netz. Der Weg deiner Zeichnung: 280×280 Pixel → auf 28×28 heruntergemittelt (je 10×10 Pixel werden zu einem) → als Tensor [1, 28, 28, 1] ins Netz → raus kommen zehn Zahlen.
Erst trainieren — dann malen.
Das Netz sagt:
🔬 Und das ist ALLES, was das Netz sagt — zehn Zahlen
Kein Wort, kein Bild, keine Erklärung: der rohe Ausgabe-Tensor der Softmax-Schicht. Die zehn Werte addieren sich immer zu 1,00 — die Position des größten ist die erkannte Ziffer. Alles, was du oben an Balken und Prozenten siehst, ist nur eine hübschere Darstellung dieser Zeile.
🤨 Ehrlich bleiben: Warum hält es deine 7 manchmal für eine 1?
97 % auf den Testbildern — und dann erkennt es deine Ziffer nicht. Kein Widerspruch, sondern der wichtigste Effekt dieses Kapitels: Verteilungs-Verschiebung (englisch distribution shift). Das Netz hat nie „Ziffern“ gelernt. Es hat gelernt, diese 65.000 Bilder zu unterscheiden — und die kommen alle aus derselben Fabrik:
- Anderer Stift: MNIST-Striche sind bei 28×28 rund zwei Pixel breit. Deine Fingerspur ist relativ dazu vielleicht dreimal so dick oder halb so dünn — für die 5×5-Lupen ein völlig anderes Muster.
- Andere Zentrierung: Jede MNIST-Ziffer wurde per Schwerpunkt mittig in ein 20×20-Feld gesetzt. Malst du klein in die Ecke, sitzt deine Ziffer schlicht an einer Stelle, an der das Netz nie eine gesehen hat.
- Andere Schreibkultur: MNIST ist US-amerikanisch. Die deutsche 7 mit Querstrich und die 1 mit dickem Aufstrich kommen dort kaum vor — die beiden landen deshalb gern in derselben Schublade.
🩹 Gegenmittel für hier: groß malen, mittig, mit ruhigem Strich — und die 7 ruhig mal ohne Querstrich. Gegenmittel in der echten Welt: mit Daten trainieren, die aussehen wie die späteren Einsatzdaten, plus künstliche Variation (drehen, verschieben, verzerren). Genau deshalb trainiert die Post nicht auf MNIST, sondern auf Fotos ihrer eigenen Pakete.
🔑 Merksatz: Eine Genauigkeit gilt immer nur für Daten, die aussehen wie die Testdaten. „97 %“ ohne die Frage „auf welchen Daten?“ ist eine leere Zahl.
🧠 Kurzer Check — hast du es?
Als Nächstes in der Werkzeug-Reihe: 430 — Objekterkennung. Dort geht es nicht mehr um was ist auf dem Bild, sondern um wo genau — und du wirfst ein fertiges Netz auf deine eigenen Fotos. Dieselben Filter, nur ein paar Größenordnungen mehr davon. 🐍
