No description has been provided for this image

Machine
Learning

Joern Ploennigs

KΓΌnstliche Neuronale Netzwerke

EvaluationΒΆ

FΓΌllt bitte die Evaluation aus und helft die Vorlesung zu verbessern:

GrundlagenΒΆ

NeuronenΒΆ

Neuronen sind die grundlegenden Bausteine eines neuronalen Netzwerks. Ein Neuron empfΓ€ngt Eingaben, verarbeitet sie und gibt eine Ausgabe weiter. Die Verarbeitung erfolgt durch eine Aktivierungsfunktion $f(\cdot)$, die den linearen Eingang in eine nichtlineare Ausgabe umwandelt. Die Grundstruktur eines Neurons besteht aus mehreren Komponenten: Eingaben (Inputs), Gewichte (Weights), Bias und der Aktivierungsfunktion.

No description has been provided for this image

Die Eingaben $x_1, x_2, ..., x_n$ sind die Signale oder Datenpunkte, die in das Neuron eingespeist werden. Gewichte $w_1, w_2, ..., w_n$ sind Faktoren, die die Bedeutung jedes Eingangs steuern. Der Bias $b$ ist ein zusÀtzlicher Parameter, der den Schwellenwert für die Aktivierung anpasst. Schließlich gibt es die Aktivierungsfunktion $f(\cdot)$, die den Summenwert der gewichteten Eingaben und des Bias in eine Ausgabe umwandelt. Die Ausgabe eines Neurons wird durch die folgende Formel berechnet:

$$ y = f\left(b + \sum_{i=1}^n w_i x_i\right) $$

  • Eingaben (Inputs, $x_1, x_2, ..., x_n$): Signale oder Datenpunkte, die in das Neuron eingespeist werden.
  • Gewichte (Weights, $w_1, w_2, ..., w_n$): Faktoren, die die Bedeutung jedes Eingangs steuern.
  • Bias (Bias, $b$): Ein zusΓ€tzlicher Parameter, der den Schwellenwert fΓΌr die Aktivierung anpasst.
  • Aktivierungsfunktion (Activation Function, $f(\cdot)$): Eine Funktion, die den Summenwert der gewichteten Eingaben und des Bias in eine Ausgabe umwandelt.

Damit gleicht das Neuron in der gleichen Formel einem Generalisierten Linearem Modell (GLM). Bei GLM zielt die Transformationsfunktion $f(\cdot)$ darauf ab, die Verteilung der Ausgangsvariable zu verΓ€ndern.

Die meisten Aktivierungsfunktionen bei KNN zielen darauf ab, das Ausgangssignal entweder klarer zu differenzieren (aktiv/inaktiv) oder nichtlinear zu transformieren , um komplexe ZusammenhΓ€nge zu lernen. Einige gΓ€ngige Aktivierungsfunktionen sind:

  • Sigmoid: Diese Funktion kennen wir von den Logistischen Regression und GLM. Sie transformiert den Eingang in einen Wert zwischen 0 und 1, was sie besonders geeignet fΓΌr die Ausgabe von Wahrscheinlichkeiten macht.

    $$f(x) = (1 + e^{-x})^{-1}.$$

  • ReLU (Rectified Linear Unit): Sie ist eine einfache und hΓ€ufig verwendete Funktion, die den Eingang direkt zurΓΌckgibt, wenn er positiv ist, und ansonsten Null. ReLU ist bekannt dafΓΌr, neuronale Netze schneller und effizienter zu trainieren.

    $$f(x) = \max(0, x).$$

  • Tanh (Hyperbolic Tangent): Diese Funktion transformiert den Eingang in einen Wert zwischen -1 und 1 und ist oft in frΓΌheren Versionen von neuronalen Netzwerken zu finden. Sie kann in Aufgaben nΓΌtzlich sein, bei denen sowohl positive als auch negative Werte relevant sind.

    $$f(x) = \tanh(x).$$

  • Softmax: Die Softmax-Funktion normalisiert die Ausgabe eines Neurons auf eine Wahrscheinlichkeitsverteilung, wobei die Summe aller AusgΓ€nge 1 ergibt. Sie wird hΓ€ufig in mehrstufigen Klassifizierungsaufgaben eingesetzt, wo sie die Wahrscheinlichkeiten aller Klassen gleichzeitig ausgibt.

    $$f(x_i) = e^{-x_i}(\sum_{j}^K e^{x_j})^{-1}.$$

SchichtenΒΆ

Die FΓ€higkeit komplexe ZusammenhΓ€nge zu erlernen, ergibt sich vor allem daraus, dass Neuronale Netzwerke aus mehreren Schichten von Neuronen bestehen, die in einer bestimmten Architektur angeordnet sind.

No description has been provided for this image

TrainingsprozessΒΆ

Der Grund, weshalb Neuronale Netzwerke fast 60 Jahre lang nicht genutzt wurden, lag in Skalierbarkeit des Trainings. Das oben abgebildete Beispiel zeigt bereits, die hohe Anzahl an 25 Parametern (Gewichte und Bias) fΓΌr ein kleines Netzwerk mit vier Schichten. LeistungsfΓ€hige Netze haben bis zu Milliarden an Parametern.

