Ultralytics YOLO27: Встать в лист ожидания.
Get Started
За пределами детекции: сегментация, поза, OBB и классификация·Классифицируй, объединяй, отправляй·Урок 10/10
Уроксредний

Оцени и подготовь к развёртыванию все задачи

Задай для каждой задачи собственную метрику приёмки для целевого размера развёртывания, проверь все задачи в одном цикле и экспортируй каждую в ONNX с проверенным предсказанием.

У каждой задачи своё определение правильного результата: перекрытие пикселей, сходство ключевых точек, IoU повёрнутых рамок, правильный класс top-1 или отношение глубин. Команды, которые используют для всех задач один и тот же чек-лист детекции, выпускают модели сегментации, проверенные по mAP рамок, и модели оценки позы, проверенные по рамкам, хотя именно рамки не являются целевым результатом. Кроме того, модель, прошедшая проверку, всё равно может дать сбой после экспорта: в этом уроке одни и те же веса модели оценки позы обнаруживают 5 человек при одном размере входного изображения и 3 — при другом, а расстояния модели глубины почти удваиваются.

Результат

Составь таблицу релиза с метрикой приёмки и imgsz для каждой модели задачи, а также проверь экспорт каждой модели в ONNX: после повторной загрузки должна определяться правильная задача, а предсказание на изображении из соответствующего домена должно быть корректным.

Ускоренное прохождение
Если ты уже освоился, вот краткая версия.
  1. Для сегментации используй mask mAP50-95, для семантической сегментации — mIoU, для оценки позы — pose mAP50-95, для OBB — OBB mAP50-95, для классификации — top-1, для глубины — δ1.

  2. Считывай основные показатели из metrics.results_dict по ключу задачи и записывай imgsz рядом с каждым показателем.

  3. Экспортируй с помощью model.export(format="onnx", imgsz=...), указав проверенный размер.

  4. Повторно загрузи экспортированную модель с помощью YOLO("model.onnx") и перед выпуском выполни одно предсказание на изображении из домена самой модели.

Практические занятия

Одна метрика приёмки для каждой задачи#

ЗадачаМетрика приёмкиКлюч results_dictАтрибут PythonЧто оценивается
сегментацияmask mAP50-95metrics/mAP50-95(M)metrics.seg.mapIoU пикселей для каждого объекта
семантическая сегментацияmIoU (+ IoU для каждого класса)metrics/mIoUmetrics.miouIoU пикселей для каждого класса
оценка позыpose mAP50-95metrics/mAP50-95(P)metrics.pose.mapOKS
obbOBB mAP50-95metrics/mAP50-95(B)metrics.box.mapIoU повёрнутых рамок
классификацияточность top-1metrics/accuracy_top1metrics.top1правильный класс top-1
глубинаδ1 (+ AbsRel)metrics/delta1metrics.delta1доля пикселей, у которых истинная глубина отличается не более чем в 1,25 раза

В руководстве по метрикам производительности объясняется каждая метрика. Запуски сегментации и оценки позы также показывают метрики рамок. Используй их для диагностики: разница между показателями рамок и масок указывает на качество контуров, — но рамки не являются целевым результатом. Рекомендации по анализу результатов детекции, например подбор порогов и построение матрицы ошибок, применимы и здесь; они приведены в разделе «Валидация и диагностика».

Проверь все задачи в одном цикле#

Режим Val принимает веса любой задачи при условии, что им соответствует набор данных, поэтому один цикл формирует показатели для таблицы релиза:

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

Если явно не указать imgsz, каждая модель проходит валидацию при размере, на котором её обучали: 640 для сегментации и оценки позы, 768 для глубины, 1024 для семантической сегментации и OBB. Показатели этих предварительно обученных моделей выше результатов обучения с размером 320 пикселей, приведённых ранее в курсе: отчасти благодаря обучению, отчасти — разрешению. Четыре изображения для валидации позволяют лишь проверить, что всё работает; например, на странице задачи оценки глубины приводится δ1 на полном наборе NYU. Классификация намеренно не включена: проверь дообученный классификатор на собственных папках, как в уроке по классификации.

Разрешение — часть метрики

Одинаковые веса показывают разные результаты при разных значениях imgsz. Записывай imgsz рядом с каждым результатом, проводи валидацию при том размере, который будешь использовать при развертывании, и никогда не сравнивай результаты, измеренные при разных размерах.

Экспортируй все задачи#

Каждую задачу можно экспортировать в ONNX одним и тем же вызовом режима Export. Задача сохраняется в метаданных модели, поэтому YOLO("model.onnx") применяет нужную постобработку. Выбор среды выполнения, проверка паритета и настройка TensorRT или OpenVINO рассматриваются в разделе «Экспорт в ONNX (и проверка паритета)»; в этом цикле проверяется, что все задачи проходят полный цикл экспорта и повторной загрузки:

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,

Все экспортированные модели загрузились повторно с правильным типом задачи. Три результата стоит проверить внимательнее:

  • При размере 320 пикселей модель оценки позы обнаружила 3 человек, тогда как запуск PyTorch при размере 640 пикселей обнаружил 5.
  • Модель глубины оценила расстояния как 4,7–26,9 м, тогда как те же веса при исходном размере 768 пикселей дали значения 2,1–14,9 м.
  • OBB ничего не обнаружила на уличной фотографии — это правильное поведение для модели, обученной на аэрофотоснимках, а не ошибка экспорта.

