Jede Aufgabe bewerten und produktiv einsetzen
Lege für jede Aufgabe eine eigene Freigabeschwelle anhand ihrer Metrik bei der Einsatzauflösung fest, validiere alle Aufgaben in einer Schleife und exportiere jede Aufgabe nach ONNX. Prüfe anschließend die Vorhersage.
Für jede Aufgabe gilt eine eigene Definition von Korrektheit: Pixelüberlappung, Keypoint-Ähnlichkeit, IoU gedrehter Boxen, ein Treffer bei Top-1 oder ein Tiefenverhältnis. Teams, die ihre Detektions-Checkliste unverändert übernehmen, geben Segmentierungsmodelle frei, deren Freigabe an der Box-mAP hängt, und Posemodelle, deren Freigabe anhand von Boxen erfolgt, obwohl diese gar nicht das Produkt sind. Und selbst ein Modell, das die Freigabeschwelle erreicht, kann nach dem Export versagen: In dieser Lektion finden dieselben Pose-Gewichte bei einer Eingabeauflösung 5 Personen und bei einer anderen nur 3; die Entfernungen des Tiefenmodells verdoppeln sich beinahe.
Praxisnah
Eine Freigabeschwelle pro Aufgabe#
| Aufgabe | Freigabeschwelle anhand von | Schlüssel results_dict | Python-Attribut | Bewertet anhand von |
|---|---|---|---|---|
| Segmentierung | Masken-mAP50-95 | metrics/mAP50-95(M) | metrics.seg.map | Pixel-IoU pro Instanz |
| Semantische Segmentierung | mIoU (+ IoU pro Klasse) | metrics/mIoU | metrics.miou | Pixel-IoU pro Klasse |
| Pose | Pose-mAP50-95 | metrics/mAP50-95(P) | metrics.pose.map | OKS |
| OBB | OBB-mAP50-95 | metrics/mAP50-95(B) | metrics.box.map | IoU gedrehter Boxen |
| Klassifizierung | Top-1-Genauigkeit | metrics/accuracy_top1 | metrics.top1 | Korrekte Top-Klasse |
| Tiefe | δ1 (+ AbsRel) | metrics/delta1 | metrics.delta1 | Anteil der Pixel, deren Tiefe höchstens um den Faktor 1,25 vom tatsächlichen Wert abweicht |
Der Leitfaden zu Leistungsmetriken erklärt die einzelnen Kennzahlen. Auch Segmentierungs- und Pose-Läufe geben Boxmetriken aus. Behalte sie als Diagnosewerte bei — eine Abweichung zwischen Box und Maske weist auf die Qualität der Konturen hin —, aber sie bilden nicht das Produkt ab. Spezifische Hinweise zur Detektion, etwa zu Schwellenwertdurchläufen und zur Konfusionsmatrix, findest du unter Validieren und Fehler diagnostizieren.
Alle Aufgaben in einer Schleife validieren#
Der Validierungsmodus akzeptiert Gewichte für jede Aufgabe, sofern der passende Datensatz angegeben ist. So liefert eine einzige Schleife die Kennzahlen für die Freigabetabelle:
from ultralytics import YOLO
runs = {
"yolo26n-seg.pt": ("coco8-seg.yaml", "metrics/mAP50-95(M)"),
"yolo26n-sem.pt": ("cityscapes8.yaml", "metrics/mIoU"),
"yolo26n-pose.pt": ("coco8-pose.yaml", "metrics/mAP50-95(P)"),
"yolo26n-obb.pt": ("dota8.yaml", "metrics/mAP50-95(B)"),
"yolo26n-depth.pt": ("depth8.yaml", "metrics/delta1"),
}
for weights, (data, key) in runs.items():
metrics = YOLO(weights).val(data=data, device="cpu", plots=False, verbose=False)
print(f"{weights:17s} {key:22s} {metrics.results_dict[key]:.3f}")yolo26n-seg.pt metrics/mAP50-95(M) 0.538
yolo26n-sem.pt metrics/mIoU 0.610
yolo26n-pose.pt metrics/mAP50-95(P) 0.419
yolo26n-obb.pt metrics/mAP50-95(B) 0.857
yolo26n-depth.pt metrics/delta1 0.377Ohne explizites imgsz wird jedes Modell mit der Auflösung validiert, mit der es trainiert wurde: 640 für Segmentierung und Pose, 768 für Tiefe sowie 1024 für semantische Segmentierung und OBB. Diese Kennzahlen der vortrainierten Modelle sind höher als die Trainingsläufe mit 320 Pixeln aus dem früheren Kurs — teils wegen des Trainings, teils wegen der Auflösung. Vier Validierungsbilder machen jede hier aufgeführte Kennzahl zu einem ersten Funktionstest; die Seite zur Tiefenaufgabe gibt beispielsweise δ1 für den vollständigen NYU-Benchmark an. Die Klassifizierung lassen wir absichtlich aus: Validiere deinen feinabgestimmten Klassifikator anhand seiner eigenen Ordner, wie in der Klassifikatorlektion beschrieben.
Dieselben Gewichte erzielen bei unterschiedlicher imgsz unterschiedliche Werte. Notiere imgsz neben jedem Wert, validiere mit der Größe, die du einsetzen wirst, und vergleiche niemals Werte, die bei unterschiedlichen Größen gemessen wurden.
Alle Aufgaben exportieren#
Jede Aufgabe lässt sich mit demselben Aufruf im Exportmodus nach ONNX exportieren. Die Aufgabe wird in den Modellmetadaten gespeichert, sodass YOLO("model.onnx") die passende Nachverarbeitung anwendet. Laufzeitoptionen, Paritätsprüfungen und die Feinabstimmung für TensorRT oder OpenVINO werden unter Nach ONNX exportieren (und die Parität überprüfen) behandelt. Diese Schleife prüft, ob jede Aufgabe den Export und erneuten Import übersteht:
from ultralytics import YOLO
for weights in ["yolo26n-seg.pt", "yolo26n-sem.pt", "yolo26n-pose.pt", "yolo26n-obb.pt", "yolo26n-cls.pt", "yolo26n-depth.pt"]:
onnx_path = YOLO(weights).export(format="onnx", imgsz=320)
onnx_model = YOLO(onnx_path) # task comes from the ONNX metadata
result = onnx_model("https://ultralytics.com/images/bus.jpg", imgsz=320, verbose=False)[0]
print(f"{onnx_model.task:9s} {result.verbose()}")segment 4 persons, 1 bus,
semantic
pose 3 persons,
obb (no detections),
classify minibus 0.38, police_van 0.21, trolleybus 0.05, amphibian 0.05, bullet_train 0.03,
depth depth 4.67-26.91m,Jeder Export wurde erneut geladen und die richtige Aufgabe erkannt. Drei Ergebnisse verdienen einen zweiten Blick:
- Die Poseerkennung fand bei 320 Pixeln 3 Personen, während der PyTorch-Lauf mit 640 Pixeln 5 fand.
- Die Tiefenschätzung ergab für die Szene 4,7–26,9 m, während dieselben Gewichte bei ihrer nativen Auflösung von 768 Pixeln 2,1–14,9 m ergaben.
- OBB fand nichts auf einem Straßenfoto — das ist das erwartete Verhalten für ein Luftbildmodell und kein Exportfehler.
PyTorch bei imgsz=320 liefert dieselben Pose- und Tiefenwerte wie ONNX. Auch das ist also kein Exportfehler: Die Eingabeauflösung hat das Ergebnis verändert. Exportiere mit der von dir validierten Auflösung imgsz. Für semantische Ergebnisse gibt es keine zusammenfassende Zeile pro Objekt. Prüfe stattdessen result.semantic_mask.
Führe mit jedem exportierten Modell einmal eine Vorhersage auf einem Bild aus, das den Trainingsdaten ähnelt – Straßenszenen für COCO-Modelle, Luftbildkacheln für OBB, Innen- oder Straßenszenen im passenden Maßstab für Tiefenschätzung –, bevor du einen Export für defekt erklärst oder auslieferst.
Wenn du deine eigene Nachverarbeitung schreibst, findest du hier die rohen ONNX-Ausgaben bei imgsz=320 aus dem Exportprotokoll:
| Aufgabe | Form der ONNX-Ausgabe(n) | Inhalt |
|---|---|---|
| Segmentierung | (1, 116, 2100) und (1, 32, 80, 80) | Boxen + 80 Klassenwerte + 32 Maskenkoeffizienten; Maskenprototypen |
| Semantische Segmentierung | (1, 320, 320) | Klassenkarte; Argmax bereits im Graphen berechnet |
| Pose | (1, 56, 2100) | Boxen + 1 Konfidenzwert + 17 × 3 Keypoint-Werte |
| OBB | (1, 20, 2100) | Boxen + 15 Klassenwerte + 1 Winkel |
| Klassifizierung | (1, 1000) | Klassenwahrscheinlichkeiten |
| Tiefe | (1, 1, 320, 320) | Tiefe in Metern pro Pixel |
Auf der Ultralytics Platform zeigt die Modellseite die aufgabenspezifischen Metriken (Masken-mAP für ein Segmentierungsmodell) über einem Export-Reiter an, über den dieselben Formate erstellt werden:

