Ultralytics YOLO27: Встать в лист ожидания.
Get Started
Урокначинающий

Как определить, что набор данных готов

Перед первым запуском обучения проверь восемь критериев «пройдено/не пройдено», автоматизируй три проверки, которые может выполнить скрипт, и выясни, какое исправление требуется при каждом сбое.

В каждом проекте наступает момент, когда команда хочет начать обучение. Иногда набор данных готов, а иногда в нём всё ещё есть утечка между выборками или недостаточно размеченный класс, из-за чего будет потрачена неделя GPU-времени и получена цифра, которой нельзя доверять. Восемь проверок, для каждой из которых фиксируется «да», «нет» или документированное исключение, позволяют принять объективное решение, а не полагаться на настроение.

Результат

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

Ускоренное прохождение
Если ты уже освоился, вот краткая версия.
  1. Оцени все восемь проверок: «да», «нет» или документированное исключение.

  2. Пусть readiness.py оценит объём данных, утечки, представленность классов в выборках и долю фоновых изображений.

  3. Исправляй каждый ответ «нет» в данных, а не гиперпараметрами.

  4. Принимай известный пробел и выпускай продукт только тогда, когда ожидаемое влияние этого пробела задокументировано.

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

Восемь проверок#

#ПроверкаКритерии прохожденияЕсли проверка не пройдена, вернись к
1Чёткая цельЦель, задача, классы и критерий приёмки записаны и согласованыНачни с бизнес-цели
2Определённые классыДля каждого класса есть определение и указан похожий объект, который к этому классу не относитсяЦель и руководство по разметке
3Репрезентативные изображенияДля каждого сценария из спецификации соблюдена квота; большинство изображений взято из производственных источниковСобери качественные и репрезентативные данные
4Достаточный объём≥ 1 500 изображений и ≥ 10 000 экземпляров на класс либо документированное исключениеСпецификация и сбор данных
5Согласованная разметкаРуководство подготовлено, калибровочный раунд проведён, согласованность ≥ 90%Рекомендации по разметке
6Контроль качества завершёнСкрипт аудита не выявил проблем, подозрительные случаи проверены, замечания по контролю качества записаныКонтроль качества набора данных
7Чистые разбиенияРазбиение с группировкой, ни одна группа не попадает в два разбиения, каждый класс представлен в каждом разбиенииПравильно раздели набор данных
8Фоновые изображения0–10% изображений — это кадры без разметки объектовСпецификация и сбор данных

Контрольный список проверяет те же решения, которые по отдельности рассматриваются в руководстве по сбору и разметке данных; здесь они объединены в единое решение о запуске или остановке.

Автоматизируй проверки, основанные на подсчётах#

Проверки 4, 7 и 8 сводятся к подсчётам, поэтому скрипт каждый раз оценивает их одинаково. Этот скрипт читает учебный набор и списки разбиений, созданные group_split.py на предыдущем занятии:

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

Разбиение с группировкой устранило утечку, но учебный набор совершенно не готов: в его самом слабом классе (30, skis) всего один размеченный экземпляр, а для половины классов нельзя рассчитать метрики на val. Так и должно быть для 128 демонстрационных изображений; именно такой вердикт и должна вынести эта проверка до того, как будет потрачена неделя на обучение.

Чистый скрипт — ещё не готовый чек-лист

Скрипт охватывает то, что можно подсчитать. Для проверок 1, 2, 3, 5 и 6 нужен человек: согласованная цель, письменные определения, охват спецификации, измеренная оценка согласованности и заметки о контроле качества. Оцени их вручную, приводя по одной строке доказательств для каждого пункта.

Реши: обучать, выпускать с известным пробелом или исправлять#

Когда проверка не пройдена, следующим шагом почти всегда хочется сделать что угодно, только не исправлять данные:

Соблазнительный обходной путьПочему это не работает
«Попробуем модель побольше».Большая модель с таким же успехом усваивает шум в разметке.
«Настроим скорость обучения».Никакая настройка оптимизатора не добавит отсутствующий класс или сценарий.
«Обучим на большем числе эпох».На разнообразных данных с ограниченным покрытием переобучение наступает быстрее.
«Добавим аугментацию».Аугментация не создаст сценарии, которых никогда не было в данных.

