Ultralytics YOLO27: Trag dich in die Warteliste ein.
Get Started
Leistungsstarke YOLO-Datensätze erstellen·Trainieren und iterieren·Lektion 8/10
LektionAnfänger

Erkennen, wann der Datensatz bereit ist

Mache den ersten Trainingslauf von acht bestandenen oder nicht bestandenen Prüfungen abhängig, automatisiere die drei Prüfungen, die sich per Skript verifizieren lassen, und finde heraus, welche Korrektur bei jedem Fehlschlag nötig ist.

Bei jedem Projekt kommt der Moment, in dem das Team trainieren möchte. Manchmal ist der Datensatz bereit; manchmal enthält er noch eine undichte Aufteilung oder eine unterbeschriftete Klasse, was eine Woche GPU-Zeit verschwendet und einen Wert liefert, dem niemand vertrauen sollte. Acht Prüfungen, die jeweils mit Ja, Nein oder einer dokumentierten Ausnahme bewertet werden, machen diese Entscheidung objektiv statt von der Stimmung abhängig.

Lernergebnis

Bewerte deinen Datensatz anhand der acht Prüfungen zur Einsatzbereitschaft; lass die drei zählbaren Prüfungen von einem Skript verifizieren und triff entweder eine Freigabeentscheidung oder erstelle eine nach Priorität geordnete Liste der nötigen Korrekturen.

Schnellkurs
Wenn du dich bereits auskennst, findest du hier die Kurzfassung.
  1. Bewerte alle acht Prüfungen mit Ja, Nein oder einer dokumentierten Ausnahme.

  2. Lass readiness.py den Umfang, Datenüberschneidungen, die Abdeckung der Aufteilungen und den Anteil an Hintergrundbildern bewerten.

  3. Behebe jedes Nein in den Daten, nicht mit Hyperparametern.

  4. Gib das Projekt nur dann mit einer bekannten Lücke frei, wenn deren erwartete Auswirkungen schriftlich festgehalten sind.

Praxisnah

Die acht Prüfungen#

#PrüfungBestehenskriterienBei einem Fehlschlag zurück zu
1Klares ZielZiel, Aufgabe, Klassen und Abnahmetest sind schriftlich festgehalten und abgestimmtBeginne mit dem Geschäftsziel
2Definierte KlassenFür jede Klasse gibt es eine Definition und ein benanntes ähnliches Objekt, das nicht dazugehörtZiel und Beschriftungsleitfaden
3Repräsentative BilderJedes Szenario der Spezifikation erfüllt seine Quote; die meisten Bilder stammen aus dem ProduktiveinsatzErfasse hochwertige, repräsentative Daten
4Ausreichender Umfang≥ 1.500 Bilder und ≥ 10.000 Instanzen pro Klasse oder eine dokumentierte AusnahmeSpezifikation und Datenerfassung
5Einheitliche BeschriftungenLeitfaden verfasst, Kalibrierungsrunde abgeschlossen, Übereinstimmung ≥ 90 %Bewährte Verfahren für die Annotation
6Qualitätskontrolle abgeschlossenPrüfskript ohne Beanstandungen, Verdachtsfälle überprüft, QC-Notizen verfasstQualitätskontrolle des Datensatzes
7Saubere AufteilungenGruppenbasierte Aufteilung, keine Gruppe in zwei Aufteilungen, jede Klasse in jeder AufteilungTeile den Datensatz richtig auf
8Hintergrundbilder0–10 % der Bilder sind leere, also ohne Objekte beschriftete EinzelbilderSpezifikation und Datenerfassung

Die Checkliste prüft dieselben Entscheidungen, die der Leitfaden zur Datenerfassung und Annotation einzeln behandelt; hier werden sie zu einer einzigen Freigabeentscheidung zusammengeführt.

Zählbare Prüfungen automatisieren#

Die Prüfungen 4, 7 und 8 sind reine Berechnungen, daher bewertet ein Skript sie jedes Mal auf dieselbe Weise. Dieses Skript liest den Übungsdatensatz und die Aufteilungslisten ein, die group_split.py in der vorherigen Lektion erstellt hat:

from collections import Counter
from pathlib import Path

root = Path("datasets/practice")  # images/, labels/, and the train/val/test.txt lists from group_split.py
splits = {s: [Path(p).stem for p in (root / f"{s}.txt").read_text().split()] for s in ("train", "val", "test")}

def classes(stem):
    label = root / "labels" / f"{stem}.txt"
    return [int(r.split()[0]) for r in label.read_text().splitlines() if r.strip()] if label.exists() else []

