Inhaltsverzeichnis
- Von ML zu Deep Learning
- Das künstliche Neuron
- Aktivierungsfunktionen
- Feedforward Neural Network
- Training: Backpropagation und Gradient Descent
- Verlustfunktionen
- Erstes Netz mit Keras
- Overfitting bekämpfen
- Convolutional Neural Networks (CNNs)
- Praktisches Projekt: Bildklassifikation mit CIFAR-10
- Optimierer im Vergleich
- Transfer Learning
- Zusammenfassung und Ausblick
- Anhang: Schnellreferenz Keras
Deep Learning – Neuronale Netze und CNNs
Fach: Data Science & Artificial Intelligence
Schulstufe: 12. Schulstufe – HTL Informatik
Voraussetzungen: Supervised Learning, Python / NumPy, grundlegende Lineare Algebra
Autor: HTL Pinkafeld – IF/IT
1. Von ML zu Deep Learning
1.1 Was ist Deep Learning?
Deep Learning ist ein Teilgebiet des Machine Learnings, das auf künstlichen neuronalen Netzen mit vielen Schichten basiert. Der Begriff „deep" (tief) bezieht sich auf die Anzahl der Schichten – moderne Netze haben oft Dutzende bis Hunderte davon.
1.2 Warum Deep Learning?
Klassische ML-Algorithmen wie Random Forest oder SVM benötigen handgefertigte Features (Feature Engineering). Bei Bildern, Audio oder Text ist das extrem aufwändig – man müsste dem Algorithmus manuell sagen, worauf er achten soll.
Deep Learning lernt die relevanten Features automatisch aus den Rohdaten:
Klassisches ML:
Rohdaten → [Feature Engineering, manuell] → Features → Algorithmus → Ausgabe
Deep Learning:
Rohdaten ────────────────────────────────→ Neuronales Netz → Ausgabe
(lernt Features selbst)
1.3 Wann ist Deep Learning sinnvoll?
| Situation | Empfehlung |
|---|---|
| Bilder, Audio, Video, Text | ✅ Deep Learning |
| Tabellarische/strukturierte Daten | ⚠️ Oft Ensemble-Methoden besser |
| Wenig Daten (< 10.000) | ⚠️ Klassisches ML oft besser |
| Viele Daten, hohe Komplexität | ✅ Deep Learning |
| Interpretierbarkeit wichtig | ❌ Eher klassisches ML |
1.4 Historischer Durchbruch
1958 Perceptron (Rosenblatt)
1986 Backpropagation (Rumelhart, Hinton)
1998 LeNet – erstes CNN für Ziffernerkennung (LeCun)
2012 AlexNet gewinnt ImageNet – Deep Learning-Revolution
2017 Transformer-Architektur (Vaswani et al.)
2022 ChatGPT – Large Language Models im Mainstream
2. Das künstliche Neuron
2.1 Biologisches Vorbild
Das künstliche Neuron ist vom biologischen Neuron inspiriert:
Biologisch: Künstlich:
Dendriten → Eingaben x₁, x₂, ..., xₙ
Zellkörper → Gewichtete Summe + Bias
Axon → Aktivierungsfunktion → Ausgabe
2.2 Mathematisches Modell
Ein einzelnes Neuron berechnet:
z = w₁·x₁ + w₂·x₂ + ... + wₙ·xₙ + b
= wᵀ·x + b (Vektorschreibweise)
y = f(z) (Aktivierungsfunktion anwenden)
- x = Eingabevektor (Features)
- w = Gewichtsvektor (wird beim Training gelernt)
- b = Bias (Verschiebung, wird ebenfalls gelernt)
- f = Aktivierungsfunktion (bringt Nichtlinearität ins Netz)
2.3 Das Perceptron
Das einfachste Neuron – der Perceptron – verwendet eine Stufenfunktion als Aktivierung:
import numpy as np
def perceptron(x, w, b):
z = np.dot(w, x) + b
return 1 if z >= 0 else 0
# Beispiel: UND-Gatter
w = np.array([1.0, 1.0])
b = -1.5
print(perceptron([0, 0], w, b)) # 0
print(perceptron([0, 1], w, b)) # 0
print(perceptron([1, 0], w, b)) # 0
print(perceptron([1, 1], w, b)) # 1
⚠️ Problem: Ein einzelnes Neuron kann nur linear trennbare Probleme lösen. Das XOR-Problem z.B. ist nicht linear trennbar – dafür brauchen wir mehrere Schichten.
3. Aktivierungsfunktionen
Aktivierungsfunktionen bringen Nichtlinearität ins Netz. Ohne sie wäre ein mehrstufiges Netz mathematisch äquivalent zu einem einzelnen Neuron.
3.1 Übersicht
| Funktion | Formel | Ausgabebereich | Typische Verwendung |
|---|---|---|---|
| Sigmoid | 1 / (1 + e⁻ᶻ) |
(0, 1) | Ausgabeschicht (Binäre Klass.) |
| Tanh | (eᶻ - e⁻ᶻ) / (eᶻ + e⁻ᶻ) |
(-1, 1) | Versteckte Schichten (veraltet) |
| ReLU | max(0, z) |
[0, ∞) | Versteckte Schichten (Standard) |
| Leaky ReLU | z if z>0 else 0.01·z |
(-∞, ∞) | Versteckte Schichten |
| Softmax | eᶻⁱ / Σ eᶻʲ |
(0,1), Summe=1 | Ausgabeschicht (Mehrklassen) |
3.2 ReLU – Rectified Linear Unit
ReLU ist heute die Standard-Aktivierungsfunktion in versteckten Schichten:
import numpy as np
import matplotlib.pyplot as plt
z = np.linspace(-4, 4, 200)
relu = np.maximum(0, z)
leaky_relu = np.where(z > 0, z, 0.01 * z)
sigmoid = 1 / (1 + np.exp(-z))
tanh = np.tanh(z)
fig, axes = plt.subplots(1, 2, figsize=(10, 4))
axes[0].plot(z, relu, label='ReLU', color='#F6A01D', linewidth=2)
axes[0].plot(z, leaky_relu, label='Leaky ReLU', color='#C97D00', linestyle='--', linewidth=2)
axes[0].axhline(0, color='gray', linewidth=0.5)
axes[0].axvline(0, color='gray', linewidth=0.5)
axes[0].set_title('ReLU Varianten'); axes[0].legend()
axes[1].plot(z, sigmoid, label='Sigmoid', color='#F6A01D', linewidth=2)
axes[1].plot(z, tanh, label='Tanh', color='#C97D00', linestyle='--', linewidth=2)
axes[1].axhline(0, color='gray', linewidth=0.5)
axes[1].set_title('Sigmoid & Tanh'); axes[1].legend()
plt.tight_layout()
plt.show()
3.3 Warum ReLU so beliebt ist
- Einfach zu berechnen: Nur ein Vergleich mit 0
- Kein Vanishing Gradient: Gradient ist konstant 1 für z > 0
- Sparse Activation: Viele Neuronen sind inaktiv (z < 0) → effizientere Repräsentation
Vanishing Gradient Problem: Bei Sigmoid/Tanh werden die Gradienten in tiefen Netzen immer kleiner (gegen 0) – das Netz lernt kaum noch. ReLU löst dieses Problem weitgehend.
4. Feedforward Neural Network
4.1 Aufbau
Ein Feedforward Neural Network (auch Multi-Layer Perceptron, MLP) besteht aus:
Eingabe- Versteckte Schichten Ausgabe-
schicht (hidden layers) schicht
x₁ ──┐ ┌── ŷ₁
x₂ ──┼─→ [Layer 1] → [Layer 2] ─┼── ŷ₂
x₃ ──┘ └── ŷ₃
Daten fließen immer vorwärts (feedforward)
- Eingabeschicht: Ein Neuron pro Feature
- Versteckte Schichten: Lernen interne Repräsentationen
- Ausgabeschicht: Ein Neuron pro Klasse (Klassifikation) oder 1 Neuron (Regression)
4.2 Matrixschreibweise einer Schicht
Für eine Schicht mit n Eingaben und m Neuronen:
Z = X · Wᵀ + b
A = f(Z)
X: (batch_size × n) Eingabe
W: (m × n) Gewichtsmatrix
b: (m,) Bias-Vektor
A: (batch_size × m) Ausgabe nach Aktivierung
4.3 Universeller Approximationssatz
Ein neuronales Netz mit einer versteckten Schicht und genügend Neuronen kann jede stetige Funktion beliebig genau approximieren.
In der Praxis sind jedoch tiefe Netze (viele Schichten, weniger Neuronen pro Schicht) effizienter als breite Netze (eine Schicht, viele Neuronen).
5. Training: Backpropagation und Gradient Descent
5.1 Das Lernprinzip
Beim Training wird ein Fehlermaß (Loss) berechnet und die Gewichte so angepasst, dass der Fehler sinkt. Das Herzstück ist der Gradientenabstieg:
w_neu = w_alt - η · ∂L/∂w
η = Lernrate (wie groß ist der Schritt?)
∂L/∂w = Gradient des Verlusts bzgl. des Gewichts
5.2 Backpropagation
Backpropagation berechnet effizient die Gradienten aller Gewichte mithilfe der Kettenregel der Differentialrechnung – von der Ausgabeschicht rückwärts zur Eingabeschicht.
Vorwärtsdurchlauf (Forward Pass):
x → Layer 1 → Layer 2 → ... → ŷ → L(ŷ, y)
Rückwärtsdurchlauf (Backward Pass):
∂L/∂wₙ ← ∂L/∂wₙ₋₁ ← ... ← ∂L/∂w₁
(Kettenregel rückwärts anwenden)
Gewichte aktualisieren:
w ← w - η · ∂L/∂w
5.3 Gradientenabstieg-Varianten
| Variante | Beschreibung | Vor-/Nachteile |
|---|---|---|
| Batch GD | Gradient über alle Daten | Stabil, aber langsam |
| Stochastic GD (SGD) | Gradient über 1 Datenpunkt | Schnell, aber laut/instabil |
| Mini-Batch GD | Gradient über k Datenpunkte | ✅ Bester Kompromiss (Standard) |
# Mini-Batch: Typische Batch-Größen: 32, 64, 128, 256
model.fit(X_train, y_train, batch_size=32, epochs=50)
5.4 Die Lernrate
Die Lernrate η ist einer der wichtigsten Hyperparameter:
η zu groß: Überspringt Minimum → konvergiert nicht
η zu klein: Lernt sehr langsam → braucht viele Epochen
η optimal: Konvergiert zuverlässig zum Minimum
Tipp: Lernraten-Scheduler passen η während des Trainings an – zu Beginn groß, später klein.
6. Verlustfunktionen
Die Verlustfunktion (Loss Function) misst, wie falsch die Vorhersagen sind.
6.1 Übersicht
| Aufgabe | Verlustfunktion | Keras-Name |
|---|---|---|
| Binäre Klassifikation | Binary Cross-Entropy | binary_crossentropy |
| Mehrklassen-Klassifikation (Integer Labels) | Sparse Categorical Cross-Entropy | sparse_categorical_crossentropy |
| Mehrklassen-Klassifikation (One-Hot Labels) | Categorical Cross-Entropy | categorical_crossentropy |
| Regression | Mean Squared Error | mse |
| Regression (robuster) | Mean Absolute Error | mae |
6.2 Cross-Entropy anschaulich
Vorhersage für Katze: 90% → Loss klein (fast richtig)
Vorhersage für Katze: 10% → Loss groß (sehr falsch)
Binary Cross-Entropy:
L = -[y · log(ŷ) + (1-y) · log(1-ŷ)]
7. Erstes Netz mit Keras
7.1 Keras und TensorFlow
Keras ist das offizielle High-Level-API von TensorFlow. Es ermöglicht das schnelle Aufbauen und Trainieren neuronaler Netze mit wenigen Zeilen Code.
pip install tensorflow
7.2 Klassifikation: MNIST-Ziffernerkennung
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
# ── 1. Daten laden ────────────────────────────────────────────────────────
(X_train, y_train), (X_test, y_test) = keras.datasets.mnist.load_data()
# Normalisieren: Pixelwerte 0–255 → 0.0–1.0
X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0
# Bilder glätten: (28, 28) → (784,)
X_train = X_train.reshape(-1, 784)
X_test = X_test.reshape(-1, 784)
print(f"Trainingsdaten: {X_train.shape}") # (60000, 784)
print(f"Testdaten: {X_test.shape}") # (10000, 784)
# ── 2. Modell aufbauen ────────────────────────────────────────────────────
model = keras.Sequential([
layers.Dense(128, activation='relu', input_shape=(784,)),
layers.Dense(64, activation='relu'),
layers.Dense(10, activation='softmax') # 10 Klassen (0–9)
])
model.summary()
# ── 3. Kompilieren ────────────────────────────────────────────────────────
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# ── 4. Trainieren ─────────────────────────────────────────────────────────
history = model.fit(
X_train, y_train,
epochs=10,
batch_size=64,
validation_split=0.1, # 10% der Trainingsdaten als Validierung
verbose=1
)
# ── 5. Evaluieren ─────────────────────────────────────────────────────────
test_loss, test_acc = model.evaluate(X_test, y_test, verbose=0)
print(f"\nTest Accuracy: {test_acc:.2%}")
# ── 6. Trainingsverlauf visualisieren ─────────────────────────────────────
fig, axes = plt.subplots(1, 2, figsize=(11, 4))
axes[0].plot(history.history['loss'], label='Training Loss')
axes[0].plot(history.history['val_loss'], label='Validation Loss')
axes[0].set_title('Verlust'); axes[0].legend()
axes[1].plot(history.history['accuracy'], label='Training Accuracy')
axes[1].plot(history.history['val_accuracy'], label='Validation Accuracy')
axes[1].set_title('Accuracy'); axes[1].legend()
plt.tight_layout()
plt.show()
7.3 Modell-Architektur lesen
Layer (type) Output Shape Param #
=================================================
dense (Dense) (None, 128) 100.480 ← 784×128 + 128 Bias
dense_1 (Dense) (None, 64) 8.256 ← 128×64 + 64 Bias
dense_2 (Dense) (None, 10) 650 ← 64×10 + 10 Bias
=================================================
Total params: 109.386
💡 Parameteranzahl berechnen:
Ausgaben × Eingaben + Ausgaben (Bias)
8. Overfitting bekämpfen
8.1 Dropout
Dropout deaktiviert zufällig einen Anteil der Neuronen während des Trainings. Das verhindert, dass einzelne Neuronen zu dominant werden.
model = keras.Sequential([
layers.Dense(256, activation='relu', input_shape=(784,)),
layers.Dropout(0.3), # 30% der Neuronen deaktivieren
layers.Dense(128, activation='relu'),
layers.Dropout(0.3),
layers.Dense(10, activation='softmax')
])
Beim Inferenz (Vorhersage) werden alle Neuronen wieder aktiviert – Dropout ist nur während des Trainings aktiv.
8.2 Batch Normalization
Batch Normalization normalisiert die Aktivierungen jeder Schicht, was das Training stabilisiert und beschleunigt:
model = keras.Sequential([
layers.Dense(256, input_shape=(784,)),
layers.BatchNormalization(),
layers.Activation('relu'),
layers.Dense(128),
layers.BatchNormalization(),
layers.Activation('relu'),
layers.Dense(10, activation='softmax')
])
8.3 Early Stopping
Das Training stoppt automatisch, wenn die Validation Loss nicht mehr sinkt:
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
callbacks = [
EarlyStopping(
monitor='val_loss',
patience=5, # Stoppt nach 5 Epochen ohne Verbesserung
restore_best_weights=True
),
ReduceLROnPlateau(
monitor='val_loss',
factor=0.5, # Lernrate halbieren
patience=3
)
]
history = model.fit(
X_train, y_train,
epochs=100,
batch_size=64,
validation_split=0.1,
callbacks=callbacks,
verbose=1
)
8.4 Regularisierung (L2)
from tensorflow.keras import regularizers
model = keras.Sequential([
layers.Dense(256, activation='relu',
kernel_regularizer=regularizers.l2(0.001),
input_shape=(784,)),
layers.Dense(10, activation='softmax')
])
8.5 Überblick Regularisierungstechniken
| Technik | Wann einsetzen | Keras |
|---|---|---|
| Dropout | Immer, besonders bei großen Netzen | layers.Dropout(rate) |
| Batch Normalization | Tiefe Netze, instabiles Training | layers.BatchNormalization() |
| Early Stopping | Immer | EarlyStopping(patience=n) |
| L2-Regularisierung | Wenn Overfitting trotz Dropout | regularizers.l2(λ) |
| Mehr Daten / Data Augmentation | Immer die beste Lösung | Siehe CNNs |
9. Convolutional Neural Networks (CNNs)
9.1 Motivation
Ein MLP auf einem 224×224 Farbbild hätte in der ersten Schicht bereits 224 × 224 × 3 = 150.528 Eingaben – das sind Millionen von Parametern, bevor das Netz auch nur eine Schicht tief ist. Außerdem ignoriert ein MLP die räumliche Struktur des Bildes völlig.
CNNs lösen beide Probleme durch lokale Verbindungen und gemeinsame Gewichte.
9.2 Der Faltungsoperator (Convolution)
Ein Filter (Kernel) der Größe k×k gleitet über das Bild und berechnet an jeder Position eine gewichtete Summe:
Eingabe (5×5): Filter (3×3): Ausgabe (Feature Map):
1 0 1 0 0 1 0 -1 · · ·
0 1 0 1 0 * 0 0 0 = · 4 ·
1 0 1 0 1 -1 0 1 · · ·
0 1 0 0 1
0 1 1 0 1
- Jeder Filter lernt ein bestimmtes Merkmal (Kante, Textur, Form)
- Viele Filter parallel → viele Feature Maps
- Gewichte werden beim Training gelernt (wie bei Dense-Schichten)
9.3 Wichtige CNN-Schichten
Conv2D – Faltungsschicht:
layers.Conv2D(
filters=32, # Anzahl der Filter
kernel_size=(3, 3), # Filtergröße
activation='relu',
padding='same' # Ausgabegröße = Eingabegröße
)
MaxPooling2D – Reduktionsschicht:
layers.MaxPooling2D(pool_size=(2, 2))
# Reduziert Breite und Höhe um Faktor 2
# Wählt den Maximalwert in jedem 2×2-Bereich
Flatten – Übergang zu Dense:
layers.Flatten()
# Wandelt 2D Feature Map in 1D-Vektor um
9.4 Typische CNN-Architektur
Eingabebild (28×28×1)
│
Conv2D (32 Filter, 3×3) → ReLU → (28×28×32)
│
MaxPooling (2×2) → (14×14×32)
│
Conv2D (64 Filter, 3×3) → ReLU → (14×14×64)
│
MaxPooling (2×2) → (7×7×64)
│
Flatten → (3136,)
│
Dense (128) → ReLU
│
Dropout (0.5)
│
Dense (10) → Softmax → (10,)
9.5 CNN für MNIST
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
# Daten laden und vorbereiten
(X_train, y_train), (X_test, y_test) = keras.datasets.mnist.load_data()
# Für CNNs: (n, 28, 28, 1) – Kanal-Dimension hinzufügen
X_train = X_train.reshape(-1, 28, 28, 1).astype('float32') / 255.0
X_test = X_test.reshape(-1, 28, 28, 1).astype('float32') / 255.0
# CNN-Modell
model = keras.Sequential([
# Block 1
layers.Conv2D(32, (3, 3), activation='relu', padding='same',
input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
# Block 2
layers.Conv2D(64, (3, 3), activation='relu', padding='same'),
layers.MaxPooling2D((2, 2)),
# Klassifikationskopf
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
model.summary()
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
history = model.fit(
X_train, y_train,
epochs=10,
batch_size=64,
validation_split=0.1
)
test_loss, test_acc = model.evaluate(X_test, y_test, verbose=0)
print(f"CNN Test Accuracy: {test_acc:.2%}") # Typisch: > 99%
10. Praktisches Projekt: Bildklassifikation mit CIFAR-10
10.1 Der CIFAR-10 Datensatz
CIFAR-10 enthält 60.000 Farbbilder (32×32 Pixel) in 10 Klassen:
Flugzeug, Auto, Vogel, Katze, Reh, Hund, Frosch, Pferd, Schiff, LKW
10.2 Data Augmentation
Da 50.000 Trainingsbilder für ein CNN relativ wenig sind, erweitern wir den Datensatz künstlich durch Data Augmentation – das Erzeugen leicht veränderter Kopien:
from tensorflow.keras.layers import RandomFlip, RandomRotation, RandomZoom
augmentation = keras.Sequential([
RandomFlip('horizontal'),
RandomRotation(0.1),
RandomZoom(0.1),
])
10.3 Vollständige Pipeline
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
import numpy as np
# ── 1. Daten laden ────────────────────────────────────────────────────────
(X_train, y_train), (X_test, y_test) = keras.datasets.cifar10.load_data()
X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0
klassen = ['Flugzeug', 'Auto', 'Vogel', 'Katze', 'Reh',
'Hund', 'Frosch', 'Pferd', 'Schiff', 'LKW']
# ── 2. Modell mit Data Augmentation ──────────────────────────────────────
model = keras.Sequential([
# Data Augmentation (nur während Training aktiv)
layers.RandomFlip('horizontal'),
layers.RandomRotation(0.1),
layers.RandomZoom(0.1),
# Block 1
layers.Conv2D(32, (3, 3), activation='relu', padding='same',
input_shape=(32, 32, 3)),
layers.BatchNormalization(),
layers.Conv2D(32, (3, 3), activation='relu', padding='same'),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
# Block 2
layers.Conv2D(64, (3, 3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.Conv2D(64, (3, 3), activation='relu', padding='same'),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
# Block 3
layers.Conv2D(128, (3, 3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.MaxPooling2D((2, 2)),
layers.Dropout(0.25),
# Klassifikationskopf
layers.Flatten(),
layers.Dense(256, activation='relu'),
layers.BatchNormalization(),
layers.Dropout(0.5),
layers.Dense(10, activation='softmax')
])
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=0.001),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# ── 3. Trainieren ─────────────────────────────────────────────────────────
callbacks = [
keras.callbacks.EarlyStopping(monitor='val_accuracy', patience=10,
restore_best_weights=True),
keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5)
]
history = model.fit(
X_train, y_train,
epochs=50,
batch_size=64,
validation_split=0.1,
callbacks=callbacks
)
# ── 4. Evaluieren ─────────────────────────────────────────────────────────
test_loss, test_acc = model.evaluate(X_test, y_test, verbose=0)
print(f"Test Accuracy: {test_acc:.2%}")
# ── 5. Einzelne Vorhersagen anzeigen ──────────────────────────────────────
y_pred = np.argmax(model.predict(X_test[:16]), axis=1)
fig, axes = plt.subplots(2, 8, figsize=(14, 4))
for i, ax in enumerate(axes.flat):
ax.imshow(X_test[i])
farbe = 'green' if y_pred[i] == y_test[i][0] else 'red'
ax.set_title(klassen[y_pred[i]], color=farbe, fontsize=8)
ax.axis('off')
plt.suptitle('CIFAR-10 Vorhersagen (grün=richtig, rot=falsch)')
plt.tight_layout()
plt.show()
11. Optimierer im Vergleich
11.1 SGD mit Momentum
Momentum „merkt" sich die Richtung der letzten Updates und beschleunigt das Training in konsistenten Richtungen:
optimizer = keras.optimizers.SGD(learning_rate=0.01, momentum=0.9)
11.2 Adam
Adam (Adaptive Moment Estimation) ist der Standard-Optimierer für Deep Learning. Er passt die Lernrate automatisch für jeden Parameter an:
optimizer = keras.optimizers.Adam(learning_rate=0.001) # Standard
11.3 Vergleich
| Optimierer | Lernrate | Konvergenz | Wann einsetzen |
|---|---|---|---|
| SGD | Manuell | Langsam, stabil | Wenn man Kontrolle will |
| SGD + Momentum | Manuell | Schneller | CNNs, fine-tuning |
| Adam | Adaptiv | Schnell | Standard, fast immer |
| RMSprop | Adaptiv | Gut | Rekurrente Netze |
12. Transfer Learning
12.1 Grundidee
Große vortrainierte Netze (z.B. VGG16, ResNet, MobileNet) wurden auf Millionen von Bildern trainiert und haben dabei gelernt, allgemeine Bildmerkmale zu erkennen (Kanten, Formen, Texturen). Dieses Wissen können wir wiederverwenden.
Vortrainiertes Netz (ImageNet, 1.000 Klassen)
│
├── Frühe Schichten: allgemeine Merkmale (Kanten, Texturen)
├── Mittlere Schichten: komplexere Formen
└── Späte Schichten: aufgabenspezifische Merkmale
Transfer Learning:
1. Vortrainiertes Netz laden
2. Letzte Schichten einfrieren (freeze)
3. Neuen Klassifikationskopf hinzufügen
4. Nur den Kopf trainieren (wenige Epochen)
12.2 Implementierung mit MobileNetV2
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
# ── 1. Basis-Modell laden (ohne Klassifikationskopf) ─────────────────────
base_model = keras.applications.MobileNetV2(
input_shape=(96, 96, 3),
include_top=False, # Ohne letzten Dense-Schichten
weights='imagenet' # Vortrainierte Gewichte laden
)
# Basis-Modell einfrieren
base_model.trainable = False
# ── 2. Neuen Kopf hinzufügen ──────────────────────────────────────────────
inputs = keras.Input(shape=(96, 96, 3))
x = keras.applications.mobilenet_v2.preprocess_input(inputs)
x = base_model(x, training=False)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.3)(x)
outputs = layers.Dense(10, activation='softmax')(x) # 10 eigene Klassen
model = keras.Model(inputs, outputs)
# ── 3. Nur den Kopf trainieren ────────────────────────────────────────────
model.compile(
optimizer=keras.optimizers.Adam(0.001),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# model.fit(X_train, y_train, epochs=10, ...)
# ── 4. Fine-Tuning: Obere Schichten des Basismodells freigeben ────────────
base_model.trainable = True
# Nur die letzten 20 Schichten trainieren
for layer in base_model.layers[:-20]:
layer.trainable = False
model.compile(
optimizer=keras.optimizers.Adam(1e-5), # Sehr kleine Lernrate!
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# model.fit(X_train, y_train, epochs=5, ...)
12.3 Wann Transfer Learning einsetzen?
Wenige eigene Daten + ähnliche Aufgabe → Feature Extraction (Basis einfrieren)
Wenige eigene Daten + andere Aufgabe → Transfer Learning + Fine-Tuning
Viele eigene Daten → Fine-Tuning oder eigenes Netz
13. Zusammenfassung und Ausblick
Überblick
Deep Learning
│
├── Grundbausteine
│ ├── Neuron: z = wᵀx + b, y = f(z)
│ ├── Aktivierung: ReLU (standard), Sigmoid, Softmax
│ └── Loss: Cross-Entropy (Klass.), MSE (Regr.)
│
├── Training
│ ├── Backpropagation + Gradientenabstieg
│ ├── Optimierer: Adam (standard)
│ └── Regularisierung: Dropout, BatchNorm, Early Stopping
│
├── Architekturen
│ ├── MLP / Dense: Tabellarische Daten
│ └── CNN: Bilder, räumliche Daten
│
└── Fortgeschritten
└── Transfer Learning: Vortrainierte Modelle wiederverwenden
Checkliste für ein Deep-Learning-Projekt
✅ Daten normalisieren (Pixel / 255 oder StandardScaler)
✅ Architektur zur Aufgabe wählen (Bilder → CNN, sonst MLP)
✅ Mit einfachem Modell beginnen, dann komplexer werden
✅ Dropout und BatchNorm gegen Overfitting einsetzen
✅ Early Stopping mit restore_best_weights aktivieren
✅ Trainingsverlauf (Loss + Accuracy) visualisieren
✅ Bei wenig Daten: Transfer Learning in Betracht ziehen
✅ Data Augmentation bei Bilddaten nutzen
Ausblick: Nächste Themen
- Natural Language Processing: Textvorverarbeitung, Embeddings, Transformer
- Rekurrente Netze (RNNs, LSTMs): Zeitreihen und Sequenzen
- Generative Modelle: GANs, Variational Autoencoders
- MLOps: Modelle versionieren, deployen und überwachen
Anhang: Schnellreferenz Keras
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
# ── Modell aufbauen ────────────────────────────────────────────────────────
model = keras.Sequential([
layers.Dense(128, activation='relu', input_shape=(n_features,)),
layers.Dropout(0.3),
layers.Dense(64, activation='relu'),
layers.Dense(n_classes, activation='softmax') # oder 'sigmoid' für binär
])
# ── CNN-Block ──────────────────────────────────────────────────────────────
cnn_block = [
layers.Conv2D(32, (3,3), activation='relu', padding='same'),
layers.BatchNormalization(),
layers.MaxPooling2D((2,2)),
layers.Dropout(0.25),
]
# ── Kompilieren ────────────────────────────────────────────────────────────
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy', # Integer-Labels
metrics=['accuracy']
)
# ── Trainieren ─────────────────────────────────────────────────────────────
history = model.fit(X_train, y_train,
epochs=50, batch_size=64,
validation_split=0.1,
callbacks=[
keras.callbacks.EarlyStopping(patience=5,
restore_best_weights=True)
])
# ── Evaluieren und Vorhersagen ─────────────────────────────────────────────
loss, acc = model.evaluate(X_test, y_test)
y_pred_proba = model.predict(X_test)
y_pred = y_pred_proba.argmax(axis=1)
# ── Modell speichern / laden ───────────────────────────────────────────────
model.save('mein_modell.keras')
model = keras.models.load_model('mein_modell.keras')
HTL Pinkafeld – IF/IT | Data Science & AI | 12. Schulstufe