ONNX dient als Austauschformat: Eine exportierte Datei lässt sich mit ONNX Runtime ausführen oder in andere Laufzeitumgebungen umwandeln.

Checkliste für die Bereitstellung#
- Die Freigabemetrik aus der obigen Tabelle erreicht auf einem zurückgehaltenen Datensatz bei der Einsatzauflösung
imgszden Zielwert. - Das exportierte Modell lässt sich mit dem erwarteten
taskerneut laden und liefert auf einem festen Bildersatz dieselben Vorhersagen wie PyTorch. - Die aufgabenspezifischen Codepfade verarbeiten leere Ergebnisse:
masks is None, null Keypoints, null OBBs. - Nachgelagerte Kennzahlen (Flächen, Winkel, Entfernungen, Klassenwahrscheinlichkeiten) werden protokolliert, damit du Veränderungen beobachten kannst, wie unter Beobachtbarkeit und Drift beschrieben.
Wenn die Freigabeschwelle nicht erreicht wird, bedeutet „zurück zu den Daten“ in der Regel, dass einer von drei Hebeln betätigt werden muss:

Verbessere zuerst die Datenqualität und den Annotationsprozess — die Prüfungen der Labels aus den Lektionen 2 und 6 sind der kostengünstigste Ausgangspunkt — und ändere das Modell erst, wenn die Daten sauber sind.
Lösung anzeigen
from ultralytics import YOLO
checks = {
"runs/segment/train/weights/best.pt": ("coco8-seg.yaml", "metrics/mAP50-95(M)", "https://ultralytics.com/images/bus.jpg"),
"runs/obb/train/weights/best.pt": ("dota8.yaml", "metrics/mAP50-95(B)", "https://ultralytics.com/images/boats.jpg"),
}
for weights, (data, key, image) in checks.items():
model = YOLO(weights)
gate = model.val(data=data, imgsz=320, plots=False, verbose=False).results_dict[key]
onnx_model = YOLO(model.export(format="onnx", imgsz=320))
result = onnx_model(image, imgsz=320, verbose=False)[0]
print(f"{onnx_model.task:8s} {key} @320 = {gate:.3f} | ONNX: {result.verbose()}")Passe die Pfade runs/... an die Ordner an, die deine Trainingsläufe ausgegeben haben (Results saved to ...). Mit den Läufen über eine Epoche aus den Lektionen 2 und 7:
segment metrics/mAP50-95(M) @320 = 0.377 | ONNX: 4 persons, 1 bus,
obb metrics/mAP50-95(B) @320 = 0.832 | ONNX: 185 ships, 3 harbors,| Modell | Maßgebliche Metrik | Wert | Bildgröße | ONNX |
|---|---|---|---|---|
| Segmentierung | Masken-mAP50-95 | 0.377 | 320 | wird als segment erneut geladen und erkennt den Bus und 4 Personen |
| OBB | OBB-mAP50-95 | 0.832 | 320 | wird als obb erneut geladen und erkennt 185 Schiffe und 3 Häfen |
Jede Prüfung verwendet ein Bild aus dem passenden Einsatzbereich: Das OBB-Modell erhält das Luftbild eines Hafens und nicht die Straßenszene. Beide Zeilen bestehen die Exportprüfung; keines der Modelle ist bereit für die Bereitstellung, denn eine Epoche mit vier Validierungsbildern ist ein erster Funktionstest, keine Freigabeprüfung.