Aufgrund der KomplexitΓ€t kΓΆnnen die Parameter nicht direkt berechnet werden und werden deshalb normalerweise iterativ angenΓ€hert. Dieser Prozess umfasst typischerweise folgende Schritte:

  1. ZufΓ€llige Initialisierung aller Parameter $w$ und $b$ mit Zufallszahlen.
  1. VorwΓ€rtsausbreitung (Forward Propagation): Die Eingabedaten werden durch das Netzwerk geleitet und die Ausgabe geschΓ€tzt. Jedes Neuron berechnet seine Aktivierungsfunktion basierend auf den gewichteten Eingaben und dem Bias mit Hilfe der oben angegeben Formel.
  1. Berechnung des Fehlers (Loss Calculation): Der Fehler oder Verlust wird durch eine Verlustfunktion berechnet, die die Differenz zwischen der vorhergesagten Ausgabe und der tatsΓ€chlichen Ausgabe misst. Die passende Verlustfunktionen richtet sich dabei nach dem Datentyp der Ausgangsvariable. Typische Verlustfunktionen kennen wir bereits:

    • Mean Square Error fΓΌr numerische Daten (siehe Lineare Regression).

    $$E^{\text{MSE}} = \frac{1}{n} \sum_{j=1}^{n}(\hat y_j - y_j)^2$$

    • Kreuzentropie (LogLoss) fΓΌr binΓ€re oder kategorische Daten (siehe Logistische Regression).

    $$E^{\text{LL}} = -\frac{1}{n} \sum_{j=1}^{n} y_j log(\hat y_j)$$

  1. RückwÀrtsausbreitung (Backpropagation): Der Fehler wird durch das Netzwerk rückwÀrts propagiert, um die Gradienten der Verlustfunktion bezüglich der Gewichte und Biases zu berechnen. Dabei wird im Wesentlichen der Fehler rückwÀrts im Netzwerk verteilt, so dass Neuronen, die einen großen Anteil an der Vorhersage haben (also hohe Gewichtung und Bias bei hoher Eingangswert), ein grâßerer Anteil am Fehler zugeteilt wird. Der Gradient $ \nabla {E(w_{ij})} $ des Gewichtes $w_{ij}$ kann mit der Kettenregel berechnet werden:

    $$ \nabla {E(w_{ij})} = \frac{\partial E}{\partial w_{ij}} $$ $$ \nabla {E(b_{i})} = \frac{\partial E}{\partial b_{i}} $$

    Die entsprechende partielle Ableitung richtet sich prinzipiell nach der Aktivierungsfunktion, wird aber meist numerisch bestimmt, wie z.B. bereits bei der Logistischen Regression diskutiert.

  1. Gewichtsaktualisierung (Weight Update): Die Gewichte und Biases werden mithilfe eines Optimierungsalgorithmus wie Gradient Descent oder Adam angepasst, um den Fehler zu minimieren. Beim Gradient Descent geschieht dies durch Anwendung der berechneten Gradienten auf die Gewichte und Biases mit Hilfe der Lernrate $\alpha$:

    $$w_{ij} = w_{ij} - \alpha * \nabla E(w_{ij})$$ $$b_{i} = b_{i} - \alpha * \nabla E(b_{i})$$

  1. Abbruchkriterium: Wiederholung der Schritte 2.-5. bis ein Konvergenzkriteriums erfΓΌllt wurde oder eine maximale Anzahl an Iterationen erreicht wird.

Der Trainingsprozess wird in der Regel ΓΌber mehrere Epochen wiederholt, wobei jede Epoche eine DurchfΓΌhrung des gesamten Trainingsdatensatzes darstellt. Dies ermΓΆglicht es dem Netzwerk, die Gewichte iterativ zu verbessern und seine Leistung auf neuen Daten zu generalisieren. Ein entscheidender Grund fΓΌr den heutigen Erfolg von Neuronalen Netzwerken ist, dass diese Berechnung der Gewichte hoch parallelisierbar ist und somit sehr gut auf modernen Graphikkarten parallelisiert werden kΓΆnnen.

Ein hΓ€ufiges Problem beim Training neuronaler Netzwerke ist Overfitting, bei dem das Netzwerk die Trainingsdaten zu gut lernt und auf neuen Daten schlecht generalisiert. Um Overfitting zu vermeiden und die Leistung des Netzwerks zu verbessern, werden verschiedene Techniken der Regularisierung eingesetzt:

  • Regularisierung (z.B. L1, L2): HinzufΓΌgen eines Regularisierungsterms zur Verlustfunktion, um die KomplexitΓ€t des Modells zu kontrollieren.
  • Dropout: ZufΓ€lliges Ausschalten von Neuronen wΓ€hrend des Trainings, um die AbhΓ€ngigkeit von bestimmten Neuronen zu reduzieren.
  • Datenaugmentation: Erweiterung des Trainingsdatensatzes durch zufΓ€llige Transformationen der Daten.

ArchitekturenΒΆ

VorwΓ€rtsgerichtete NetzeΒΆ

Die einfachsten Formen neuronaler Netzwerke sind VorwÀrtsgerichtete Neuronale Netze (FNN - Feedforward Neural Networks). Bei ihnen fließen die Daten in eine Richtung von der Eingabeschicht zur Ausgabeschicht, ohne rückwÀrts gerichtete Datenflüsse. Sie entsprechen den oben dargestellten Netzwerken. Sie sind besonders geeignet bei einfachen Problemen, wo keine Autokorrelation oder komplexe Muster vorherrschen.

No description has been provided for this image

Rekurrente NetzeΒΆ

Rekurrente oder rΓΌckgekoppelte Neuronale Netze (RNN - Recurrent Neural Networks) sind neuronalen Netzen, die sich von Feedforward-Netzen dadurch unterscheiden, dass sie Verbindungen zwischen Neuronen einer Schicht zu Neuronen derselben oder vorheriger Schichten ermΓΆglichen. Diese Art der Verschaltung Γ€hnelt der bevorzugten Struktur neuronaler Netze im Gehirn, insbesondere im Neocortex. RNNs sind ideal fΓΌr sequenzielle Daten wie Zeitreihen oder Text, da sie ΓΌber Schleifen verfΓΌgen, die Informationen ΓΌber Zeitpunkte (oder Wortfolgen/SΓ€tze) hinweg speichern. Dadurch lΓ€sst sich z.B. gut die Autoregression in Zeitreihen oder komplette SΓ€tze erlernen.