stems = [s for split in splits.values() for s in split]
instances = Counter(c for s in stems for c in classes(s))
images = Counter(c for s in stems for c in set(classes(s)))
background = sum(not classes(s) for s in stems) / len(stems)
groups = {split: {s.rsplit("_", 1)[0] for s in names} for split, names in splits.items()}
per_split = {split: {c for s in names for c in classes(s)} for split, names in splits.items()}
shared = (groups["train"] & groups["val"]) | (groups["train"] & groups["test"]) | (groups["val"] & groups["test"])
weakest = min(instances, key=lambda c: (images[c], instances[c]))

checks = {
    "4 volume": (images[weakest] >= 1500 and instances[weakest] >= 10_000,
                 f"weakest class {weakest}: {images[weakest]} images, {instances[weakest]} instances"),
    "7 no shared groups": (not shared, f"{len(shared)} groups appear in more than one split"),
    "7 every class in every split": (all(per_split[s] == set(instances) for s in splits),
                                     ", ".join(f"{s} misses {len(set(instances) - per_split[s])}" for s in splits)),
    "8 background 0-10%": (background <= 0.10, f"{background:.1%} background images"),
}
for name, (ok, detail) in checks.items():
    print(f"{'PASS' if ok else 'FAIL'}  {name:<29} {detail}")
FAIL  4 volume                      weakest class 30: 1 images, 1 instances
PASS  7 no shared groups            0 groups appear in more than one split
FAIL  7 every class in every split  train misses 5, val misses 36, test misses 41
PASS  8 background 0-10%            1.6% background images

Die gruppenbasierte Aufteilung hat die Datenüberschneidung beseitigt, aber der Übungsdatensatz ist noch lange nicht bereit: Die schwächste Klasse (30, skis) hat nur eine beschriftete Instanz, und die Validierung kann die Hälfte der Klassen nicht bewerten. Das ist das zu erwartende Urteil für 128 Demobilder und genau das Urteil, das diese Prüfung vor einer Trainingswoche liefern soll.

Ein sauberes Skript ist keine vollständig ausgefüllte Checkliste

Das Skript deckt ab, was sich zählen lässt. Für die Prüfungen 1, 2, 3, 5 und 6 braucht es einen Menschen: ein vereinbartes Ziel, schriftliche Definitionen, die Abdeckung der Spezifikation, einen gemessenen Übereinstimmungswert und QC-Notizen. Bewerte sie manuell und halte jeweils einen Beleg fest.

Entscheide: trainieren, mit einer Lücke freigeben oder korrigieren#

Wenn eine Prüfung fehlschlägt, ist der verlockende nächste Schritt fast immer etwas anderes, als die Daten zu korrigieren:

Verlockende AbkürzungWarum sie nicht funktioniert
„Versuch es mit einem größeren Modell.“Ein größeres Modell lernt Beschriftungsfehler genauso zuverlässig.
„Stimme die Lernrate ab.“Keine Optimierereinstellung ergänzt eine fehlende Klasse oder ein fehlendes Szenario.
„Trainiere mit mehr Epochen.“Mit mehr Epochen auf wenig vielfältigen Daten kommt es schneller zu Überanpassung.
„Füge mehr Datenaugmentation hinzu.“Datenaugmentation kann keine Szenarien erzeugen, die im Datensatz nie enthalten waren.

Drei Fälle, in denen der Datensatz fast bereit ist#

MusterNicht bestandene PrüfungWoran es zu erkennen istLösung
Umfang ohne Vielfalt35.000 Bilder, eine Kamera, keine GrenzfälleErfasse vor dem Training Bilder von mehr Kameras, Standorten und Zeitpunkten
Vielfalt ohne Einheitlichkeit5Annotatoren sind sich über Boxausdehnung und Verdeckung uneinigVervollständige den Leitfaden, kalibriere die Annotationen und beschrifte die betroffenen Beispiele neu
Unbemerkte Datenüberschneidung7Zufällige Aufteilung einzelner VideobilderErneut nach Clip, Kamera oder Tag aufteilen; rechne mit einem niedrigeren mAP auf dem Validierungsdatensatz, denn dieser Rückgang entspricht der Realität

Mit einer bekannten Lücke ausliefern#

Oft ist ein gezieltes erstes Modell die richtige Entscheidung, bevor alle Prüfungen bestanden sind: ein Pilotprojekt, ein Prototyp oder eine erste Version für einen Teil der Kameras. Ein Modell im Produktivbetrieb zeigt schneller, was tatsächlich nicht stimmt, als wenn du den Datensatz im Dunkeln weiter optimierst. Wenn du mit einer Lücke auslieferst, halte drei Dinge fest:

  • Welche Prüfung fehlgeschlagen ist.
  • Die erwarteten Auswirkungen, zum Beispiel „keine Nachtdaten; rechne nach Einbruch der Dunkelheit mit geringerer Trefferquote“.
  • Der Erfassungsplan, mit dem du die Lücke schließt, während Version 1 läuft.