Три почти готовых набора данных#

СценарийНепройденная проверкаКак это выглядитРешение
Объём без разнообразия35 000 изображений, одна камера, нет сложных случаевДо обучения собери данные с других камер, площадок и в другое время
Разнообразие без согласованности5Разметчики расходятся во мнениях о границах рамок и степени перекрытия объектовЗаверши руководство, проведи калибровку и перемаркируй затронутую выборку
Незаметная утечка7Случайное разбиение видеокадров по отдельным изображениямРаздели данные заново по видеоклипам, камерам или дням; ожидай снижения mAP на валидации — это отражает реальность.

Запускай модель, зная о пробеле в данных#

Часто правильное решение — сначала создать целевую модель, не дожидаясь, пока все проверки пройдут: пилотную версию, прототип или v1 для части камер. Модель в продакшене быстрее покажет, что на самом деле не так, чем попытки вслепую довести датасет до совершенства. Если запускаешь модель, зная о пробеле, запиши три вещи:

  • Какая проверка не пройдена.
  • Ожидаемое влияние, например: «нет ночных данных; ожидай снижения полноты после наступления темноты».
  • План сбора данных, который устранит проблему, пока работает v1.
Исключение без оценки последствий — это пропущенная проверка

Запись «Объём: исключение» ничего не говорит следующему человеку. Запись «Объём: pallet, 700 экземпляров; ожидается снижение полноты обнаружения поддонов в загруженных зонах; к июню размечаем ещё 2 000» описывает контролируемый риск. Для каждого исключения нужно указать ожидаемое влияние на приёмочное тестирование.

Повторяй проверки перед каждым переобучением#

Качество модели во времени: качество сохраняется, пока поступают новые размеченные данные, а затем снижается после ожидаемого момента спада; возникает вопрос — переобучать модель сейчас или подождать

Датасет, готовый для v1, не обязательно будет готов для v3. Новые классы, источники и аннотаторы могут нарушить проверку, которая раньше проходила, а производственные данные дрейфуют, пока накапливаются новые метки. Перед каждым переобучением запускай readiness.py и заново оценивай результаты ручных проверок: это занимает минуты, а пропуск проверки может стоить недели обучения на испорченном датасете.

Попробовать

Запусти readiness.py на разделённом датасете (или учебном наборе), затем вручную оцени пять проверок, добавив по одной строке обоснования к каждой. Расставь все не пройденные проверки по степени риска для приёмочного теста. Результат: оценённый контрольный список из восьми пунктов с решением о запуске или списком исправлений по приоритету; сохрани его рядом с заметками по контролю качества.

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

  • Для каждого исключения указано ожидаемое влияние на приёмочный тест и план устранения.

  • Решение (обучать, запускать с задокументированным пробелом или сначала исправить проблему) записано вместе с контрольным списком.

Показать решение

Оценённый контрольный список для учебного набора:

#ПроверкаОценкаОбоснование
1Чёткая цельдаobjective.md и acceptance_test.py из урока 1
2Определены классынетДля 80 классов COCO нет письменных определений или описания похожих объектов, которые нужно исключать
3Репрезентативные изображениянетcoverage.py: для cam2–cam4 не выполнена квота
4Достаточный объёмнетreadiness.py: у самого слабого класса 1 изображение
5Согласованность разметкинетСогласованность на калибровочном раунде — 47%
6Контроль качества завершёнчастичноАудит проведён; подозрительные случаи в 000000000438.jpg ещё не разобраны
7Корректные разбиениянетОбщие группы отсутствуют, но в val нет 36 из 71 класса
8Изображения без объектовда1.6%

Решение: сначала исправить. Приоритет по риску для приёмочного теста: (1) сократить список классов до нужных для цели — это сразу упростит проверки 2, 4 и 7; (2) собрать больше групп для этих классов; (3) завершить правило в руководстве для людей вдали и перемаркировать данные. Демонстрационный набор эту проверку не проходит — и так и должно быть.

Что дальше

После прохождения контрольного списка в следующем уроке запускается базовое дообучение, а его результаты используются для определения следующего исправления датасета.

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