Die ML-Pipeline
Egal ob Logistic Regression oder CNN — der Weg von 54.000 Fotos zu einer belastbaren Zahl ist immer derselbe. Wer diese Pipeline einmal sauber verinnerlicht, erkennt 80 % aller ML-Fehler sofort: Es sind fast immer Reihenfolge-Fehler.
Eiserne Regel: Alles, was aus den Daten gelernt wird (Skalierung, Modell, Feature-Auswahl), darf nur die Trainingsdaten sehen. Test-Daten sind tabu, bis die allerletzte Zahl berichtet wird.
Die sechs Schritte
1
Daten laden
Bilder + Labels aus der Ordnerstruktur einlesen. Ordnername = Klasse.
2
Split: Train / Validation / Test
Z.B. 70/15/15 — stratifiziert, damit jede der 38 Klassen in jedem Teil im gleichen Verhältnis vorkommt.
3
Preprocessing
Bilder skalieren, Features extrahieren, normalisieren. Scaler wird nur auf Train gefittet, dann auf alles angewendet.
4
Training
Das Verfahren lernt seine Parameter aus den Trainingsdaten — Gewichte, Splits oder Filter, je nach Modell.
5
Validierung & Tuning
Hyperparameter (C, n_estimators, Lernrate…) am Validation-Set vergleichen — so oft du willst.
6
Finale Evaluation
Genau einmal auf dem Test-Set messen. Diese Zahl kommt in den Bericht.
In Python: Dateiliste + stratifizierter Split
Für die klassischen Verfahren sammeln wir erst Pfade und Labels, gesplittet wird bevor irgendetwas berechnet wird:
PYTHONsplit.py
from pathlib import Path
from sklearn.model_selection import train_test_split
DATA_DIR = Path("plantvillage dataset/color")
pfade, labels = [], []
for klassen_ordner in sorted(DATA_DIR.iterdir()):
for bild in klassen_ordner.glob("*.jpg"):
pfade.append(bild)
labels.append(klassen_ordner.name)
# 70 % Train, 30 % Rest — stratify hält die Klassenverhältnisse
X_train, X_rest, y_train, y_rest = train_test_split(
pfade, labels, test_size=0.30, stratify=labels, random_state=42
)
# Rest nochmal halbieren: 15 % Validation, 15 % Test
X_val, X_test, y_val, y_test = train_test_split(
X_rest, y_rest, test_size=0.50, stratify=y_rest, random_state=42
)
print(len(X_train), len(X_val), len(X_test)) # ~38000, ~8150, ~8150Warum eigentlich? — Warum ist das Test-Set heilig?
Das Test-Set simuliert Zukunft: Daten, die das Modell im Einsatz sehen wird und die heute niemand kennt. Jedes Mal, wenn du eine Entscheidung anhand des Test-Scores triffst („mit C=10 ist Test besser, nehmen wir!“), fließt Information aus dem Test-Set ins Modell — und der Score wird zur Selbsttäuschung. Genau dafür existiert das Validation-Set: Es ist das Test-Set, das du verbrauchen darfst.
Häufiger Denkfehler — Data Leakage — der Klassiker
Leakage = Information aus Validation/Test sickert ins Training. Die zwei häufigsten Varianten:
- Scaler auf allem fitten:
scaler.fit(X)vor dem Split berechnet Mittelwert und Streuung auch aus Test-Daten. Richtig:scaler.fit(X_train), dannscaler.transform(X_test). - Near-Duplicates über den Split: PlantVillage enthält teils mehrere Fotos desselben Blatts. Landet eins in Train und eins in Test, prüft der Test nur noch Wiedererkennen statt Generalisieren — die Scores werden künstlich gut.
Tiefer rein — Cross-Validation statt festem Validation-Set
Bei kleinen Datasets verschenkt ein festes Validation-Set wertvolle Trainingsdaten. k-Fold Cross-Validation teilt Train in k Stücke, trainiert k-mal (jedes Stück einmal als Validierung) und mittelt die Scores. Bei 54.000 Bildern ist das für die klassischen Verfahren machbar (
cross_val_score in scikit-learn), beim CNN meist zu teuer — dort bleibt es beim festen Split. Das Test-Set bleibt in beiden Welten unangetastet.