Ziel ist es, ein Neural Network zu entwickeln, das den Fashion MNIST Datensatz klassifiziert. Der Fokus liegt dabei auf:
- Nutzung von Faltungsschichten, die die Erkennungsleistung bei Bildern (Computer Vision) gegenüber klassischen neuronalen Netzen meist deutlich verbessern. Diese Netze werden als Convolutional Neural Networks (CNN) bezeichnet.
- Aufbau eines geeigneten CNNs für Bildklassifikation
- Verwendung von Dropout zur Reduktion von Overfitting
- Evaluation und Visualisierung des Trainingsverlaufs
1. Hintergrund: Was ist Fashion MNIST?
Fashion MNIST ist ein weit verbreiteter Benchmark-Datensatz für Bildklassifikation. Er besteht aus 70.000 Graustufenbildern der Größe 28×28, die jeweils ein Kleidungsstück aus zehn Klassen darstellen:
Label | Klasse |
---|---|
0 | T-Shirt/Top |
1 | Hose |
2 | Pullover |
3 | Kleid |
4 | Jacke/Mantel |
5 | Sandale |
6 | Hemd |
7 | Sneaker |
8 | Tasche |
9 | Niedrige Stiefel |
Hier ein Auszug aus dem Datensatz:

2. Vorbereitung
2.1 Laden des Datensatzes
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# Fashion MNIST laden
fashion_mnist = tf.keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
2.2 Dimensionsprüfung
print("Trainingsdaten:", train_images.shape)
print("Testdaten:", test_images.shape)
→ Ausgabe:
Trainingsdaten: (60000, 28, 28)
Testdaten: (10000, 28, 28)
2.3 Normalisierung und Reshaping
Die Pixelwerte der Bilder (wie bei den meisten digitialen Bildern) beträgt 0 bis 255. Neuronale Netze können – je nach gewählten Aktivierungsfunktionen – allerdings besser Werte verarbeiten die zwischen 0 und 1 (Relu/Sigmoid-Aktivierungsfunktion) bzw. zwischen – 1 und +1 (Tanh-Aktivierungsfunktion) liegen. Daher wird mit einer Division durch 255 eine einfache Normalisierung angewendet.
CNNs benötigen außerdem Eingaben mit einer expliziten Kanal-Dimension: Bei Farbbildern sind das üblicherweise 3 Kanäle. In dem Beispiel werden Graustufenbildern genutzt wofür 1 Kanal notwendig ist.
# Wertebereich [0, 255] → [0.0, 1.0]
train_images = train_images / 255.0
test_images = test_images / 255.0
# Kanal hinzufügen (1 Graustufenkanal)
train_images = train_images[..., tf.newaxis] # → (60000, 28, 28, 1)
test_images = test_images[..., tf.newaxis]
2.4 Stichproben anzeigen
class_names = ['T-Shirt', 'Hose', 'Pullover', 'Kleid', 'Mantel',
'Sandale', 'Hemd', 'Sneaker', 'Tasche', 'Stiefel']
plt.figure(figsize=(10,4))
for i in range(10):
plt.subplot(2, 5, i+1)
plt.imshow(train_images[i].squeeze(), cmap='gray')
plt.title(class_names[train_labels[i]])
plt.axis('off')
plt.tight_layout()
plt.show()
3. Modellarchitektur: CNN mit Dropout
Das Modell besteht unter anderen aus Schichten, die in den vorherigen Tutorials noch nicht genutzt wurden:
- Zwei Faltungsschichten (Conv2D) zur Merkmalextraktion
- Zwei Pooling-Schichten (MaxPooling2D) zur Reduktion der räumlichen Dimension
- Dropout zur Reduktion von Overfitting
- Normale Neuronen-Schichten zur Klassifikation
Was sind Faltungsschichten?
Eine Faltungsschicht besteht aus einer Anzahl kleiner Filter (auch Kernels genannt), die systematisch über das Eingabebild gleiten. Jeder Filter ist eine kleine Matrix (z. B. 3×3 oder 5×5), deren Werte lernbar sind. Während des Gleitens (auch Convolution genannt) wird an jeder Position das Skalarprodukt zwischen dem Filter und dem entsprechenden Bildausschnitt berechnet. Dieses Ergebnis repräsentiert bestimmte lokale Merkmale, etwa Kanten, Texturen oder Muster. Das Resultat der Filteranwendung ist eine sogenannte Feature Map, die anzeigt, wo und wie stark ein bestimmtes Merkmal im Bild vorhanden ist. Durch das Stapeln mehrerer Filter kann eine Faltungsschicht viele verschiedene Merkmale gleichzeitig erkennen. Die so extrahierten Informationen dienen in tieferen Schichten als Grundlage für komplexere Muster und letztlich für die Klassifikation.
Für eine hhorizontale Kantenerkennung (z. B. zur Betonung von Linien, Kontrasten oder Texturen in vertikaler Richtung) wird vom CNN eine Kernelmatrix gelernt, die auf horizontale Kanten reagiert und nach dem Lernen wie folgt aussehen kann:
[ -1 -1 -1 ]
[ 0 0 0 ]
[ 1 1 1 ]
Die Faltung lässt diese 3×3-Matrix nun über alle Pixel der Trainingsbilder und erstellt das Skalarprodukt daraus und gibt dies in die nächste Schicht weiter. Da an den Bildrändern je ein Pixel verloren geht (bei einer 5×5 Matrix würden 2 Pixel je Bildrand verloren gehen), verkleinert sich das nachfolgende „Bild“ um 2 Pixel in horizontaler und vertikaler Richtung.
Die Faltungschicht lässt nicht nur eine Matrix über das Bild gleiten, sondern x (meist wählt man 16, 32, 64 oder 128). D.h. es werden entsprechend viele gefaltete Bilder in die nächste Schicht übergeben. Jede Matrix bzw. Faltung betont andere Merkmale („Features“) des Bildes, z.B. Kanten und Texturen. Werden mehrere Faltungsschichten gestapelt, werden immer abstraktere Merkmale betont. Bsp:
1. Faltungsschicht betont Kanten und Texturen
2. Faltungsschicht betont einfachen geometrische Formen wie Ecken, Kreise, Ellipsen etc.
3. Faltungsschicht betont komplexere geometrischen Formen oder auch erste reale Objekte wie Augen, Nasen etc.
4. Faltungsschicht betont Objekte, die aus mehreren geomplexere geometrischen Formen oder auch reale Objekten zusammengesetzt sind, z.B. Gesichter oder Tiere
Was sind Pooling-Schichten?
Eine Poolingschicht gleitet ebenfalls mit kleinen Matrixen über das Bild. Im Gegensatz zur Faltungsschicht ist es aber nur eine Matrix und sie ermittelt den maximalen Pixelwert innerhalb dieser Matrix und gibt diesen an die nächste Schicht weiter. Wird eine 2×2-Matrix genutzt, halbiert sich die Auflösung des Bildes sowohl in horizontaler als auch in vertikaler Richtung – die Pixelanzahl reduziert sich dadurch auf ein Viertel und es werden weniger Neuronen in den nachfolgenden Schichten benötigt (dies reduziert die benötigte Rechenleistung bzw. Rechenzeit). Dieses Maximalwert-Pooling bietet sich vor allem nach Faltungsschichten an, bei denen ja manche Pixel durch die Faltung betont werden (z.B. Kanten). Die betonten Pixel bleibend dann beim Maximalwert-Pooling erhalten! D.h. der Informationsgehalt pro Pixel erhöht sich während die nachfolgenden Schichten entlastet werden.
Was sind Dropout-Schichten?
Dropout ist eine Technik, die in neuronalen Netzen verwendet wird, um Overfitting zu vermeiden und die Generalisierung des Modells zu verbessern, d.h. um zu Vermeiden, dass das neuronale Netz die Trainingsdaten auswendig lernt, sondern eher allgemeine Merkmale der Trainingsdaten lernt (wie z.B. eher die Form eines Schuhs, als alle Schuhpixel der Trainingsdaten).
Während des Trainings werden bei jedem Schritt zufällig ausgewählte Neuronenausgaben der Vorgängerschicht (oder auch die Ausgaben der Faltungs- oder Poolingschicht) temporär deaktiviert – das bedeutet, ihre Ausgaben werden auf null gesetzt. Dadurch wird verhindert, dass sich das Modell zu stark auf einzelne Neuronen oder Pfade verlässt. Stattdessen muss es lernen, robuste und redundante Merkmalsrepräsentationen zu entwickeln. Dropout wirkt wie eine Art Ensemble-Lernen innerhalb eines einzelnen Netzwerks, da bei jedem Trainingsdurchlauf ein anderes Subnetzwerk aktiv ist. Beim Testen oder Vorhersagen bleibt Dropout deaktiviert, sodass alle Neuronen verwendet werden. Besonders effektiv ist Dropout in voll verbundenen Schichten (Dense Layers), kann aber auch in Faltungsschichten eingesetzt werden. Meist werden Dropout-Werte von 10%-50% verwendet – beim Training werden dann 10%-50% der Ausgaben der Vorgängerschicht deaktiviert.
Dropout funktioniert erfahrungsgemäß bei Computer-Vision sehr gut.
3.1 Aufbau des CNN
model = tf.keras.Sequential([
# Erste Faltungsschichtmit 32 Filtern mit einer Kernelgröße von 3x3 Pixel
tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1)),
# Bildgröße vierteln, aber die vorherigen Merkmale der Faltungsschicht weitestgehend beibehalten
tf.keras.layers.MaxPooling2D(2,2),
# Zweite Faltungsschicht mit 64 Filtern mit einer Kernelgröße von 3x3 Pixel
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
# Flatten-Schicht zur Vektorisierung
tf.keras.layers.Flatten(),
# Dropout: zufälliges Deaktivieren von 20% der Vorgängerschichtausgaben während des Trainings
tf.keras.layers.Dropout(0.2),
# Normale Neuronen-Schicht
tf.keras.layers.Dense(128, activation='relu'),
# Ausgangsschicht mit 10 Klassen
tf.keras.layers.Dense(10, activation='softmax')
])
4. Modellkompilierung
model.compile(optimizer='adam',
sparse_categorical_crossentropy
loss='',
metrics=['accuracy'])
- Adam: adaptiver Optimierer, der gut mit Bilddaten funktioniert
- Categorical Crossentropy: geeignet für ganzzahlige Klassenlabels
- Accuracy: Klassifikationsgenauigkeit als Metrik
5. Training
5.1 Training starten
history = model.fit(train_images, train_labels,
epochs=10,
validation_split=0.1,
batch_size=64)
- validation_split=0.1: 10 % der Trainingsdaten werden für die Validierung genutzt.
- Batchgröße: Anzahl der Bilder pro Trainingsschritt
6. Evaluation des Modells
pythonCopyEdittest_loss, test_acc = model.evaluate(test_images, test_labels)
print(f'Testgenauigkeit: {test_acc:.4f}')
7. Visualisierung des Trainingsverlaufs
plt.figure(figsize=(12, 5))
plt.subplot(1,2,1)
plt.plot(history.history['accuracy'], label='Training')
plt.plot(history.history['val_accuracy'], label='Validierung')
plt.title('Genauigkeit pro Epoche')
plt.xlabel('Epoche')
plt.ylabel('Genauigkeit')
plt.legend()
plt.subplot(1,2,2)
plt.plot(history.history['loss'], label='Training')
plt.plot(history.history['val_loss'], label='Validierung')
plt.title('Verlust pro Epoche')
plt.xlabel('Epoche')
plt.ylabel('Loss')
plt.legend()
plt.tight_layout()
plt.show()
8. Resultat
Das CNN-Modell mit Dropout erreicht auf dem Fashion-MNIST-Datensatz eine hohe Genauigkeit und gute Generalisierungsleistung. Durch Dropout wird das Risiko von Overfitting deutlich reduziert, insbesondere bei kleineren Datensätzen oder vielen Trainingsdurchläufen.
9. Mögliche Erweiterungen
- Variation der Dropout-Rate (z. B. 0.3 oder 0.5)
- Hinzufügen weiterer Faltungs- und Poolingschichten
- Verwendung von Batch Normalization