$$ y_j = f\left(b + \sum_{i=1}^n w_{i,j} x_{i,j} + v y_{j-1} \right) $$

No description has been provided for this image

FaltungsnetzeΒΆ

Faltungsnetze (CNN - Convolutional Neural Networks) sind besonders effektiv bei der Verarbeitung von hΓΆherdimensionalen Daten wie Bilddaten oder geospatialer Daten. Sie verwenden Faltungsoperationen, um Merkmale (Kanten, Reliefs, Muster, etc.) aus Eingabebildern zu extrahieren oder zu erlernen und gleichzeitig einen hΓΆherendimensionalen Eingang auf einen niedrigdimensionaleren Ausgang zu reduzieren, der diese Merkmale encodiert. Dadurch reprΓ€sentiert der Ausgang nur die Relevanz des extrahierten oder gelernten Merkmals und es muss nicht das Gesamtbild gelernt werden. Durch Schichtung mehrere versteckter Faltungsschichten hintereinander werden so zuerst Merkmale extrahiert und dann Muster dieser im Bild gelernt (z.B. die Form eines Hundes). Auf die Faltung und die Bildverarbeitung werden wir im Nachfolgekurs "Maschinelles Lernen und KΓΌnstliche Intelligenz" noch vertieft eingehen.

No description has been provided for this image

Neuronale Netzwerke in PythonΒΆ

Neuronale Netzwerke in sklearnΒΆ

Wir demonstrieren neuronale Netzwerke anhand einer erweiterten Version des Yin-Yang-Beispiels aus der Klassifikation indem wir die Anzahl der Farben auf 4 Kategorien und die Verwirbelung erhΓΆhen. Wieder besteht die Aufgabe darin, die richtige Farbe basierend auf dem Punkt vorherzusagen, also eine Klassifikationsaufgabe. Wir erstellen die Daten wie folgt:

InΒ [1]:
import numpy as np # Import von NumPy
import pandas as pd # Import von Pandas
import plotly.express as px # Import von Plotly
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split

np.random.seed(33)
N = 1000  # Anzahl der Punkte
X1 = np.random.normal(size=N)
X2 = np.random.normal(size=N)
X = np.column_stack((X1, X2))

alpha = np.arctan2(X2, X1)
r = np.sqrt(X1**2 + X2**2)

## Teile the sum of a sin and cosine into 5 intervals
category = pd.cut(np.sin(3*alpha + 2*r) + np.cos(3*alpha + 2*r),
           bins=[-1.5, -1.1, -0.6, 0.6, 1.1, 1.5],
           labels=[0, 1, 2, 3, 4])
y = category.astype(int)

# Teile in Test und Trainings-Datensatz
X_train, X_test, y_train, y_test = train_test_split(X, y)
InΒ [2]:
# Darstellung des Datensatzes
fig=px.scatter(x=X2, y=X1, color=y, width=600, height=600)
fig.update_traces(marker_line=dict(width=.3, color="black"))
fig.show()

Das Bild zeigt ein komplexes Muster von Spiralarmen in fünf verschiedenen Farben. Dreiarmige gelbe und blauen Arme entsprechen den grâßten und kleinsten Werten, wÀhrend sechsarmige Arme in verschiedenen Rot- und Violetttânen den dazwischen liegenden Werten entsprechen. Diese Entscheidungsgrenzen sind sehr schwer mit einfachen Modellen wie logistischer Regression, SVM oder sogar BÀumen zu erfassen. Prüfen wir das noch einmal mit einer kleinen Visualisierungsfunktion, die wir auch in der Klassifikation genutzt haben.

Testen wir einen Random Forest, so erhalten wir zwar ein gutes Modell, dass allerdings overfittet und schlecht generalisiert.

InΒ [4]:
from sklearn.ensemble import RandomForestClassifier

m = RandomForestClassifier()
_ = m.fit(X_train, y_train)
m.score(X_test, y_test)
Out[4]:
0.772
InΒ [5]:
confusion_matrix(y_test, m.predict(X_test))
Out[5]:
array([[52,  0,  2,  0,  0],
       [10, 19,  5,  0,  0],
       [ 4,  7, 50,  9,  0],
       [ 0,  0, 10, 24,  4],
       [ 0,  0,  3,  3, 48]])
InΒ [6]:
DBPlot(m, X_test, y_test)

Ein SVM mit radialem Kernel erkennt die Struktur besser, aber hat einen deutlich hΓΆheren Fehler.

InΒ [7]:
from sklearn.svm import SVC

m = SVC(kernel="rbf", gamma=1)
_ = m.fit(X_train, y_train)
m.score(X_test, y_test)
Out[7]:
0.544
InΒ [8]:
confusion_matrix(y_test, m.predict(X_test))
Out[8]:
array([[43,  0, 11,  0,  0],
       [19,  0, 15,  0,  0],
       [11,  0, 52,  0,  7],
       [ 1,  0, 11,  0, 26],
       [ 3,  0, 10,  0, 41]])
InΒ [9]:
DBPlot(m, X_test, y_test)

Allerdings kΓΆnnen neuronale Netzwerke (und k-NN) deutlich besser damit umgehen.

sklearn implementiert einfache Feed-Forward-Neuronale Netzwerke, so genannte Multi-Layer Perceptrons. Dies sind einfache dichte Feed-Forward-Netzwerke mit einer beliebigen Anzahl von versteckten Schichten. Auch wenn sie strukturell einfache neuronaler Netzwerke sind, sind sie dennoch leistungsfΓ€hig genug fΓΌr viele Aufgaben.

Wie bei anderen fortgeschrittenen Modellen bietet sklearn zwei unterschiedlichen Klassen fΓΌr Klassifikationsaufgaben MLPClassifier und fΓΌr Regressionsaufgaben MLPRegressor. Die grundlegende Verwendung dieser Modelle ist identisch zu den anderen sklearn-Modellen.

