Einstieg in Neuronale Netze mit TensorFlow und Keras
Aus der Toolbox des Data Scientists sind sie nicht mehr wegzudenken: Neuronale Netze finden zunehmend überall dort Verbreitung, wo aus Daten Vorhersagen gemacht werden sollen. Ihre Innovation ist einfach beschrieben, aber schwer vorstellbar: Neuronale Netze modellieren Prozesse, die über das menschliche Verständnis hinausgehen. Mit TensorFlow existiert ein attraktives Open Source Framework zur Implementierung mit vielen guten Argumenten: Steuerung über eine Python-Library, eine High Level API (Keras) für viele verbreitete Anwendungsfälle, eine Low Level API für Detailverliebte, eine aktive Community und Unterstützung durch Google. In diesem Blogpost geben wir eine kurze Einführung in die Theorie Neuronaler Netze mit Beispielen in der TensorFlow API Keras.
Architektur Neuronaler Netze
Neuronale Netze sind Algorithmen zur Verarbeitung numerischer Information, die konzeptuell der neuronalen Funktion des menschlichen Gehirns nachempfunden sind. Der grundlegende Aufbau ist immer gleich: Input-Daten (Features) werden über Hidden Layers verarbeitet und auf einen Output (Vorhersage) projiziert.
Der Input kann fast beliebig komplex werden, muss aber immer numerisch sein. Datentypen wie Text oder Bilder müssen erst in numerische Daten transformiert werden.
Der Output muss ebenfalls numerisch sein, ist aber in der Regel weniger komplex. Beispiele sind ein einfacher Skalar wie beispielsweise Netzwerkauslastung oder eine binär kodierte Kategorie, etwa ob ein Kunde ein Produkt kauft oder nicht.
In dem Hidden Layer steckt die eigentliche Funktionalität des Neuronalen Netzes. Die Werte in den Input-Neuronen (X1, …, Xn) werden mit Gewichten multipliziert und an Neuronen des ersten Hidden Layer weitergegeben (h1, …, hn). Über das Durchprobieren verschiedener Gewichte wird später das Modell optimiert. Dabei kann jedes Input-Neuron auf jedes Neuron des ersten Hidden Layer projizieren. In der Abbildung kommen für eine Beobachtung fünf Werte in jedem Neuron des Hidden Layer an. Diese werden pro Neuron aufsummiert und bilden die Aktivierung. In aller Regel wird die Summe zusätzlich durch eine Aktivierungsfunktion verarbeitet, die zum Beispiel für Werte über einem Cut Off 1 und sonst 0 ausgibt. Diese Art Aktivierungsfunktion würde der neuronalen Struktur des menschlichen Gehirns entsprechen, wo ein Neuron entweder feuert oder nicht feuert. In der Praxis werden – je nach Anwendungsfall – auch andere Aktivierungsfunktionen verwendet.
Dieser Prozess der Weitergabe von Aktivierungen kann beliebig oft wiederholt werden. Durch die Verkettung von Hidden Layers erhält das Neuronale Netz mehr Tiefe und kann nicht-lineare Zusammenhänge besser abbilden. Zum Schluss projizieren die Neuronen des letzten Hidden Layers auf den Output Layer. Hier kann festgelegt werden, welches Format die Vorhersage annehmen soll. Wenn das Modell eine binäre Entscheidung treffen soll, wählt man nur ein Neuron im Output Layer und eine Aktivierungsfunktion des letzten Hidden Layers, die nur zwei Funktionswerte annehmen kann.
Trainieren des Modells
Zur Optimierung des Modells wird die Güte der Vorhersage überprüft. Neuronale Netze arbeiten mit Trainingsdaten, bei denen der Output bekannt ist ("labeled data"). Es liegen also Beobachtungen für den Output vor. Diese Beobachtungen werden mit den Vorhersagen des Modells über eine Loss Funktion verglichen. Die Verbesserung des Modells geschieht über die Gewichte, mit denen die Aktivierung der Neuronen multipliziert wird. Ein Optimizer schlägt bessere Gewichte vor und die Loss Funktion wird erneut berechnet. Dieser Prozess wird solange wiederholt, bis eine maximale Zahl an Iterationen ("Epochen") erreicht ist oder sich der Loss nicht mehr signifikant ändert. Das trainierte Modell kann nun zur Vorhersage unbekannter Daten verwendet werden.
Neuronale Netze in TensorFlow und Keras
TensorFlow ist eine Software-Bibliothek, die mathematische Operationen zum Trainieren neuronaler Netze graphenbasiert abbildet und deren Berechnung effizient in Python und C++ umsetzt. TensorFlow wurde in Google's Deep-Learning-Abteilung Google Brain zunächst intern entwickelt und 2015 unter der Apache-Lizenz 2.0 als Open Source Projekt veröffentlicht. Es bietet stabile API's für Python und C, early releases für C++, Go, Java, JavaScript and Swift, sowie third-party packages unter anderem für C#, R und Scala. Tensorflow unterstützt parallele Verarbeitung auf CPUs und GPUs. In 2018 hat Google die Entwicklung dedizierter Chipsätze für TensorFlow-Applikationen angekündigt (Edge TPU).
Keras ist eine Python-Bibliothek, die eine high-level Beschreibung Neuronaler Netze ermöglicht und verschiedene Frameworks zur Implementierung unterstützt (TensorFlow, Microsoft Cognitive Toolkit, Theano, PlaidML). Der Fokus liegt dabei auf Nutzerfreundlichkeit, Modularität und Erweiterbarkeit. So können die einzelnen Bausteine neuronaler Netze (Ebenen, Aktivierungsfunktionen, Optimizer, etc.) separat festgelegt und in einem Pipeline Interface zu einem Gesamtmodel zusammengefügt werden.
Beispiel: Implementierung in Keras
Das Modell aus Abbildung 1 soll nun in über Keras in TensorFlow implementiert werden. Als Beispiel verwenden wir den Titanic Datensatz.
Wir wollen vorhersagen, ob ein Passagier den Untergang der Titanic überlebt hat (Überlebt = 1) oder nicht (Überlebt = 0). Die Variable "Überlebt" ist also die Zielvariable bzw. der Output. Alle anderen Variablen sind potentielle Features. Zunächst müssen die Variablen in ein numerisches Format übertragen werden. "Name" und "Kabine" lassen sich nicht sinnvoll numerisch kodieren und können deshalb nicht berücksichtigt werden. "Geschlecht" und "Zugestiegen" werden binär kodiert. Außerdem müssen alle Features über lineare Transformationen auf denselben Wertebereich abgebildet werden, z.B. Minimum = 0 und Maximum = 1:
# Benötigte Imports import tensorflow as tf import pandas as pd from keras.models import Sequential from keras.layers import InputLayer, Dense, Activation from sklearn.preprocessing import MinMaxScaler # Einlesen der Daten data = pd.read_csv('titanic.csv') # Zielvariable (target) und Features (input) auswählen target = data['Ueberlebt'] input = data.drop('Ueberlebt', axis=1, ) # Daten skalieren scaler = MinMaxScaler(feature_range=(0, 1)) scaler.fit(input) input = scaler.transform(input) target = target.values
Der Datensatz ist nun vollständig für die Verarbeitung im Neuronalen Netz aufbereitet und das Modell kann in Keras umgesetzt werden. Dafür wird mit Sequential() ein Container erstellt, in den sequentiell die Ebenen des Modells mit add() angefügt werden. Dabei wird mit name der Name des Layers, mit unit die Anzahl der Neuronen und mit activiation die Aktivierungsfunktion festgelegt.
# Modell erstellen model = Sequential() # Input Layer model.add(InputLayer(name = "InputLayer", input_shape=(5,))) # Hidden Layer model.add(Dense(units=10, name = "HiddenLayer1", activation="relu")) model.add(Dense(units=5, name = "HiddenLayer2", activation="relu")) # Output Layer model.add(Dense(units=1, name = "OutputLayer", activation="sigmoid"))
Jetzt kann das Modell trainiert werden. Mit compile() werden der Optimizer, die Loss Funktion und zusätzliche deskriptive Metriken konfiguriert. Mit fit() werden dem Modell die Input- und Zieldaten für das Training übergeben und mit epochs die Anzahl der Iterationen festgelegt.
# Modell konfigurieren model.compile(optimizer="adam", loss="binary_crossentropy", metrics=["accuracy"]) # Modell trainieren model.fit(x = input, y = target, epochs = 50)
Man kann nachvollziehen, wie über die Iterationen die Loss Funktion minimiert wird und die Accuracy (acc, Anteil richtiger Klassifikationen) zunimmt. Nach 100 Iterationen trifft das Modell für das Überleben von 80 Prozent der Passagiere die richtige Vorhersage.
Über predict() können mit dem Modell Vorhersagen für zukünftige oder hypothetische Daten gemacht werden. Für einen Mann sagt das Modell niedrigere Überlebenschancen vorher als für eine Frau und für einen Passagier der ersten Klasse sagt es eine höhere Überlebenschance vorher als für einen Passagier der dritten Klasse.
import numpy as np hypMann = [0, 1, 0.7, 0.9, 1] hypFrau = [0, 0, 0.7, 0.9, 1] model.predict(np.array([hypMann, hypFrau])) >>> [[0.524] [0.962]] hypKlasse1 = [0, 1, 0.7, 0.9, 1] hypKlasse3 = [1, 1, 0.7, 0.1, 1] model.predict(np.array([hypKlasse1, hypKlasse3])) >>> [[0.285] [0.524]]
Einordnung
In diesem Blogpost haben wir ein minimales Beipiel für ein Neuronales Netz mit fünf Input-Variablen und einer binären Output-Variable über Keras in TensorFlow implementiert. Hier ist zu bemerken, dass das vorgestellte minimale Beispiel nicht den optimalen oder typischen Anwendungsfall von neuronalen Netzen widerspiegelt. Zu Illustrationszwecken wurde ein überschaubarer, tabellarischer Datensatz (957 Beobachtungen von 5 Features) mit einem kleinen, einfachen Neuronalen Netz (nur zwei Hidden Layers mit 10 und 5 Neuronen) bearbeitet. In der Praxis werden in der Regel deutlich komplexere neuronale Netze auf größeren, komplexeren Datensätzen trainiert. Die Erweiterungsmöglichkeiten sind vielfältig: Mehr und komplexere Input- und Output-Variablen, mehr Layer mit mehr Neuronen, andere Aktivierungs- und Loss-Funktionen, andere Optimizer und weitere, hier nicht besprochene Konzepte wie Bias, Dropout oder Rekursivität. Zur Implementierung dieser und mehr Methoden ist TensorFlow ein mächtiges Tool, zu dem Keras ein gut zugängliches Interface bietet.
Bei Updates im Blog, informieren wir per E-Mail.
Kommentare