Eine Ausnahme ohne Folgenabschätzung ist nur eine übersprungene Prüfung

„Umfang: Ausnahme“ sagt der nächsten Person nichts. „Umfang: pallet mit 700 Instanzen; geringere Erkennungsrate bei Paletten in vollen Lagerbuchten zu erwarten; bis Juni 2.000 weitere gekennzeichnet“ beschreibt ein gesteuertes Risiko. Für jede Ausnahme müssen die erwarteten Auswirkungen auf den Abnahmetest angegeben werden.

Vor jedem erneuten Training erneut prüfen#

Modellqualität im Zeitverlauf: Die Qualität bleibt stabil, solange neue annotierte Daten hinzukommen, und sinkt dann nach dem erwarteten Zeitpunkt des Rückgangs. Dadurch stellt sich die Frage, ob jetzt erneut trainiert oder noch gewartet werden sollte

Ein Datensatz, der für Version 1 bereit war, ist nicht automatisch auch für Version 3 geeignet. Neue Klassen, neue Quellen und neue Annotatoren können jeweils eine Prüfung zum Scheitern bringen, die zuvor bestanden wurde. Außerdem verändern sich die Produktionsdaten, während immer mehr neue Annotationen hinzukommen. Führe vor jedem erneuten Training readiness.py erneut aus und bewerte die manuellen Prüfungen noch einmal; das dauert nur wenige Minuten. Wenn du darauf verzichtest, kann dich das eine Woche Training mit einem fehlerhaften Datensatz kosten.

Ausprobieren

Führe readiness.py auf deinem aufgeteilten Datensatz (oder dem Übungsdatensatz) aus und bewerte anschließend die fünf manuellen Prüfungen selbst, jeweils mit einer Zeile als Beleg. Ordne jede fehlgeschlagene Prüfung danach, wie stark sie den Abnahmetest gefährdet. Ergebnis: eine bewertete Checkliste mit acht Zeilen und einer Freigabeentscheidung oder einer priorisierten Liste der nötigen Korrekturen, gespeichert neben den QC-Notizen.

Abgeschlossen, wenn
Du hast die Lektion abgeschlossen, wenn alle folgenden Punkte zutreffen.
  • Alle acht Prüfungen sind bewertet und mit je einer Zeile belegt; die drei quantifizierbaren Ergebnisse stammen aus dem Skript.

  • Für jede Ausnahme sind ihre erwarteten Auswirkungen auf den Abnahmetest und ein Plan zu ihrer Behebung angegeben.

  • Die Entscheidung (trainieren, mit einer dokumentierten Lücke ausliefern oder zuerst korrigieren) ist zusammen mit der Checkliste festgehalten.

Lösung anzeigen

Eine bewertete Checkliste für den Übungsdatensatz:

#PrüfungBewertungBeleg
1Klares Zieljaobjective.md und acceptance_test.py aus Lektion 1
2Definierte KlassenneinFür die 80 Klassen von COCO gibt es weder schriftliche Definitionen noch Angaben zu auszuschließenden ähnlichen Objekten
3Repräsentative Bilderneincoverage.py: cam2–cam4 liegen unter der Mindestanzahl
4Ausreichender Umfangneinreadiness.py: Die schwächste Klasse hat 1 Bild
5Einheitliche AnnotationenneinÜbereinstimmung von 47 % in der Kalibrierungsrunde
6QC abgeschlossenteilweisePrüfung durchgeführt; Verdachtsfälle in 000000000438.jpg noch offen
7Saubere AufteilungenneinKeine gemeinsamen Gruppen, aber im Validierungsdatensatz fehlen 36 von 71 Klassen
8Hintergrundbilderja1.6%

Entscheidung: zuerst korrigieren. Nach Risiko für den Abnahmetest geordnet: (1) die Klassenliste auf die für das Ziel benötigten Klassen beschränken; damit werden die Prüfungen 2, 4 und 7 zugleich vereinfacht; (2) mehr Gruppen für diese Klassen sammeln; (3) die Regel im Leitfaden zu Personen in der Ferne fertigstellen und die Annotationen korrigieren. Bei einem Demodatensatz fällt diese Prüfung zu Recht durch.

Wie es weitergeht

Sobald die Checkliste bestanden ist, wird in der nächsten Lektion eine Feinabstimmung als Baseline durchgeführt und aus den Ergebnissen die nächste Korrektur am Datensatz abgeleitet.