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

Определи спецификацию набора данных

До начала сбора данных спланируй сценарии, квоты, вариативность, крайние случаи и изображения фона, а затем соотнеси план с целевыми объёмами Ultralytics.

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

Результат

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

Ускоренное прохождение
Если ты уже освоился, вот краткая версия.
  1. Запиши сценарии отдельными строками: камера, место, время и условие; для каждого укажи квоту.

  2. Установи квоты на уровне ≥1 500 изображений и ≥10 000 размеченных экземпляров на класс для эксплуатации.

  3. Добавь отдельную строку для каждого известного крайнего случая и собери для него больше данных.

  4. Отведи 0–10% изображений под фон без объектов.

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

Место спецификации в процессе#

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

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

Запиши сценарии отдельными строками#

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

СценарийКамерыМестаВремя сутокУсловиеКвотаПримечания
dock-daycam-1 — cam-4сектора A–C08:00–17:00любое1,200часы пиковой загрузки
dock-nightcam-1 — cam-4сектора A–C22:00–04:00любое400натриевое освещение, меньше людей
loading-raincam-2, cam-3сектор Bлюбоетолько дождь200редкий, но критичный случай
штабельлюбоелюбоелюбоеподдоны в штабеле выше 2 уровней150скрывает людей за собой
Фонлюбоелюбоелюбоепустой док150нет объектов, нет меток

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

Соотнеси спецификацию с целевыми объёмами#

В рекомендациях Ultralytics по достижению наилучших результатов обучения приведены практические ориентиры для эксплуатации:

Целевой показательРекомендация
Изображения на класс≥ 1,500
Размеченные экземпляры на класс≥ 10,000
Фоновые изображения (без меток)0–10% набора данных; в COCO — около 1%
РазнообразиеРазное время суток, сезоны, погода, освещение, углы съёмки, источники данных и камеры

Это ориентиры для модели, готовой к эксплуатации. Для первых экспериментов достаточно нескольких сотен размеченных объектов на класс, а первая модель поможет быстрее всего понять, для каких сценариев нужно собрать больше данных. Чтобы выяснить, насколько набор данных не дотягивает до ориентира, подсчитай его объём. Этот скрипт можно запустить на COCO128 — срезе COCO из 128 изображений, который загружается автоматически:

from collections import Counter
from pathlib import Path

from ultralytics.data.utils import IMG_FORMATS, check_det_dataset, img2label_paths

IMAGES_PER_CLASS, INSTANCES_PER_CLASS = 1500, 10_000  # Ultralytics production targets

data = check_det_dataset("coco128.yaml")  # downloads COCO128 (~7 MB) on first run; swap in your data YAML
images = [p for p in Path(data["train"]).rglob("*.*") if p.suffix[1:].lower() in IMG_FORMATS]
image_count, instance_count, background = Counter(), Counter(), 0
for label in map(Path, img2label_paths([str(p) for p in images])):
    classes = [int(r.split()[0]) for r in label.read_text().splitlines() if r.strip()] if label.exists() else []
    instance_count.update(classes)
    image_count.update(set(classes))
    background += not classes

print(f"{len(images)} images, {background} background ({background / len(images):.0%}, target 0-10%)")
print(f"{'class':>12} {'images':>7} {'instances':>10} {'of target':>10}")
ranked = instance_count.most_common()
for cls, n in ranked[:3] + ranked[-3:]:  # best and worst covered classes
    coverage = min(image_count[cls] / IMAGES_PER_CLASS, n / INSTANCES_PER_CLASS)
    print(f"{data['names'][cls]:>12} {image_count[cls]:>7} {n:>10} {coverage:>10.1%}")

never_labeled = [name for i, name in data["names"].items() if i not in instance_count]
print(f"{len(never_labeled)} classes in names with zero labels: {never_labeled[:4]} ...")
128 images, 2 background (2%, target 0-10%)
       class  images  instances  of target
      person      61        254       2.5%
         car      12         46       0.5%
         cup      10         36       0.4%
        bear       1          1       0.0%
      banana       1          1       0.0%
        skis       1          1       0.0%
9 classes in names with zero labels: ['fire hydrant', 'parking meter', 'sheep', 'cow'] ...