Die wichtigsten Argumente fΓΌr den MLPClassifier sind:

MLPClassifier(hidden_layer_sizes, activation, max_iter, alpha)

Von diesen ist hidden_layer_sizes der zentralste. Dies beschreibt die Anzahl der versteckten Schichten (die Grâße der Eingabe- und Ausgabeschicht wird automatisch aus den Daten bestimmt). Es handelt sich um ein Tupel, das die Anzahl der Knoten für jede versteckte Schicht angibt, daher gibt die LÀnge des Tupels auch die Anzahl der versteckten Schichten an. Zum Beispiel bedeutet hidden_layer_sizes = (32, 16) zwei versteckte Schichten, die erste mit 32 und die folgende mit 16 Knoten. activation beschreibt die Aktivierungsfunktion. Es empfiehlt sich meist es bei der Standardfunktion relu zu lassen, außer es gibt die oben beschriebenen Gründe für andere Aktivierungsfunktionen. alpha ist der L2-Regularisierungsparameter und max_iter gibt die maximale Anzahl von Iterationen an, bevor die Optimierung stoppt.

Lassen Sie uns nun die Verwendung von MLPClassifier an den Yin-Yang Beispiel demonstrieren. Beginnen wir mit einem einfachen Perzeptron mit einer einzigen versteckten Schicht von 20 Knoten. Daher verwenden wir hidden_layer_sizes=(20,), ein Tupel mit nur einer Zahl. Das Anpassen des Modells und die Vorhersage sind grâßtenteils Àhnlich wie bei den anderen sklearn-Funktionen, daher diskutieren wir dies hier nicht. Wir erhâhen auch die Anzahl der Iterationen, da die Standardanzahl von 200 in diesem Fall zu gering ist:

InΒ [10]:
from sklearn.neural_network import MLPClassifier

m = MLPClassifier(hidden_layer_sizes = (20,), max_iter=10000)
_ = m.fit(X_train, y_train)
m.score(X_test, y_test)
Out[10]:
0.408
InΒ [11]:
confusion_matrix(y_test, m.predict(X_test))
Out[11]:
array([[35,  1, 14,  0,  4],
       [16,  4, 10,  0,  4],
       [19,  1, 24,  0, 26],
       [ 2,  0, 17,  0, 19],
       [ 1,  0, 14,  0, 39]])
InΒ [12]:
DBPlot(m, X_test, y_test)

Dieses einfache Modell hat zuerst auch nur eine niedrige Genauigkeit. Das liegt daran, dass es zu einfach ist, nur eine einzelne kleine versteckte Schicht reicht nicht aus, um das komplexe Spiralmuster gut zu modellieren. Was sich gut in der Visualisierung erkennen lΓ€sst. Wir kΓΆnnen dort sehen, dass das Modell die Idee korrekt einfΓ€ngt: Spiralen in verschiedenen Farben, aber die Form der Spiralen ist nicht genau genug.

Lassen Sie uns das Modell mit einem leistungsstΓ€rkeren Netzwerk wiederholen:

InΒ [13]:
m = MLPClassifier(hidden_layer_sizes = (256, 128, 64), max_iter=10000)
_ = m.fit(X_train, y_train)
m.score(X_test, y_test)
Out[13]:
0.892
InΒ [14]:
confusion_matrix(y_test, m.predict(X_test))
Out[14]:
array([[49,  3,  2,  0,  0],
       [ 5, 26,  3,  0,  0],
       [ 1,  3, 61,  5,  0],
       [ 0,  0,  2, 35,  1],
       [ 0,  0,  0,  2, 52]])
InΒ [15]:
DBPlot(m, X_test, y_test)

Jetzt sind die Ergebnisse sehr gut mit einer Genauigkeit von ca. 95 %. Die visuelle Inspektion bestΓ€tigt, dass das leistungsstΓ€rkere neuronale Netzwerk die Gesamtstruktur des Modells gut erfassen kann.

Die angepassten Netzwerkmodelle haben verschiedene Methoden und Attribute, z.B. gibt coefs_ die Modellgewichte aus (als Liste von Gewichtsmatrizen, eine fΓΌr jede Schicht), und intercepts_ gibt die Modell-Biaswerte aus (als Liste von Bias-Vektoren, einer fΓΌr jede Schicht). Zum Beispiel enthΓ€lt das oben angepasste Modell

InΒ [16]:
np.sum([b.size for b in m.intercepts_])
Out[16]:
453

Bias.

WΓ€hrend sklearn einen einfachen Zugang zu neuronalen Netzwerkmodellen bietet, sind diese Modelle erheblich eingeschrΓ€nkt. FΓΌr leistungsstΓ€rkere Netzwerke muss man andere Bibliotheken wie tensorflow oder pytorch verwenden.

Neuronale Netzwerke in KerasΒΆ

Tensorflow and KerasΒΆ

Tensorflow ist eine Bibliothek, die Berechnungsgraphen implementiert, die automatisch Gradienten berechnen kânnen. Sie ermâglicht auch Berechnungen auf der GPU durchzuführen, was potenziell zu erheblichen Geschwindigkeitsverbesserungen gegenüber CPU-Berechnungen führen kann. In vielerlei Hinsicht Àhnelt sie numpy, wo man Matrizen und Tensoren erstellen und manipulieren kann. Allerdings ist sie aufgrund des Berechnungsgraphen-Ansatzes und der GPU-bezogenen Überlegungen viel schwieriger zu verwenden.

