Ultralytics YOLO27: Únete a la lista de espera.
Lecciónintermedio

Evalúa y entrega cada tarea

Establece un umbral para cada tarea según su propia métrica y el tamaño de implementación, valida todas las tareas en un solo bucle y exporta cada una a ONNX con una predicción verificada.

Cada tarea tiene su propia definición de acierto: solapamiento de píxeles, similitud de puntos clave, IoU de cajas giradas, un acierto en la primera posición o una proporción de profundidad. Los equipos que reutilizan su lista de comprobación de detección entregan modelos de segmentación cuyo umbral se basa en mAP de cajas y modelos de pose cuyo umbral se basa en cajas que nunca fueron el producto. Además, un modelo que supera su umbral puede fallar después de exportarse: en esta lección, los mismos pesos de pose encuentran a 5 personas con un tamaño de entrada y a 3 con otro, y las distancias del modelo de profundidad casi se duplican.

Resultado

Prepara una tabla de publicación con la métrica de referencia y imgsz de cada modelo de tarea, además de una exportación ONNX verificada de cada modelo que se vuelva a cargar con la tarea correcta y prediga correctamente en una imagen del dominio correspondiente.

Vía rápida
Si ya tienes experiencia, aquí tienes un resumen.
  1. Establece el umbral de segmentación en mask mAP50-95, el de segmentación semántica en mIoU, el de pose en pose mAP50-95, el de OBB en OBB mAP50-95, el de clasificación en top-1 y el de profundidad en δ1.

  2. Lee las cifras principales de metrics.results_dict con la clave de la tarea y anota imgsz junto a cada cifra.

  3. Exporta con model.export(format="onnx", imgsz=...) al tamaño que has validado.

  4. Vuelve a cargar la exportación con YOLO("model.onnx") y haz una predicción en una imagen del propio dominio del modelo antes de entregarlo.

Práctico

Un umbral por tarea#

TareaEstablece el umbral segúnClave de results_dictAtributo de PythonSe mide mediante
segmentaciónmAP50-95 de máscarasmetrics/mAP50-95(M)metrics.seg.mapIoU de píxeles por instancia
segmentación semánticamIoU (+ IoU por clase)metrics/mIoUmetrics.miouIoU de píxeles por clase
posepose mAP50-95metrics/mAP50-95(P)metrics.pose.mapOKS
obbmAP50-95 de OBBmetrics/mAP50-95(B)metrics.box.mapIoU de cajas giradas
clasificaciónprecisión top-1metrics/accuracy_top1metrics.top1clase principal correcta
profundidadδ1 (+ AbsRel)metrics/delta1metrics.delta1proporción de píxeles cuya profundidad está dentro de 1,25 veces la profundidad real

La guía de métricas de rendimiento explica cada puntuación. Las ejecuciones de segmentación y pose también muestran métricas de cajas; consérvalas como diagnóstico —una diferencia entre cajas y máscaras apunta a la calidad del contorno—, pero no son el producto. Las prácticas específicas de detección, como las pruebas con distintos umbrales y la matriz de confusión, también se aplican a Validar y diagnosticar.

Valida todas las tareas en un solo bucle#

El modo Val acepta los pesos de cualquier tarea junto con el conjunto de datos correspondiente, así que un solo bucle genera las cifras de la tabla de publicación:

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.377

Si no especificas imgsz, cada modelo se valida con el tamaño con el que se ha entrenado: 640 para segmentación y pose, 768 para profundidad, y 1024 para segmentación semántica y OBB. Estas cifras de modelos preentrenados son superiores a las de las ejecuciones de entrenamiento a 320 píxeles de antes en el curso, en parte por el entrenamiento y en parte por la resolución. Con cuatro imágenes de validación, todas las cifras de aquí son solo una prueba rápida; por ejemplo, la página de la tarea de profundidad muestra δ1 en el conjunto de referencia NYU completo. La clasificación se omite deliberadamente: valida el clasificador ajustado con sus propias carpetas, como en la lección sobre clasificación.

La resolución forma parte de la métrica

Los mismos pesos obtienen puntuaciones distintas con diferentes valores de imgsz. Registra imgsz junto a cada cifra, valida con el tamaño que vayas a desplegar y no compares nunca cifras medidas con tamaños distintos.

Exporta todas las tareas#

Cada tarea se exporta a ONNX con la misma llamada al modo Export. La tarea se guarda en los metadatos del modelo, así que YOLO("model.onnx") aplica el posprocesamiento adecuado. La elección del entorno de ejecución, las comprobaciones de paridad y el ajuste de TensorRT u OpenVINO se tratan en Exportar a ONNX (y verificar la paridad); este bucle comprueba que todas las tareas superan el proceso de ida y vuelta:

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,

Todas las exportaciones se volvieron a cargar con la tarea correcta. Hay tres resultados que conviene revisar:

  • La pose encontró a 3 personas con 320 píxeles, mientras que la ejecución en PyTorch a 640 píxeles encontró a 5.
  • La profundidad calculó distancias de 4,7–26,9 m, mientras que los mismos pesos con su resolución nativa de 768 píxeles calcularon distancias de 2,1–14,9 m.
  • OBB no encontró nada en una foto de una calle: es el comportamiento correcto para un modelo aéreo, no un error de exportación.