PyTorch с imgsz=320 выдаёт те же показатели для оценки позы и глубины, что и ONNX, поэтому ни в одном из случаев нет ошибки экспорта: результат изменился из-за размера входного изображения. Экспортируй модель с тем значением imgsz, которое ты проверил. Для семантической сегментации нет сводной строки по объектам, поэтому проверь result.semantic_mask.

Проверяй каждый экспорт в соответствующей ему предметной области

Сделай по одному предсказанию каждой экспортированной моделью на изображении, похожем на те, на которых она обучалась: у моделей COCO это должны быть уличные сцены, у OBB — аэрофотоснимки, а у моделей глубины — сцены в помещении или на улице с подходящим масштабом. Выполни эту проверку, прежде чем объявлять экспорт неисправным или отправлять его в рабочую среду.

Если ты реализуешь собственную постобработку, ниже приведены исходные выходы ONNX при imgsz=320 из журнала экспорта:

ЗадачаФорма выходных данных ONNXСодержимое
сегментация(1, 116, 2100) и (1, 32, 80, 80)рамки + 80 оценок классов + 32 коэффициента масок; прототипы масок
семантическая сегментация(1, 320, 320)карта классов; argmax уже включён в граф
оценка позы(1, 56, 2100)рамки + 1 оценка + значения 17 × 3 для ключевых точек
obb(1, 20, 2100)рамки + 15 оценок классов + 1 угол
классификация(1, 1000)вероятности классов
глубина(1, 1, 320, 320)глубина в метрах на пиксель

На платформе Ultralytics на странице модели отображаются метрики для соответствующей задачи (например, mask mAP для модели сегментации), а на вкладке Export можно получить модель в тех же форматах:

Страница модели сегментации на платформе Ultralytics: карточки с mask mAP50, mAP50-95, точностью и полнотой над вкладкой Export со списком TorchScript, ONNX, OpenVINO, TensorRT и CoreML

ONNX — формат для обмена моделями: один экспортированный файл запускается в ONNX Runtime или конвертируется для других сред выполнения.

ONNX как формат для обмена моделями: модели из PyTorch, TensorFlow, Keras и других фреймворков экспортируются в ONNX и загружаются в ONNX Runtime или другой фреймворк

Чек-лист перед выпуском#

  • Метрика приёмки из таблицы выше достигает целевого значения на отложенной выборке при размере развёртывания imgsz.
  • Экспортированная модель повторно загружается с ожидаемым task и выдаёт те же предсказания, что и PyTorch, на фиксированном наборе изображений.
  • В коде для каждой задачи обрабатываются пустые результаты: masks is None, отсутствие ключевых точек, отсутствие OBB.
  • Показатели для последующей обработки (площади, углы, расстояния, вероятности классов) записываются в журнал, чтобы отслеживать их изменения, как описано в разделе «Наблюдаемость и дрейф».

Если метрика приёмки не достигнута, «вернуться к данным» обычно означает использовать один из трёх способов:

Три способа повысить mAP: качество данных, оптимизация модели и процесс аннотирования

Сначала исправь качество данных и процесс разметки: проверки меток из уроков 2 и 6 — самый простой способ начать. Меняй модель только после того, как приведёшь данные в порядок.

Попробовать

Выбери две задачи, которым ты обучал в этом курсе. Для каждой добавь в таблицу релиза строку с метрикой приёмки при размере развёртывания imgsz, экспортируй обученную модель best.pt в ONNX при этом размере, загрузи её повторно и проверь, что она выдаёт разумное предсказание на одном изображении из соответствующего домена.

Критерии готовности
Урок считается завершённым, если выполнены все условия ниже.
  • В таблице релиза указаны правильная метрика приёмки, её значение и imgsz для обеих моделей.

  • Обе модели экспортированы в ONNX и повторно загружены с ожидаемым task.

  • Каждая экспортированная модель выдала разумное предсказание на изображении из соответствующего домена.

Показать решение
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()}")

Замени пути runs/... на пути к папкам, выведенные при запусках обучения (Results saved to ...). Для запусков в одну эпоху из уроков 2 и 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,
МодельМетрика для принятия решенияЗначениеimgszONNX
сегментацияmask mAP50-950.377320повторно загружается как segment, обнаруживает автобус и 4 человек
obbOBB mAP50-950.832320повторно загружается как obb, обнаруживает 185 кораблей и 3 гавани

Для каждой проверки используется изображение из соответствующего домена: модель OBB получает аэрофотоснимок гавани, а не уличную сцену. Обе строки проходят проверку экспорта, но ни одна модель не готова к выпуску: обучение в течение одной эпохи на четырёх изображениях для валидации — это лишь проверка работоспособности, а не проверка по пороговому значению.

Что дальше

Сдай экзамен по курсу, чтобы получить сертификат, а затем продолжи обучение по курсу Ultralytics YOLO в production, чтобы развернуть эти модели с оптимизированными средами выполнения, трекингом и мониторингом.

Войди, чтобы сохранять прогресс