Посмотреть как Markdown

Датасеты

Датасет в LibreYOLO — это YAML-файл, в котором заданы корень, сплиты и имена классов. Всё остальное, включая расположение файлов разметки, выводится из этого файла по соглашению.

Указание датасета для обучения

data= принимает путь к YAML или имя конфига, который поставляется вместе с пакетом.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # Подойдёт встроенное имя, относительный путь или абсолютный путь.model.train(data="coco8.yaml", epochs=10)
CLI
libreyolo train model=LibreYOLO9s.pt data=coco8.yaml epochs=10

Имя разрешается в фиксированном порядке: существующий абсолютный путь, затем имя как есть относительно рабочего каталога, затем то же имя с добавленным .yaml, затем каталог встроенных конфигов. Если ничего не совпало, в ошибке перечисляются все просмотренные каталоги и все встроенные конфиги.

Встроенные конфиги

Вместе с пакетом поставляются тринадцать конфигов датасетов — они лежат в libreyolo/config/datasets/.

КонфигЗадачаПримечания
coco8.yamldetect8 изображений, скачивается по обычному URL
coco128.yamldetect128 изображений
coco1000.yamldetect800 на обучение, 200 на валидацию
coco5000.yamldetect4000 на обучение, 1000 на валидацию
coco.yamldetectполный COCO 2017
coco-val-only.yamldetectтолько val2017
coco8-pose.yamlpose8 изображений, ключевые точки COCO-17
coco-pose.yamlposeключевые точки COCO 2017
ade20k.yamlsemantic150 классов
cityscapes.yamlsemantic19 классов, скачивание вручную
cocostuff.yamlsemantic182 класса, скачивание вручную
gopro.yamlrestoreпары для устранения размытия
sr8.yamlrestoreпары для суперразрешения

Обычный URL для скачивания есть только у coco8.yaml и coco128.yaml. Остальные либо содержат Python-блок скачивания, для которого нужно явное разрешение (описано ниже), либо ожидают, что данные уже лежат на диске.

Где датасет лежит на диске

Ключ path в YAML задаёт корень датасета. Абсолютный path используется как есть. Относительный сначала ищется в каталоге датасетов, затем рядом с самим YAML-файлом, а датасет, который предстоит скачать, попадает в каталог датасетов.

Этот каталог — ~/datasets, его переопределяет переменная окружения LIBREYOLO_DATASETS_DIR. Файла настроек для него нет.

Ключи YAML

yaml
path: my-dataset        # корень датасета
train: images/train     # нужен для обучения
val: images/val         # нужен для валидации
test: images/test       # необязателен
nc: 3                   # необязателен; должен согласовываться с names
names:
  0: person
  1: helmet
  2: vest
download: https://example.com/my-dataset.zip   # необязателен

train, val и test принимают каталог с изображениями, файл .txt с одним путём к изображению на строку или список, где смешано и то и другое. Строки в списке .txt могут быть относительными — тогда они разрешаются относительно каталога самого файла со списком, — а строки, начинающиеся с #, пропускаются.

names может быть списком или отображением с целочисленными ключами. nc необязателен; если присутствуют оба и они расходятся, doctor сообщает об этом как об ошибке.

Структура каталогов и файлы разметки

У детекции, сегментации, оценки позы и повёрнутых рамок структура одна. Путь к разметке выводится из пути к изображению: компонент каталога images заменяется на labels, а расширение — на .txt:

my-dataset/
  images/train/0001.jpg   ->   labels/train/0001.txt
  images/val/0002.jpg     ->   labels/val/0002.txt

Заменяется только целый компонент пути images, поэтому каталог с именем images_old остаётся нетронутым.

Строка детекции — это пять полей, все нормированы к [0, 1] по исходной ширине и высоте изображения:

<class_id> <cx> <cy> <w> <h>

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

Другие задачи

Сегментация сохраняет ту же структуру, но со строками-полигонами <class_id> <x1> <y1> ... <xN> <yN> минимум из трёх точек. Строка детекции из пяти полей принимается и означает прямоугольный экземпляр.

Оценка позы добавляет в YAML kpt_shape: [K, D] и необязательную перестановку flip_idx. В каждой строке ровно 5 + K * D полей: рамка, затем K ключевых точек вида x y или x y v, где видимость — 0, 1 или 2.

Повёрнутые рамки используют ровно девять полей: класс, а за ним четыре угловые точки в нормированных координатах. Угол в файле не хранится.

