Das Problem: ML ist mehr als Modellierung
Viele ML-Projekte scheitern nicht an schlechten Modellen, sondern an falschen Fragestellungen:
- Falsche Metrik optimiert: Accuracy auf unbalancierten Daten ist irreführend
- Stakeholder ignoriert: Das Safety-Team hat andere Prioritäten als das Product-Team
- Fehlerkosten nicht berücksichtigt: Ein übersehenes Stop-Schild ist kritischer als ein verwechseltes Speed-Limit
- Evaluation oberflächlich: 95% Accuracy versteckt 50% Fehlerrate auf seltenen Klassen
Warum Traffic Sign Recognition?
Verkehrsschilderkennung ist ein perfektes Lehrbeispiel:
| Herausforderung | Relevanz |
|---|---|
| 43 Klassen | Multi-Class Classification |
| Klassenimbalance | 10x Unterschied zwischen häufigen und seltenen Schildern |
| Ähnliche Klassen | Speed Limits unterscheiden sich nur in Zahlen |
| Safety-kritisch | Übersehenes Stop-Schild = potentieller Unfall |
| Reale Variationen | Beleuchtung, Blur, Verdeckung |
Die Lösung: Interaktives ML-Pipeline Dashboard
Ein Streamlit-Dashboard, das den kompletten ML-Workflow lehrt – vom Problem Framing bis zur Fehleranalyse.
Architektur
┌─────────────────────────────────────────────────────────────────┐
│ GTSRB ML PIPELINE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Problem │ │ Data │ │ Dataset │ │
│ │ Framing │──│ Exploration │──│ Split │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Stakeholder Klassen- Stratified │ │
│ │ Analyse Verteilung vs Random │ │
│ │ │ │
│ │ Metrik- Daten- Data Leakage │ │
│ │ Auswahl Challenges Prevention │ │
│ │ │ │
│ │ Success Sample Cross- │ │
│ │ Criteria Browser Validation │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Model │ │ Evaluation │ │
│ │ Training │──│ & Errors │ │
│ └─────────────┘ └─────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ CNN mit Confusion Misclassified │ │
│ │ BatchNorm Matrix Examples │ │
│ │ │ │
│ │ Class Per-Class Critical │ │
│ │ Weights Metrics Classes │ │
│ │ │ │
│ │ Training Error Confused │ │
│ │ Curves Analysis Pairs │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Seite 1: Problem Framing
Kernfrage: Wer nutzt das Modell und was ist ihnen wichtig?
Stakeholder-Analyse
┌─────────────────────────────────────────────────────────────────┐
│ STAKEHOLDER PRIORITIES │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 👤 Vehicle Safety Team │
│ ├─ Priorität: Keine übersehenen kritischen Schilder │
│ ├─ Metrik: Recall auf Stop, No Entry, Yield │
│ └─ Risikotoleranz: Niedrig – Safety First │
│ │
│ 👤 Product Team │
│ ├─ Priorität: Balance zwischen Genauigkeit und Performance │
│ ├─ Metrik: F1-Score, Inference Time │
│ └─ Risikotoleranz: Mittel – User Experience │
│ │
│ 👤 Regulatory / Homologation │
│ ├─ Priorität: Nachweisbare Mindestanforderungen │
│ ├─ Metrik: Per-Class Accuracy Thresholds │
│ └─ Risikotoleranz: Keine – Muss Standards erfüllen │
│ │
│ 👤 ML Engineering Team │
│ ├─ Priorität: Robustheit und Wartbarkeit │
│ ├─ Metrik: Cross-Validation Stabilität, Kalibrierung │
│ └─ Risikotoleranz: Mittel – Technical Debt │
│ │
└─────────────────────────────────────────────────────────────────┘
Metrik-Auswahl
| Metrik | Formel | Wann nutzen? | Limitation |
|---|---|---|---|
| Accuracy | (TP+TN)/Total | Balancierte Daten | Irreführend bei Imbalance |
| Precision | TP/(TP+FP) | False Positives sind teuer | Ignoriert False Negatives |
| Recall | TP/(TP+FN) | False Negatives sind teuer | Ignoriert False Positives |
| F1-Score | 2×(P×R)/(P+R) | Balance zwischen P und R | Ignoriert True Negatives |
| Macro F1 | Ø F1 aller Klassen | Alle Klassen gleich wichtig | Seltene Klassen übergewichtet |
Kritische Klassen identifizieren
🔴 SAFETY-KRITISCH (hoher Recall erforderlich):
- Klasse 14: Stop
- Klasse 17: No Entry
- Klasse 13: Yield
- Klasse 1: Speed Limit 30 (Schulzonen)
🟡 VERWECHSLUNGSGEFAHR (oft konfundiert):
- Klassen 0-8: Speed Limits (nur Zahlen unterscheiden sich)
- Klassen 33-37: Richtungspfeile (ähnliche Muster)
Seite 2: Data Exploration
Kernfrage: Welche Herausforderungen stecken in den Daten?
Klassenverteilung
Samples pro Klasse:
┌────────────────────────────────────────────────────────────────┐
│ Klasse 2 (50 km/h) ████████████████████████████ 2250 │
│ Klasse 1 (30 km/h) ████████████████████████████ 2220 │
│ Klasse 38 (Keep right) ████████████████████████████ 2070 │
│ ... │
│ Klasse 0 (20 km/h) ███ 210 │
│ Klasse 19 (Curve left) ███ 210 │
│ Klasse 37 (Go left) ███ 210 │
└────────────────────────────────────────────────────────────────┘
Imbalance Ratio: 10.7x (2250 vs 210 Samples)
Daten-Challenges
| Challenge | Problem | Mitigation |
|---|---|---|
| Klassenimbalance | Modell ignoriert seltene Klassen | Class Weights, Oversampling |
| Beleuchtungsvarianz | Dunkel/Hell/Gegenlicht | Data Augmentation |
| Motion Blur | Bewegungsunschärfe | Blur Augmentation |
| Partielle Verdeckung | Äste, andere Schilder | Cutout Augmentation |
| Ähnliche Klassen | Speed Limits fast identisch | Hard Example Mining |
Seite 3: Dataset Split
Kernfrage: Wie organisiere ich Daten, um Overfitting zu vermeiden?
Die drei Splits
┌─────────────────────────────────────────────────────────────────┐
│ │
│ TRAINING SET (60-80%) │
│ └─ Modell lernt Muster │
│ │
│ VALIDATION SET (10-20%) │
│ └─ Hyperparameter tunen (Epochs, Learning Rate, etc.) │
│ │
│ TEST SET (10-20%) │
│ └─ Finale Evaluation – NUR EINMAL verwenden! │
│ │
└─────────────────────────────────────────────────────────────────┘
Stratification bei Imbalance
OHNE Stratification: MIT Stratification:
┌──────────────────────┐ ┌──────────────────────┐
│ Train: 60% Klasse A │ │ Train: 50% Klasse A │
│ Val: 80% Klasse A │ ←BAD │ Val: 50% Klasse A │ ←GOOD
│ Test: 40% Klasse A │ │ Test: 50% Klasse A │
└──────────────────────┘ └──────────────────────┘
Ohne Stratification kann die Validation Set Verteilung
stark von der Training Set Verteilung abweichen!
Data Leakage vermeiden
❌ FALSCH:
1. Alle Daten normalisieren
2. Dann splitten
→ Test Set "sieht" Training-Statistiken
✅ RICHTIG:
1. Erst splitten
2. Nur Training Set Statistiken berechnen
3. Diese auf Val/Test anwenden
Seite 4: Model Training
Kernfrage: Wie trainiere ich ein Modell, das generalisiert?
Modell-Auswahl
Nutzer können zwischen drei Modelltypen wählen:
┌─────────────────────────────────────────────────────────────────┐
│ MODELL-VERGLEICH │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 📊 Logistic Regression │
│ ├─ Komplexität: Niedrig │
│ ├─ Training: Schnell (Sekunden) │
│ ├─ Funktionsweise: Lineare Entscheidungsgrenzen │
│ └─ Best für: Baseline, schnelle Experimente │
│ │
│ 📈 Polynomial Regression │
│ ├─ Komplexität: Mittel │
│ ├─ Training: Mittel (Minuten) │
│ ├─ Funktionsweise: PCA + Polynomiale Features + Linear │
│ └─ Best für: Nicht-lineare Muster ohne Deep Learning │
│ │
│ 🧠 Neural Network (CNN) │
│ ├─ Komplexität: Hoch │
│ ├─ Training: Langsam (Minuten-Stunden) │
│ ├─ Funktionsweise: Lernt hierarchische Features automatisch │
│ └─ Best für: Beste Genauigkeit, Bildklassifikation │
│ │
└─────────────────────────────────────────────────────────────────┘
CNN Architektur
Input: 32×32×3 RGB
│
▼
┌─────────────────────────────────┐
│ Conv Block 1 │
│ Conv2d(3→32) + BN + ReLU │
│ Conv2d(32→32) + BN + ReLU │
│ MaxPool(2×2) + Dropout(0.25) │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Conv Block 2 │
│ Conv2d(32→64) + BN + ReLU │
│ Conv2d(64→64) + BN + ReLU │
│ MaxPool(2×2) + Dropout(0.25) │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Conv Block 3 │
│ Conv2d(64→128) + BN + ReLU │
│ Conv2d(128→128) + BN + ReLU │
│ MaxPool(2×2) + Dropout(0.25) │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Classifier │
│ Flatten │
│ Linear(2048→512) + BN + ReLU │
│ Dropout(0.5) │
│ Linear(512→43) │
└─────────────────────────────────┘
│
▼
Output: 43 Klassen
Class Weights für Imbalance
# Problem: Seltene Klassen werden ignoriert
# Lösung: Höheres Gewicht für seltene Klassen
class_counts = [2250, 2220, ..., 210, 210] # Samples pro Klasse
class_weights = 1.0 / class_counts # Inverse Häufigkeit
class_weights = normalize(class_weights) # Normalisieren
# CrossEntropyLoss mit Gewichten
criterion = nn.CrossEntropyLoss(weight=class_weights)
Seite 5: Evaluation
Kernfrage: Wo versagt das Modell und warum?
Confusion Matrix
PREDICTED
0 1 2 3 ...
┌───┬───┬───┬───┬─────┐
0 │95%│ 3%│ 1%│ 1%│ │ ← Speed 20
T 1 │ 5%│90%│ 3%│ 2%│ │ ← Speed 30
R 2 │ 2%│ 4%│92%│ 2%│ │ ← Speed 50
U 3 │ 1%│ 2%│ 3%│93%│ │ ← Speed 60
E ...│ │ │ │ │ │
└───┴───┴───┴───┴─────┘
Speed Limits werden oft untereinander verwechselt!
Per-Class Metrics
Klasse Precision Recall F1-Score Support
──────────────────────────────────────────────
0 0.89 0.78 0.83 60
1 0.94 0.96 0.95 720
2 0.95 0.97 0.96 750
...
14 0.98 0.99 0.99 270 ← Stop (kritisch!)
17 0.97 0.98 0.98 360 ← No Entry (kritisch!)
...
19 0.72 0.65 0.68 60 ← Schwach!
37 0.75 0.70 0.72 60 ← Schwach!
Error Analysis
TOP VERWECHSLUNGSPAARE:
┌─────────────────────────────────────────────────────────────────┐
│ Speed 30 → Speed 50 │ 45 Fehler │ Gleiche Kategorie │
│ Speed 50 → Speed 30 │ 38 Fehler │ Gleiche Kategorie │
│ Speed 70 → Speed 80 │ 32 Fehler │ Gleiche Kategorie │
│ Turn right → Go straight │ 12 Fehler │ ⚠️ Cross-Category! │
│ Yield → Priority │ 8 Fehler │ ⚠️ Cross-Category! │
└─────────────────────────────────────────────────────────────────┘
Cross-Category Fehler sind kritischer als Same-Category Fehler!
Technische Umsetzung
Tech Stack
| Komponente | Technologie |
|---|---|
| Frontend | Streamlit |
| Visualisierung | Plotly |
| ML Framework | PyTorch |
| Data Processing | NumPy, Pandas, scikit-learn |
| Dataset | GTSRB (43 Klassen, 51k Bilder) |
Key Features
- Demo Mode: Funktioniert ohne echten Datensatz
- Interaktiv: Hyperparameter live anpassen
- Visuell: Alle Konzepte mit Grafiken erklärt
- Educational: Best Practices und Anti-Patterns
Key Takeaways
Problem Framing
- Stakeholder zuerst – Verschiedene Nutzer haben verschiedene Prioritäten
- Accuracy ist nicht alles – Besonders bei unbalancierten Daten
- Fehlerkosten berücksichtigen – Manche Fehler sind teurer als andere
Data Handling
- Imbalance behandeln – Class Weights, Stratification
- Splits respektieren – Test Set ist heilig
- Data Leakage vermeiden – Split vor Preprocessing
Evaluation
- Per-Class analysieren – Gesamtmetriken verstecken Probleme
- Confusion Matrix studieren – Zeigt Fehlermuster
- Echte Fehler anschauen – Bilder zeigen das “Warum”
Tech Stack: PyTorch, Streamlit, Plotly, scikit-learn
Dataset: German Traffic Sign Recognition Benchmark (GTSRB)
Interesse am Code? GitHub Repository