PyTorch con imgsz=320 da las mismas cifras de pose y profundidad que ONNX, así que tampoco se trata de un error de exportación en ninguno de los dos: el tamaño de entrada cambió el resultado. Exporta con el imgsz que has validado. Los resultados semánticos no tienen una línea de resumen por objeto, así que comprueba result.semantic_mask.

Prueba cada exportación en su propio dominio

Haz una predicción con cada modelo exportado sobre una imagen similar a las del entrenamiento —escenas urbanas para modelos COCO, teselas aéreas para OBB, escenas interiores o urbanas a la escala adecuada para profundidad— antes de dar por defectuosa una exportación o desplegarla.

Si escribes tu propio posprocesamiento, estas son las salidas brutas de ONNX con imgsz=320, extraídas del registro de exportación:

TareaForma(s) de salida de ONNXContenido
segmentación(1, 116, 2100) y (1, 32, 80, 80)cajas + 80 puntuaciones de clase + 32 coeficientes de máscara; prototipos de máscara
segmentación semántica(1, 320, 320)mapa de clases, argmax ya incluido en el grafo
pose(1, 56, 2100)cajas + 1 puntuación + 17 × 3 valores de puntos clave
obb(1, 20, 2100)cajas + 15 puntuaciones de clase + 1 ángulo
clasificación(1, 1000)probabilidades de clase
profundidad(1, 1, 320, 320)profundidad en metros por píxel

En Ultralytics Platform, la página del modelo muestra sus propias métricas de tarea (mAP de máscara para un modelo de segmentación) encima de una pestaña de exportación que genera los mismos formatos:

Página de modelo de Ultralytics Platform para un modelo de segmentación, con tarjetas de mask mAP50, mAP50-95, precisión y recuperación encima de la pestaña Export, que muestra TorchScript, ONNX, OpenVINO, TensorRT y CoreML

ONNX es el formato de intercambio: un único archivo exportado se ejecuta en ONNX Runtime o se convierte a otros entornos de ejecución.

ONNX como formato de intercambio: los modelos de PyTorch, TensorFlow, Keras y otros frameworks se exportan a ONNX y se cargan en ONNX Runtime u otro framework

Lista de comprobación para la entrega#

  • La métrica de referencia de la tabla anterior alcanza su objetivo en un conjunto reservado y con el imgsz de implementación.
  • El modelo exportado se vuelve a cargar con el task esperado y coincide con las predicciones de PyTorch en un conjunto fijo de imágenes.
  • Las rutas de código de cada tarea gestionan los resultados vacíos: masks is None, cero puntos clave y cero OBB.
  • Se registran las cifras posteriores (áreas, ángulos, distancias y probabilidades de clase) para poder detectar cambios, tal como se explica en Observabilidad y deriva.

Si no se alcanza el umbral, «volver a los datos» suele significar actuar sobre una de estas tres palancas:

Tres formas de mejorar mAP: calidad de los datos, optimización del modelo y proceso de anotación

Primero corrige la calidad de los datos y el proceso de anotación —las comprobaciones de etiquetas de las lecciones 2 y 6 son el punto de partida más sencillo— y cambia el modelo solo cuando los datos estén limpios.

Pruébalo

Elige dos tareas que hayas entrenado en este curso. Para cada una, escribe una fila de la tabla de publicación con la métrica de referencia en el imgsz de implementación, exporta a ONNX el best.pt entrenado con ese tamaño, vuelve a cargarlo y confirma que predice correctamente en una imagen del dominio correspondiente.

Cuándo se considera terminado
Has terminado la lección cuando se cumplen todas estas condiciones.
  • La tabla de publicación incluye la métrica de referencia correcta, su valor y el imgsz de los dos modelos.

  • Los dos modelos se han exportado a ONNX y se han vuelto a cargar con el task esperado.

  • Cada exportación ha generado una predicción razonable en una imagen de su propio dominio.

Mostrar solución
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()}")

Ajusta las rutas de runs/... para que apunten a las carpetas que han indicado tus ejecuciones de entrenamiento (Results saved to ...). Con las ejecuciones de una época de las lecciones 2 y 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,
ModeloMétrica de aceptaciónValortamaño de imagenONNX
segmentaciónmAP50-95 de máscaras0.377320se vuelve a cargar como segment y detecta el autobús y a 4 personas
obbmAP50-95 de OBB0.832320se vuelve a cargar como obb y detecta 185 barcos y 3 puertos

Cada comprobación usa una imagen de su propio dominio: el modelo OBB recibe la foto aérea del puerto, no la escena de la calle. Las dos filas superan la comprobación de exportación; ninguno de los modelos está listo para entregarse, porque una época con cuatro imágenes de validación es una prueba rápida, no un umbral de aceptación.

Qué viene después

Haz el examen del curso para obtener el certificado y, después, continúa con Ultralytics YOLO en producción para implementar estos modelos con entornos de ejecución optimizados, seguimiento y supervisión.