Семантическая сегментация сопоставляет каждому изображению одноканальную маску того же разрешения; путь получается подстановкой masks_dir (по умолчанию masks) вместо images. Значение пикселя 255 означает «игнорировать». label_mapping при загрузке переводит исходные id в id для обучения.

Классификация вместо файлов разметки использует дерево ImageFolder: в train/ и val/ лежит по одному каталогу на класс. Соответствие класса и индекса задаётся отсортированным порядком имён каталогов.

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

Полный контракт по каждой задаче, включая соглашения о масштабе глубины и кодирование id паноптических сегментов в PNG, — это docs/dataset_schema.md в репозитории библиотеки.

Нативный COCO JSON

Файл аннотаций COCO JSON можно использовать напрямую. Добавьте отображение annotations, и путь сплита станет корнем с изображениями:

yaml
path: my-dataset
train: images/train
val: images/val
annotations:
  train: annotations/train.json
  val: annotations/val.json

Если names присутствует, имена категорий в JSON должны с ним совпадать, и именно names задаёт id меток, которые предсказывает модель. Без names id категорий COCO сортируются и плотно отображаются в 0..N-1.

Этот путь ожидает по одному каталогу с изображениями на сплит. Список путей или список изображений в .txt вызывает ошибку, а не загружает молча другой набор.

Автоскачивание

Датасет считается на месте, когда его путь train или val разрешается в непустой каталог или в существующий файл. Если это не так, а в YAML есть ключ download, дальнейшее решает его значение.

URL с http или https скачивается и, если это zip, распаковывается в корень датасета. Всё остальное считается встроенным Python-скриптом и запускается только при allow_download_scripts=True. Без этого скрипт пропускается с предупреждением, а обучение продолжается на том, что лежит на диске.

bash
libreyolo train model=LibreYOLO9s.pt data=coco.yaml allow_download_scripts=true

Этот флаг ограничивает выполнение кода, а не доступ к сети. Скачивание по URL происходит в любом случае; флаг нужен именно блокам download: |. CLI печатает предупреждение, когда флаг включён, а doctor не включает его никогда.

Проверка датасета перед обучением

libreyolo doctor читает датасет для детекции и сообщает, что пойдёт не так, ещё до того, как в дело вступит GPU. При найденных ошибках он завершается с кодом 1, поэтому годится как CI-гейт.

Проверка датасета
libreyolo doctor my-dataset.yaml
Завершение CI с ошибкой и на предупреждениях
libreyolo doctor my-dataset.yaml strict=true json=true
Пропуск прохода с декодированием изображений
# Читает только разметку и YAML. Проверки на повреждения, дубликаты# и утечки между сплитами требуют пикселей, поэтому пропускаются.libreyolo doctor my-dataset.yaml fast=true
Python
from libreyolo import doctor report = doctor.diagnose("my-dataset.yaml", imgsz=640) for finding in report.findings:    print(finding.severity.value, finding.check_id, finding.message) raise SystemExit(report.exit_code(strict=False))

Проверки разбиты на шесть семейств:

СемействоЧто ищет
configотсутствующий names, nc, расходящийся с names, отсутствующие или пустые сплиты, повторяющиеся имена классов
filesизображения без файла разметки, разметка без изображения, отсутствующие изображения, перечисленные в сплите, конфликты имён без расширения
labelsнекорректные строки, id классов вне [0, nc), координаты вне [0, 1], рамки нулевой площади, крошечные или огромные рамки, повторяющиеся рамки, побайтово одинаковые файлы разметки
balanceклассы без экземпляров или почти без них, коэффициент дисбаланса классов, классы, встречающиеся только в одном сплите, доля фоновых изображений
imagesфайлы, которые не декодируются, поворот по EXIF, необычная раскладка каналов, однотонные изображения, точные и почти точные дубликаты
splitsодно и то же изображение в двух сплитах, точно или почти точно

--only и --skip принимают id проверки или префикс семейства, поэтому skip=images,labels.tiny_object — корректная запись. --fast отбрасывает все проверки, которым нужно декодировать пиксели, то есть семейства images и splits.

Стоит знать о двух особенностях. С --strict на код возврата влияют не только ошибки, но и предупреждения. И doctor работает только с датасетами для детекции: датасет для оценки позы, сегментации или повёрнутых рамок отклоняется с сообщением о том, что именно распознано, вместо проверки по неподходящему контракту.

Смотрите также

Проверено с LibreYOLO v1.5.0.