WWDC Scholarship 2019

Was ist die WWDC?
Die WWDC („Worldwide Developers Conference“), ist die Entwicklerkonferenz von Apple welche jährlich durchgeführt wird. Dort werden neue Features von iOS und macOS sowie neue Technologien vorgestellt. Ausserdem kann man mit Apple Entwicklern reden, sich Tipps geben lassen und andere Entwickler kennenlernen.

Wie kommt man an die WWDC?
Um an der WWDC teilzunehmen, muss man viel Glück haben. Die Tickets zur Teilnahme werden verlost. Wenn man Glück hat und ausgewählt wird, muss man noch 1599 CHF zahlen damit man teilnehmen darf.
Es gibt aber noch einen anderen Weg, wie man teilnehmen kann. Als Schüler/Student kann man ein selbstgeschriebenes Programm einreichen und Apple wählt dann bis zu 350 Personen aus, welche kostenlos teilnehmen dürfen. Die Konkurrenz ist aber gross, letztes Jahr gab es acht- bis neuntausend Bewerber und in diesem Jahr waren es noch mehr.

Meine Bewerbung
Als ich gehört habe, dass es das „WWDC Scholarships“ Programm gibt, war ich begeistert und habe mich dazu entschieden, teilzunehmen. Ich wusste schnell, dass ich etwas mit Machine Learning machen wollte. Ich habe die neusten Änderungen angeschaut und bin auf CreateML gestossen. Mit CreateML kann man auf einem Mac ein Modell erstellen, welches dann später mit CoreML und Vision auf macOS und iOS verwendet werden kann. In den Weihnachtsferien im Dezember habe ich mit dem Projekt begonnen. Ich habe mit CreateML und CoreML herumexperimentiert und geschaut, was man damit alles machen kann. Zuerst habe ich Tiere erkannt aber dann begann ich mit der Erkennung von Handschrift. Daraufhin habe ich mit dem MNIST Dataset herumgespielt und einige Zahlen erkannt. Da man aber keine öffentlichen Ressourcen verwenden sollte, konnte ich MNIST nicht verwenden. Ich habe mich dazu entschieden, Zahlen und Operatoren zu erkennen um einen handschriftlichen Taschenrechner zu erstellen. Dafür brauchte ich für jedes Zeichen (0-9, +, -, *, /, =) möglichst viele Bilder.
Meine erste Idee war es, den Nutzer jedes Zeichen zeichnen zu lassen, dann das Modell trainieren und dieses dann direkt verwenden. Leider ist es nicht sehr toll, mit einer Maus zu schreiben. Deshalb habe ich mich dazu entschieden, diese Idee nicht umzusetzen.
Die andere Möglichkeit, welche es gibt, ist es, das Training des Modells auf einem Mac durchzuführen, das Modell dann auf ein iPad kopieren und dort die Handschrift zu erkennen. Ich habe mich für diese Möglichkeit entschieden, da es besser ist auf einem Touchscreen zu zeichnen und da das Training eine Weile dauern kann und so besser im Voraus durchgeführt wird.
Die erste Version welche ich entwickelt habe, war eine Zeichnungsfläche, ein „Erkennen“-Button und ein Label in dem das Resultat stehen wird. Man konnte so eine Zahl oder einen Operator zeichnen und dieser wurde dann ins Label geschrieben.
Dann habe ich noch einen „Berechnen“-Button hinzugefügt. Wenn dieser gedrückt wurde, wurde die Rechnung im Label ausgerechnet und das Resultat ausgegeben.
Die erste Version hat zwar funktioniert, war aber das Programm war weder genau bei der Erkennung, noch besonders performant, noch besonders nutzerfreundlich. Deshalb wollte ich einige Änderungen vornehmen. Ich habe herausgefunden, dass ich mit Vision nicht nur die Bilder klassifizieren kann, sondern auf deutlich mehr. Vision kann erkennen, wo in einem Bild Texte sind und wo die einzelnen Buchstaben sind (siehe Bild unten).
vision-example Somit konnte man alle Zahlen direkt nacheinander schreiben ohne warten zu müssen oder einen Button drücken zu müssen. Leider funktionierte Vision nur in ungefähr 70% der Fälle. Am meisten Probleme hatte Vision bei kurzen Texten wie z.B. 3+5. Deshalb musste ich diese Idee wieder verwerfen.
Meine nächste Idee war, den Nutzer nach jedem Zeichen kurz warten zu lassen, bis das Zeichen erkennt wurde. Wenn es ein Gleichheitszeichen ist, sollte die Rechnung ausrechnet werden. Nachdem ich diese Idee umgesetzt habe, konnte man ganze Rechnungen mit Zahlen und Operatoren zeichnen, man musste nur zwischen den Zeichen kurz warten. Da ich an diesem Projekt alleine arbeite, habe ich auch nicht sehr viele Daten zur Verfügung. Deshalb musste ich alle Trainingsdaten selbst zeichnen. Dies führte dazu, dass die Genauigkeit der Erkennung nicht sehr hoch war (mehr dazu ist im Abschnitt „Probleme“ zu finden).
Ich habe herausgefunden, dass die Genauigkeit stark anstieg, wenn ich die Operatoren entfernte, dies habe ich auch getan. Nun muss man die Operatoren über einen Button eingeben.
Die Performance war aber immer noch ziemlich schlecht. Nach einigen Anpassungen bei der Bildverarbeitung und der Verwendung von mehreren Threads war die Performance sehr gut.