Keras ist ein TensorFlow-Front-End, ein Submodul, das einen viel benutzerfreundlicheren Zugang zum Aufbau neuronaler Netzwerke bietet. Die FunktionalitΓ€t umfasst eine Vielzahl von Netzwerkschichten, bei denen man die entsprechenden Parameter anpassen kann. Beim Aufbau des Netzwerks kann man einfach die Schichten hintereinander hinzufΓΌgen, die Verbindung zwischen den Schichten wird von Keras selbst ΓΌbernommen. Eine gute Quelle fΓΌr die Keras-Dokumentation ist die API-Referenzdokumentation.

Beispielnetzwerk in kerasΒΆ

Lassen Sie uns das Farbspiralbeispiel aus dem letzten Abschnitt von sklearn neu implementieren, diesmal jedoch mit keras. Es wird einige bemerkenswerte Unterschiede geben:

Der Aufbau des Netzwerks selbst ist in Keras anders. Keras berechnet nicht die Grâße der Eingabe- und Ausgangsschichten aus den Daten. Beide müssen vom Benutzer angegeben werden. Schließlich sagt Keras nur Wahrscheinlichkeiten für alle Kategorien voraus, daher müssen wir Code hinzufügen, der die Spalte (Kategorie) mit der hâchsten Wahrscheinlichkeit findet.

Das Modell erzeugenΒΆ

Zuerst der wichtigste Schritt: Aufbau und Kompilierung des Modells. Dies unterscheidet sich sehr von der Vorgehensweise in sklearn. Lassen Sie uns ein sequentielles Modell mit dichten Schichten aufbauen, die gleiche Architektur, die wir mit sklearn erstellt haben:

InΒ [17]:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# sequential (not recursive) model (one input, one output)
model=Sequential()
model.add(Dense(512, activation="relu", input_shape=(2,)))
model.add(Dense(256, activation="relu"))
model.add(Dense(64, activation="relu"))
nCategories = len(np.unique(category))
model.add(Dense(nCategories, activation="softmax"))
/opt/miniconda3/envs/lehre4/lib/python3.12/site-packages/keras/src/layers/core/dense.py:87: UserWarning:

Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.

Das richtige Festlegen der Eingabeformen und Ausgabeknoten ist eine der Hauptursachen fΓΌr Frustration, wenn man anfΓ€ngt, mit keras zu arbeiten. Die Fehlermeldungen sind lang und nicht besonders hilfreich, und es ist schwer zu verstehen, was das Problem ist. Hier ist eine Checkliste, die durchgearbeitet werden kann, wenn etwas nicht funktioniert:

  • EnthΓ€lt die erste (und nur die erste) Schicht das Argument input_shape?
  • Stellt input_shape korrekt die Form einer einzelnen Instanz der Eingabedaten dar?
  • Haben Sie die richtige Anzahl von Knoten in der Softmax-aktivierten Ausgangsschicht?

Training des ModellsΒΆ

Die nΓ€chste Aufgabe besteht darin, das Modell zu kompilieren und anzupassen. Keras-Modelle mΓΌssen kompiliert werden - was wir bisher eingerichtet haben, ist nur eine Beschreibung des Modells, nicht das tatsΓ€chliche Modell, das fΓΌr TensorFlow-Tensoren eingerichtet ist und mΓΆglicherweise fΓΌr die GPU-AusfΓΌhrung. Wir kΓΆnnen das Modell wie folgt kompilieren:

InΒ [18]:
model.compile(loss='sparse_categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])
print(model.summary())
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┑━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
β”‚ dense (Dense)                   β”‚ (None, 512)            β”‚         1,536 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ dense_1 (Dense)                 β”‚ (None, 256)            β”‚       131,328 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ dense_2 (Dense)                 β”‚ (None, 64)             β”‚        16,448 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ dense_3 (Dense)                 β”‚ (None, 5)              β”‚           325 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 Total params: 149,637 (584.52 KB)
 Trainable params: 149,637 (584.52 KB)
 Non-trainable params: 0 (0.00 B)
None

Die drei wichtigsten Argumente sind

  • loss beschreibt die Modellverlustfunktion, sparse_categorical_crossentropy, im Wesentlichen die Log-Likelihood, ist geeignet fΓΌr Kategorisierungsaufgaben. Der genaue Typ hΓ€ngt auch davon ab, wie das Ergebnis genau codiert ist.
  • optimizer ist der Optimierer, der fΓΌr den stochastischen Gradientenabstieg verwendet werden soll. adam und rmsprop sind gute Optionen, aber es gibt auch andere MΓΆglichkeiten.
  • metrics ist eine Metrik, die wΓ€hrend der Optimierung ausgewertet und gedruckt wird und einige RΓΌckmeldungen darΓΌber bietet, wie die Auswertung verlΓ€uft.

Die letzte Zeile hier druckt die Modellzusammenfassung aus, eine praktische Übersicht darüber, was wir gemacht haben:

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense (Dense)                (None, 512)               1536      
_________________________________________________________________
dense_1 (Dense)              (None, 256)               131328    
_________________________________________________________________
dense_2 (Dense)              (None, 64)                16448     
_________________________________________________________________
dense_3 (Dense)              (None, 5)                 325       
=================================================================
Total params: 149,637
Trainable params: 149,637
Non-trainable params: 0

Dieses Netzwerk enthΓ€lt fast 150.000 Parameter, von denen alle trainierbar sind.

Nach erfolgreicher Kompilierung kΓΆnnen wir das Modell anpassen:

InΒ [19]:
history = model.fit(X, y, epochs=200)
Epoch 1/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.2420 - loss: 1.5866   
Epoch 2/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.3124 - loss: 1.5348
Epoch 3/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.3380 - loss: 1.5022
Epoch 4/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.3526 - loss: 1.4948
Epoch 5/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.3948 - loss: 1.4387
Epoch 6/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.4190 - loss: 1.4134
Epoch 7/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.4227 - loss: 1.4061
Epoch 8/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.4894 - loss: 1.3473
Epoch 9/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.5230 - loss: 1.2732 
Epoch 10/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.5768 - loss: 1.1794
Epoch 11/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.5832 - loss: 1.1095 
Epoch 12/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.5968 - loss: 1.0112
Epoch 13/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.6172 - loss: 0.9614
Epoch 14/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.6854 - loss: 0.8595
Epoch 15/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.6902 - loss: 0.8209
Epoch 16/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7138 - loss: 0.7498
Epoch 17/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7299 - loss: 0.6942
Epoch 18/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7558 - loss: 0.6768 
Epoch 19/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7601 - loss: 0.6116
Epoch 20/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7664 - loss: 0.6233
Epoch 21/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7620 - loss: 0.5642
Epoch 22/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7781 - loss: 0.5570 
Epoch 23/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.7963 - loss: 0.5587 
Epoch 24/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8258 - loss: 0.5069
Epoch 25/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8218 - loss: 0.4908 
Epoch 26/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8461 - loss: 0.4580
Epoch 27/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8414 - loss: 0.4397 
Epoch 28/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.8631 - loss: 0.4306
Epoch 29/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8701 - loss: 0.3760
Epoch 30/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8724 - loss: 0.3639
Epoch 31/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8582 - loss: 0.3748
Epoch 32/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8729 - loss: 0.3524
Epoch 33/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8801 - loss: 0.3546
Epoch 34/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8928 - loss: 0.3425
Epoch 35/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8587 - loss: 0.3670
Epoch 36/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8704 - loss: 0.3701
Epoch 37/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9065 - loss: 0.3003 
Epoch 38/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8964 - loss: 0.3134
Epoch 39/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8586 - loss: 0.3718 
Epoch 40/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8973 - loss: 0.2846
Epoch 41/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9045 - loss: 0.2834
Epoch 42/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8937 - loss: 0.2887 
Epoch 43/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9041 - loss: 0.3050 
Epoch 44/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.8821 - loss: 0.3079
Epoch 45/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9180 - loss: 0.2617
Epoch 46/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9315 - loss: 0.2482
Epoch 47/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9136 - loss: 0.2491
Epoch 48/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9157 - loss: 0.2374
Epoch 49/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9145 - loss: 0.2357 
Epoch 50/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9483 - loss: 0.2060
Epoch 51/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9087 - loss: 0.2396
Epoch 52/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9340 - loss: 0.2377 
Epoch 53/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9319 - loss: 0.1937
Epoch 54/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9390 - loss: 0.2065 
Epoch 55/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9351 - loss: 0.2100
Epoch 56/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9131 - loss: 0.2308
Epoch 57/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9354 - loss: 0.2039 
Epoch 58/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9472 - loss: 0.1931 
Epoch 59/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9195 - loss: 0.2264 
Epoch 60/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9239 - loss: 0.2087 
Epoch 61/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9270 - loss: 0.1953 
Epoch 62/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9007 - loss: 0.2922 
Epoch 63/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9295 - loss: 0.2009
Epoch 64/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9556 - loss: 0.1596
Epoch 65/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9447 - loss: 0.1768
Epoch 66/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9195 - loss: 0.2043
Epoch 67/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9269 - loss: 0.1980 
Epoch 68/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9375 - loss: 0.1924
Epoch 69/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9439 - loss: 0.1680
Epoch 70/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9202 - loss: 0.1917
Epoch 71/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9220 - loss: 0.2461
Epoch 72/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9386 - loss: 0.1639
Epoch 73/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9369 - loss: 0.1834
Epoch 74/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9474 - loss: 0.1701 
Epoch 75/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9441 - loss: 0.1719 
Epoch 76/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9302 - loss: 0.1957 
Epoch 77/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9415 - loss: 0.1750 
Epoch 78/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.9428 - loss: 0.1548 
Epoch 79/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9326 - loss: 0.1750 
Epoch 80/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9278 - loss: 0.1889
Epoch 81/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9291 - loss: 0.2374
Epoch 82/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9335 - loss: 0.2041
Epoch 83/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9311 - loss: 0.1968
Epoch 84/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9398 - loss: 0.1552
Epoch 85/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9673 - loss: 0.1390
Epoch 86/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9430 - loss: 0.1499
Epoch 87/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9516 - loss: 0.1568 
Epoch 88/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9283 - loss: 0.1687 
Epoch 89/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9544 - loss: 0.1385
Epoch 90/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9466 - loss: 0.1521
Epoch 91/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9479 - loss: 0.1525 
Epoch 92/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9361 - loss: 0.1530 
Epoch 93/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9230 - loss: 0.2029 
Epoch 94/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9447 - loss: 0.1537
Epoch 95/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9416 - loss: 0.1609 
Epoch 96/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9444 - loss: 0.1749 
Epoch 97/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9421 - loss: 0.1576
Epoch 98/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9166 - loss: 0.1857
Epoch 99/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9425 - loss: 0.1695
Epoch 100/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9444 - loss: 0.1552
Epoch 101/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9378 - loss: 0.1624 
Epoch 102/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9498 - loss: 0.1431
Epoch 103/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9586 - loss: 0.1337
Epoch 104/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9411 - loss: 0.1526 
Epoch 105/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9084 - loss: 0.2323
Epoch 106/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9529 - loss: 0.1623
Epoch 107/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9388 - loss: 0.1750
Epoch 108/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9095 - loss: 0.2029
Epoch 109/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9165 - loss: 0.1815
Epoch 110/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9525 - loss: 0.1398 
Epoch 111/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9453 - loss: 0.1610
Epoch 112/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9394 - loss: 0.1811 
Epoch 113/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9416 - loss: 0.1598
Epoch 114/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9647 - loss: 0.1007
Epoch 115/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9500 - loss: 0.1379 
Epoch 116/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.9179 - loss: 0.2284
Epoch 117/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9184 - loss: 0.2205 
Epoch 118/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9496 - loss: 0.1374 
Epoch 119/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9441 - loss: 0.1320
Epoch 120/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9276 - loss: 0.1717
Epoch 121/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9461 - loss: 0.1389
Epoch 122/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9697 - loss: 0.1011
Epoch 123/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9520 - loss: 0.1230
Epoch 124/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9570 - loss: 0.1133
Epoch 125/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9627 - loss: 0.1118
Epoch 126/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9475 - loss: 0.1428
Epoch 127/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9659 - loss: 0.1012
Epoch 128/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9479 - loss: 0.1337
Epoch 129/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9491 - loss: 0.1412
Epoch 130/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9440 - loss: 0.1343
Epoch 131/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9566 - loss: 0.1321
Epoch 132/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9563 - loss: 0.1101
Epoch 133/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9554 - loss: 0.1330
Epoch 134/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9585 - loss: 0.1197
Epoch 135/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9553 - loss: 0.1210
Epoch 136/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9690 - loss: 0.0943
Epoch 137/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9573 - loss: 0.1255
Epoch 138/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9614 - loss: 0.0988
Epoch 139/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9645 - loss: 0.0981
Epoch 140/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9563 - loss: 0.1292
Epoch 141/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9499 - loss: 0.1273
Epoch 142/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9433 - loss: 0.1313 
Epoch 143/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9255 - loss: 0.1627 
Epoch 144/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9447 - loss: 0.1703
Epoch 145/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9565 - loss: 0.1109
Epoch 146/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9570 - loss: 0.1063
Epoch 147/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9618 - loss: 0.1016
Epoch 148/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9573 - loss: 0.1047
Epoch 149/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9588 - loss: 0.1149
Epoch 150/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9319 - loss: 0.1750
Epoch 151/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9568 - loss: 0.1034
Epoch 152/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9516 - loss: 0.1152
Epoch 153/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9395 - loss: 0.1530
Epoch 154/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9461 - loss: 0.1331
Epoch 155/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9626 - loss: 0.1101
Epoch 156/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9555 - loss: 0.1173
Epoch 157/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.9110 - loss: 0.2713 
Epoch 158/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9075 - loss: 0.3131
Epoch 159/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9526 - loss: 0.1204
Epoch 160/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9614 - loss: 0.1138
Epoch 161/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9491 - loss: 0.1336
Epoch 162/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9399 - loss: 0.1355
Epoch 163/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9195 - loss: 0.2212
Epoch 164/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9365 - loss: 0.1575
Epoch 165/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9461 - loss: 0.1443
Epoch 166/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9549 - loss: 0.1099
Epoch 167/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9795 - loss: 0.0811
Epoch 168/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9654 - loss: 0.0818
Epoch 169/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9415 - loss: 0.1343
Epoch 170/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9681 - loss: 0.0848
Epoch 171/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9516 - loss: 0.1609
Epoch 172/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9437 - loss: 0.1349
Epoch 173/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9588 - loss: 0.1157
Epoch 174/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9490 - loss: 0.1180
Epoch 175/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9054 - loss: 0.3089
Epoch 176/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9111 - loss: 0.2796
Epoch 177/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9646 - loss: 0.0958
Epoch 178/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9657 - loss: 0.1028
Epoch 179/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9775 - loss: 0.0832
Epoch 180/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9864 - loss: 0.0724
Epoch 181/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9777 - loss: 0.0729
Epoch 182/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9719 - loss: 0.0837
Epoch 183/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9585 - loss: 0.1135
Epoch 184/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9530 - loss: 0.1345
Epoch 185/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9255 - loss: 0.2039 
Epoch 186/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9316 - loss: 0.1574
Epoch 187/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9265 - loss: 0.1630
Epoch 188/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9410 - loss: 0.1444
Epoch 189/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9562 - loss: 0.1151
Epoch 190/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9518 - loss: 0.1082
Epoch 191/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9826 - loss: 0.0673
Epoch 192/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9741 - loss: 0.0786
Epoch 193/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9729 - loss: 0.0820
Epoch 194/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9711 - loss: 0.0750 
Epoch 195/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9659 - loss: 0.0925
Epoch 196/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9761 - loss: 0.0802
Epoch 197/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9730 - loss: 0.0840
Epoch 198/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9659 - loss: 0.1003
Epoch 199/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - accuracy: 0.9562 - loss: 0.1076 
Epoch 200/200
32/32 ━━━━━━━━━━━━━━━━━━━━ 0s 1ms/step - accuracy: 0.9529 - loss: 0.1242

In diesem Beispiel ist X die Designmatrix, y der Ergebnisvektor, und das Argument epochs gibt an, wie viele Epochen der Optimierer durchlaufen soll. Keras gibt den Fortschritt beim Optimieren an, es kΓΆnnte so aussehen

Epoch 1/200
25/25 [==============================] - 0s 2ms/step - loss: 1.5984 - accuracy: 0.2438
Epoch 2/200
25/25 [==============================] - 0s 2ms/step - loss: 1.5709 - accuracy: 0.2763
Epoch 3/200
25/25 [==============================] - 0s 3ms/step - loss: 1.5550 - accuracy: 0.3013

Hierbei kann man die aktuelle Epoche, den Batch (fΓΌr stochastischen Gradientenabstieg) und die aktuelle Genauigkeit der Trainingsdaten sehen. In diesem Beispiel werden alle Epochen bis zum Abschluss ausgefΓΌhrt, daher sehen wir 32/32 fΓΌr Batches, aber normalerweise kann man die Batch-Nummer sehen, die sich wΓ€hrend des Trainings fortschreitet. Dieses Beispiel funktioniert sehr schnell, Keras meldet 2 ms pro Schritt (Batch) und die Gesamtzeit fΓΌr die Epoche ist zu gering, um gemeldet zu werden. Aber eine einzelne Epoche kann bei komplexeren Modellen und mehr Daten viele Minuten dauern.

Achtung: BatchqualitΓ€t vs. ModellqualitΓ€t

Die ModellqualitΓ€t (hier Genauigkeit) wird fΓΌr eine einzelne Batch berechnet und gibt nur eine grobe Richtlinie fΓΌr die tatsΓ€chliche Modellgenauigkeit, auch auf Trainingsdaten. Nehmen Sie diese Genauigkeitsmessung nicht zu ernst!

Achtung: Modelle fertig trainieren

Keras ermâglicht es Ihnen, Vorhersagen mit einem Modell zu treffen, das nicht angepasst ist (im Gegensatz zu scikit-learn, wo das einen Fehler verursacht). Die Ergebnisse werden bestenfalls mittelmÀßig aussehen.

Vorhersagen und PlottenΒΆ

Wenn die Anpassung abgeschlossen ist, kΓΆnnen wir das Modell fΓΌr Vorhersagen verwenden. Die Vorhersage funktioniert Γ€hnlich wie in sklearn, nur dass die predict-Methode die Wahrscheinlichkeit vorhersagt, nicht die Kategorie (analog zu sklearn's predict_proba).

InΒ [20]:
phat = model.predict(X_test)
8/8 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step 

In diesem Beispiel handelt es sich um eine Matrix mit 5 Spalten, wobei jede Spalte die Wahrscheinlichkeit darstellt, dass der Datenpunkt zur entsprechenden Kategorie gehΓΆrt. Beispielsweise kΓΆnnten Zeilen von phat so aussehen:

InΒ [21]:
phat[:5]
Out[21]:
array([[5.95512835e-38, 3.64608788e-14, 9.98544693e-01, 1.45527220e-03,
        2.91063951e-09],
       [1.82841420e-01, 8.16542685e-01, 6.15835190e-04, 4.51730125e-14,
        5.24001487e-24],
       [9.99992132e-01, 7.85444445e-06, 6.54230489e-12, 2.19196022e-25,
        1.10281194e-35],
       [9.99036908e-01, 9.63104074e-04, 1.26972577e-09, 7.09073374e-20,
        8.26557008e-33],
       [9.99998331e-01, 1.71557156e-06, 9.29063142e-14, 2.84648575e-27,
        2.38099274e-38]], dtype=float32)

Wir sehen, dass für jedes Test-Fall eine Wahrscheinlichkeit für jede Kategorie angegeben ist. Als nÀchstes wollen wir mit np.argmax(phat, axis=-1) die Spalte (Kategorie) finden, mit der hâchsten Wahrscheinlichkeit. Es findet einfach die Position der grâßten Elemente im Array entlang der letzten Achse (axis=-1), d.h. Spalten. Für jede Zeile finden wir also die entsprechende Spaltennummer. Beachten Sie, dass np.argmax die Spalten ab 0 zÀhlt, nicht ab 1:

InΒ [22]:
yhat = np.argmax(phat, axis=-1)
yhat[:5]
Out[22]:
array([2, 1, 0, 0, 0])

Endlich kΓΆnnen wir die Verwirrungsmatrix mit pd.crosstab berechnen und die Genauigkeit berechnen:

InΒ [23]:
from sklearn.metrics import confusion_matrix

print("confusion matrix:\n", confusion_matrix(y_test, yhat))
print("Accuracy (on training data):", np.mean(y_test == yhat))
confusion matrix:
 [[54  0  0  0  0]
 [ 2 32  0  0  0]
 [ 0  1 69  0  0]
 [ 0  0  2 36  0]
 [ 0  0  0  0 54]]
Accuracy (on training data): 0.98

In diesem Beispiel machen wir Vorhersagen auf Trainingsdaten, aber wir kânnen natürlich auch einen anderen Datensatz für Vorhersagen auswÀhlen. Da der vorhergesagte Wert eine Wahrscheinlichkeitsmatrix mit 5 Spalten sein wird, berechnen wir yhat als die Spaltennummer, die die grâßte Wahrscheinlichkeit für jede Zeile enthÀlt.

Wie man sehen kann, ist die Verwirrungsmatrix fast ausschließlich auf der Hauptdiagonalen besetzt, und die Genauigkeit ist hoch.

Schließlich müssen wir, wenn wir ein Àhnliches Diagramm wie oben erstellen mâchten, die DBPlot-Funktion anpassen, um zu berücksichtigen, dass Keras-Modelle nur Wahrscheinlichkeiten vorhersagen.

InΒ [24]:
def DBPlot(m, X, y, nGrid = 300):
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max, nGrid), 
                           np.linspace(x2_min, x2_max, nGrid))
    XX = np.column_stack((xx1.ravel(), xx2.ravel()))
    ## predict probability
    phat = m.predict(XX, verbose=0)
    ## find the column that corresponds to the maximum probability
    hatyy = np.argmax(phat, axis=-1).reshape(xx1.shape)
    fig = px.imshow(hatyy, width=600, height=600)
    fig.add_scatter(x=X[:,0]/(x1_max-x1_min)*nGrid+nGrid/2, y=X[:,1]/(x2_max-x2_min)*nGrid+nGrid/2, mode="markers", 
                    marker=dict(color=[mcolors[i] for i in y]), marker_line=dict(width=.3, color="black"))
    fig.update_coloraxes(showscale=False)
    fig.update_layout(showlegend=False)
    fig.show()
InΒ [25]:
DBPlot(model, X_test, y_test)

Noch einmal, die Funktion ist fast identisch mit der sklearn Version, außer der Zeile, die np.argmax(phat, axis=-1) enthÀlt, die die vorhergesagten Wahrscheinlichkeiten in Kategorien umwandelt.

fΒ Β rΒ Β aΒ Β gΒ Β eΒ Β nΒ Β ?