Датасеты
Датасет в LibreYOLO — это YAML-файл, в котором заданы корень, сплиты и имена классов. Всё остальное, включая расположение файлов разметки, выводится из этого файла по соглашению.
Указание датасета для обучения
data= принимает путь к YAML или имя конфига, который поставляется вместе с
пакетом.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # Подойдёт встроенное имя, относительный путь или абсолютный путь.model.train(data="coco8.yaml", epochs=10)libreyolo train model=LibreYOLO9s.pt data=coco8.yaml epochs=10Имя разрешается в фиксированном порядке: существующий абсолютный путь, затем имя
как есть относительно рабочего каталога, затем то же имя с добавленным .yaml,
затем каталог встроенных конфигов. Если ничего не совпало, в ошибке
перечисляются все просмотренные каталоги и все встроенные конфиги.
Встроенные конфиги
Вместе с пакетом поставляются тринадцать конфигов датасетов — они лежат в
libreyolo/config/datasets/.
| Конфиг | Задача | Примечания |
|---|---|---|
coco8.yaml | detect | 8 изображений, скачивается по обычному URL |
coco128.yaml | detect | 128 изображений |
coco1000.yaml | detect | 800 на обучение, 200 на валидацию |
coco5000.yaml | detect | 4000 на обучение, 1000 на валидацию |
coco.yaml | detect | полный COCO 2017 |
coco-val-only.yaml | detect | только val2017 |
coco8-pose.yaml | pose | 8 изображений, ключевые точки COCO-17 |
coco-pose.yaml | pose | ключевые точки COCO 2017 |
ade20k.yaml | semantic | 150 классов |
cityscapes.yaml | semantic | 19 классов, скачивание вручную |
cocostuff.yaml | semantic | 182 класса, скачивание вручную |
gopro.yaml | restore | пары для устранения размытия |
sr8.yaml | restore | пары для суперразрешения |
Обычный URL для скачивания есть только у coco8.yaml и coco128.yaml.
Остальные либо содержат Python-блок скачивания, для которого нужно явное
разрешение (описано ниже), либо ожидают, что данные уже лежат на диске.
Где датасет лежит на диске
Ключ path в YAML задаёт корень датасета. Абсолютный path используется как
есть. Относительный сначала ищется в каталоге датасетов, затем рядом с самим
YAML-файлом, а датасет, который предстоит скачать, попадает в каталог датасетов.
Этот каталог — ~/datasets, его переопределяет переменная окружения
LIBREYOLO_DATASETS_DIR. Файла настроек для него нет.
Ключи YAML
path: my-dataset # корень датасетаtrain: images/train # нужен для обученияval: images/val # нужен для валидацииtest: images/test # необязателенnc: 3 # необязателен; должен согласовываться с namesnames: 0: person 1: helmet 2: vestdownload: https://example.com/my-dataset.zip # необязателенtrain, val и test принимают каталог с изображениями, файл .txt с одним
путём к изображению на строку или список, где смешано и то и другое. Строки в
списке .txt могут быть относительными — тогда они разрешаются относительно
каталога самого файла со списком, — а строки, начинающиеся с #, пропускаются.
names может быть списком или отображением с целочисленными ключами. nc
необязателен; если присутствуют оба и они расходятся, doctor сообщает об этом
как об ошибке.
RF-DETR для позы читает kpt_names с ID или именем класса в ключах. Он сохраняет первые именованные строки ключевых точек каждого класса; пустой список обозначает класс только с рамками. Для позы с несколькими классами нужны names и хотя бы один класс с ключевыми точками.
Структура каталогов и файлы разметки
У детекции, сегментации, оценки позы и повёрнутых рамок структура одна. Путь к
разметке выводится из пути к изображению: компонент каталога 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 сообщает, сколько строк прошло по этому пути.
Рамки с конечными координатами, пересекающие границу изображения, одинаково обрезаются при обучении и валидации. Рамки без видимой площади, с неконечными координатами и некорректные полигоны отбрасываются. ID классов вне допустимого диапазона диагностируются до построения целевых значений. train(classes=[...]) фильтрует разметку по исходным ID классов; см. гиперпараметры.
Другие задачи
Сегментация сохраняет ту же структуру, но со строками-полигонами
<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, и путь сплита станет корнем с изображениями:
path: my-datasettrain: images/trainval: images/valannotations: 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. Без этого скрипт пропускается с
предупреждением, а обучение продолжается на том, что лежит на диске.
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.yamllibreyolo doctor my-dataset.yaml strict=true json=true# Читает только разметку и YAML. Проверки на повреждения, дубликаты# и утечки между сплитами требуют пикселей, поэтому пропускаются.libreyolo doctor my-dataset.yaml fast=truefrom 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 работает только с датасетами для детекции:
датасет для оценки позы, сегментации или повёрнутых рамок отклоняется с
сообщением о том, что именно распознано, вместо проверки по неподходящему
контракту.
Смотрите также
- Гиперпараметры — про аргументы, которые
принимает
train(), когда данные на месте. - Валидация и метрики — про оценку на сплите
valилиtest.