Как это читать:

  • Покрытие — меньшее из соотношения числа изображений и соотношения числа экземпляров, поскольку классу нужны оба показателя. Даже у person, класса с наилучшим покрытием, этот показатель составляет всего 2,5% от целевого объёма для эксплуатации.
  • Классы с одним экземпляром (bear, banana, skis) невозможно ни выучить, ни оценить. В своём наборе данных либо собери для них дополнительные примеры, либо исключи их из v1.
  • Классы без меток перечислены в YAML, но ни разу не размечены. Модель всё равно тратит ресурсы на их предсказание. Удали их из names или собери для них данные до начала обучения.

Охвати факторы вариативности#

Детекция Ultralytics YOLO на набережной: люди и велосипедисты рядом с камерой, собака и автомобили на разном расстоянии, каждый объект размечен ограничивающей рамкой и оценкой уверенности

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

ИзмерениеПримеры
ВремяДень, ночь, рассвет, сумерки
ПогодаСолнце, облачность, дождь, туман, снег
ОсвещениеЯркое, тусклое, блики, резкие тени, смешанное освещение
КамераМодель, объектив, высота установки, поле зрения
ГеографияОбъекты, города, страны
Люди и операторыСмены, команды, униформа, средства защиты
Варианты продуктаАртикулы, версии упаковки, цвета
Размер объектаБлизко и крупно, на среднем расстоянии, далеко и мелко
ПерекрытиеБез перекрытия, частичное, сильное, за стеклом
Состояние оборудованияГрязные или запотевшие объективы, повреждённые поддоны, стёртая разметка на полу

Разнообразие важнее объёма: 1 500 изображений, распределённых по этим строкам, ценнее 5 000 снимков с одной камеры в полдень.

Запланируй фоновые изображения и граничные случаи#

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

Как хранится изображение фона

В формате Ultralytics YOLO изображение фона — это просто изображение с пустым файлом меток или вообще без такого файла. При сканировании обучающая процедура учитывает оба варианта (… 1200 images, 90 backgrounds, 0 corrupt). Перед первой эпохой сверь это число со своей целевой долей 0–10%.

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

Естественная частота появления не даёт изучить редкие случаи

Если человек за штабелем поддонов появляется в одном кадре из 200, то в наборе данных, собранном с естественной частотой, будет около 7 таких кадров из 1 500 — слишком мало для обучения. Намеренно увеличивай долю редких случаев: их квоты должны быть намного выше, чем их доля в реальных видеозаписях.

Спецификация не обязана быть полной

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

Попробовать

Составь для проекта таблицу сценариев из 5–10 строк, указав для каждой числовую квоту, а также добавь строку для фона и по одной строке для каждого известного граничного случая. Обсуди её с кем-нибудь, кто работает на объекте внедрения, и добавь каждый названный им сценарий. Затем запусти volume_gap.py на любых уже размеченных данных (или COCO128) и отметь классы с лучшим и худшим покрытием. Результат: spec.md с таблицей и показателями покрытия.

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

  • Охвачено или явно исключено не менее 5 из 10 измерений вариативности.

  • Сумма квот достигает как минимум целевых значений по числу изображений и экземпляров для каждого класса либо разрыв задокументирован как исключение для v1.

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

Квоты рассчитываются по целевому числу экземпляров, а не только по числу изображений. Предположим, что на парковке нужно считать объекты двух классов, а на пилотных видеозаписях в среднем 3 автомобиля и 0,5 грузовика на изображение:

КлассЭкземпляров на изображениеИзображений для 10 000 экземпляровИзображений для минимального объёма в 1 500План
car3.0≈ 3,3001,5003 300 изображений
truck0.5≈ 20,0001,500Целевой сбор у въезда на погрузочную площадку, где грузовики встречаются в 10 раз чаще

Обычных видеозаписей достаточно для автомобилей. Для грузовиков потребовалось бы 20 000 случайных изображений, поэтому в спецификацию добавляют отдельный сценарий (въезд на погрузочную площадку, будни с 06:00 до 10:00), а не собирают в шесть раз больше всего. Добавь строку для фона — около 5% (пустая парковка ночью) — и строки для граничных случаев: снегопокров и грузовики, частично выходящие за край кадра.

Что дальше

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

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