Machine Learning mit Apache Spark 2

Neuronale Netze & Fazit

Klassifizieren mit Neuronen

Neuronale Netze sind die Stars des maschinellen Lernens und erleben nach einem Hype in den 1990er-Jahren ihren zweiten Frühling. Biologische Nervenzellen lieferten bereits in den 1960ern die Grundidee für das mathematische Modell. Eine detaillierte Einführung findet sich auf den Seiten zu Deep Learning bei der Stanford University.

Zeitgemäße Hardware erlaubt das Training immer größerer Netze. Zusätzlich haben Forscher in den letzten Jahren neue Netzstrukturen für Spezialaufgaben erforscht. Einen schönen Überblick liefert der "Neuronal Netzwerk Zoo" des Asimov-Instituts.

Spark bietet einen Multilayer Perceptron Classifier (MLPC), der ein Feedforward Artificial Neural Network (FANN) erzeugt, bei dem sich jedes Neuron mit allen Neuronen der davor liegenden Schicht verbindet. Das Verfahren nutzt Back Propagation als Lernmethode, die die Abweichungen zwischen Ergebnis der Ausgabeneuronen und der Erwartungswerte ermittelt. Die Differenzen definieren die Stärke der Veränderungen an den Gewichten zwischen den Neuronen. Die Details finden sich in der Spark-Dokumentation.

Der Klassifizierer erwartet als Parameter die Struktur des Netzes. Das Beispiel nutzt vier Ebenen: In der ersten entsprechen die 784 Neuronen dem Eingabevektor. Es folgen zwei versteckte Schichten mit 800 und 100 Neuronen. Die Ausgabeschicht enthält 10 Neuronen für die gesuchten Klassen:

int[] layers = { 784, 800, 100, 10 };
MultilayerPerceptronClassifier mlpc = new MultilayerPerceptronClassifier()
.setLabelCol(stringIndexer.getOutputCol())
.setFeaturesCol(assembler.getOutputCol())
.setLayers(layers);

Nach dem Start fällt die deutlich längere Laufzeit von 33 Minuten auf. Das Ergebnisse verbessert sich leicht auf 96,7 Prozent.

Ansätze zur Optimierung

Um den Prozess zu verbessern, können Entwickler den Kontrast erhöhen. Aus dem Spark-Fundus bietet sich hierfür der Binarizer an, der die Pixel an dem Grenzwert 127,5 scharf in schwarze oder weiße Punkte trennt. Für die Pipeline ergibt sich ein neuer Schritt zwischen VectorAssembler und Classifier. Die Eingabespalte des Classifier ist damit die Ausgabe des Binarizer:

  Binarizer binarizer = new Binarizer()
.setInputCol("features")
.setOutputCol("bin_features")
.setThreshold(127.5);
  MultilayerPerceptronClassifier mlpc = 
new MultilayerPerceptronClassifier()
.setLabelCol(stringIndexer.getOutputCol())
.setFeaturesCol(binarizer.getOutputCol())
.setLayers(layers);
  Pipeline pipeline = new Pipeline()
.setStages(new PipelineStage[] {assembler
, stringIndexer
, binarizer
, mlpc
, indexToString
});

Der Einsatz des Binarizer verbessert die Erkennung leider nicht (96,5 %). Er reduziert dafür die Trainingsdauer erheblich um 20 Prozent (6 Minuten). Erst eine eine geschicktere Wahl der Werte für die Anzahl der Iteration und der Toleranz erhöht die Erkennungsleistung: Eine geringe Toleranz führt zu exakten Ergebnissen zum Preis von mehr Iterationen im Training. Die maximale Anzahl der Iterationen begrenzt die Laufzeit des Trainings:

  MultilayerPerceptronClassifier mlpc = 
new MultilayerPerceptronClassifier()
.setLabelCol(stringIndexer.getOutputCol())
.setFeaturesCol(binarizer.getOutputCol())
.setLayers(layers)
.setMaxIter(1000) //default 100
.setTol(1e-7); //default 1e-6

Die neuen Einstellungen verbessern die Erkennung auf 97,8 Prozent mit dem Preis, dass die Rechenzeit auf über eine Stunde steigt:

Label 0 1 2 3 4 5 6 7 8 9
0 970 1 3 2 2 1 1
1 1128 1 1 1 3 1
2 5 1 1003 6 2 1 3 6 5
3 4 987 7 1 4 3 4
4 1 2 958 5 4 12
5 3 1 6 3 869 2 1 4 3
6 4 3 3 7 4 936 1
7 3 6 3 1 1009 6
8 2 1 3 6 4 4 1 4 945 4
9 3 4 10 3 3 6 5 975

Eine höhere Anzahl von Schichten und von Neuronen je Schicht könnten die Leistung weiter steigern. Manche Veröffentlichungen zu der Aufgabenstellung schlagen vor, die Trainingsdaten um leicht gedrehte Bilder zu erweitern. Das lässt sich mit Spark als Affine-Transformationen realisieren.

Ausblick und Fazit

Maschinelles Lernen hat das Potenzial zu einem bestimmenden Trend der nächsten Jahre zu werden. Der Bedarf ist vorhanden, und die Techniken sind bereit für den professionellen Einsatz.

Die größten Herausforderungen eines Projekts im Bereich maschinelles Lernen liegen im Beschaffen und Aufbereiten von Trainingsdaten sowie der Wahl eines Algorithmus für eine konkrete Aufgabenstellung. Leider ist die Wirkung von Parametern im Detail oft nur dürftig dokumentiert. Manchmal hilft ein Blick in den Quellcode, oft bleibt nur eigenes Experimentieren.

Etwas Hilfestellung gibt ein sogenanntes Cheatsheet von Microsoft, das einige Algorithmen und ihre typischen Einsatzmöglichkeiten aufzeigt.

Werkzeuge wie Apache Spark erleichtern den Einstieg – die Vielfalt der vorhanden Algorithmen und Hilfsklassen ist beeindruckend. Das Pipeline-Konzept überzeugt bei der Umsetzung wiederverwendbaren Abläufe und Modelle im produktiven Einsatz. Das Verteilen von Berechnungen auf einem Cluster erlaubt das Erstellen komplexer Modelle. (rme)

Heiko Spindler
ist freiberuflicher Softwarearchitekt, Entwickler und Scrum Master. Er ist Dozent, schreibt Artikel und spricht regelmäßig auf Fachkonferenzen. 2014 erschien sein Buch "Single-Page-Web-Apps" im Franzis Verlag.

Literatur:

[1] Kahneman, Daniel; Schnelles Denken, langsames Denken; Penguin Verlag 2016