Funktionsweise des Programms

VIDEO

Meine Trainingsdaten (ca. 5000 Bilder) sind auf meinem Mac. Mit CreateML erstelle ich dann das MLModel (Dateiformat der Machine Learning Models). Dann teste ich die Genauigkeit mit einigen anderen Bildern um den Fortschritt zu sehen. Danach ziehe ich mein MLModel in das eigentliche Projekt.

Wenn man das Programm startet, erscheint die Ansicht, welche rechts zu sehen ist. Das grosse Feld, ist der Zeichnungsbereich, rechts sind verschiedene Buttons und unten ist das Label mit der Rechnung.

Wenn man nun eine Zahl zeichnet, wird dieses an das Model gesendet. Nur kurze Zeit später ist die Erkennung abgeschlossen, das Gezeichnete wird grün und das Resultat steht unten.

Wie die Erkennung funktioniert

Mein MLModel habe ich bereits erstellt, dieses lade ich als VNCoreMLModel. Sobald man aufhört zu zeichnen, wird das Gezeichnete mit der Funktion UIGraphicsGetImageFromCurrentImageContext() in ein Bild umgewandelt und einer anderen Funktion mitgegeben. Dort wird ein VNCoreMLRequest mit meinem MLModel und dem completionHandler (was ausgeführt wird, sobald die Funktion abgeschlossen wurde) erstellt. Ausserdem wird noch ein VNImageRequestHandler mit dem Bild erstellt.  Mit diesem VNImageRequestHandler kann man einen VNCoreMLRequest für ein einzelnes Bild ausführen. Dann wird der Request mit handler.perform([request]) ausgeführt. Nun wird die Funktion, welche im completionHandler festgelegt ist, ausgeführt. Dabei wird das Resultat und die Confidence (wie sicher sich der Algorithmus ist, dass die Antwort stimmt) mitgegeben. In dieser Funktion werden die Resultate ausgelesen und ausgegeben. Wenn die Confidence unter 60% liegt, erscheint ein Alert mit den zwei wahrscheinlichsten Zahlen. Danach wird die Zahl in das Label geschrieben und man kann die nächste Zahl zeichnen.

Probleme

Genauigkeit der Erkennung ist tief

Um dieses Problem zu lösen, werden mehr Trainingsbilder benötigt. Ich habe mehrmals während dem Trainingsprozess, die Genauigkeit gemessen und bin zu folgenden Ergebnissen gekommen:

Screenshot-2019-05-28-at-11.36.23

Wie man sehen kann, beträgt der Unterschied in der Genauigkeit zwischen 2750 und 5000 Trainingsbildern weniger als 1.5%. Daraus kann man schliessen, dass es sich nicht sehr lohnt, noch mehr Bilder zu verwenden.

Da es die meisten Verwechslungen zwischen den Operatoren und den Zahlen gab, habe ich zum Test die Operatoren entfernt und die Ergebnisse waren deutlich besser. Zu den meisten Verwechslungen kommt es zwischen 0 & 9, 1 & 2, 1 & 7, 2 & 3, 4 & 7, 4 & 9.

Zusätzlich habe ich noch eine Funktion hinzugefügt, dass ein Alert erscheint, wenn sich das Programm nicht sicher ist, welche Zahl gezeichnet wurde.

Model wird auf iOS nicht geladen

Ich habe mein Projekt immer im Simulator getestet und dies hat auch funktioniert. Als ich das Projekt dann auf einem iPad starten wollte, konnte das Model nicht geladen werden. Im Internet habe ich dann erfahren, dass auf Mac das Model beim Ausführen des Projekts automatisch kompiliert will. Dies geschieht auf iOS aber nicht.

Zum Glück gibt es die MLModel.compileModel(at: URL) Methode, mit der ich ohne grosse Probleme, das Model kompilieren kann.

Das Projekt
Das gesamte Projekt ist auf GitHub: github.com/adamgiesinger/wwdc-2019-scholarship

Fazit
Ich hatte bei diesem Projekt sehr viel Spass und ich habe viel Neues gelernt. Schlussendlich wurde meine Einreichung sogar angenommen und nun kann ich vom 3. bis zum 7. Juni in San José live an der WWDC dabei sein. 🎉
Ich würde jeder interessierten Person empfehlen, sich ebenfalls zu bewerben, da es eine tolle Sache ist!

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*

*

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>