Гиперпараметры
Каждый аргумент обучения — поле датакласса TrainConfig. Базовый класс задаёт само поле и его значение по умолчанию; каждое семейство моделей наследуется от него и переопределяет те значения, которые меняет его опубликованный рецепт.
Задание аргументов
train() принимает именованные аргументы, а CLI — те же имена в форме
key=value.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")results = model.train( data="my-dataset.yaml", epochs=100, batch=16, imgsz=640, lr0=0.01,) print(results["best_mAP50_95"])libreyolo train model=LibreYOLO9s.pt data=my-dataset.yaml \ epochs=100 batch=16 imgsz=640 lr0=0.01Оба пути ведут в одно и то же место. Аргументы передаются в
TrainConfig.from_kwargs(), который собирает датакласс конфигурации семейства.
Опечатка не вызывает ошибку
from_kwargs() отбрасывает любой ключ, которого нет среди полей конфигурации, и
выдаёт UserWarning с его именем. Обучение после этого стартует со значением по
умолчанию:
# UserWarning: Unknown training config keys (ignored): ['learning_rate']model.train(data="my-dataset.yaml", learning_rate=0.001)Ничего не падает, запуск доходит до конца, а скорость обучения так и не стала той, которую запросил вызывающий код. Читайте предупреждения на первой эпохе нового рецепта. CLI строже, потому что проверяет имена флагов до сборки конфигурации, так что флаг CLI с опечаткой отклоняется сразу.
Значения по умолчанию свои у каждого семейства
TrainConfig задаёт поле и базовое значение по умолчанию. Каждое семейство
наследуется от него и переопределяет то, что меняет его опубликованный рецепт,
поэтому у вопроса «какая скорость обучения по умолчанию» нет одного правильного
ответа.
Базовые значения по умолчанию — optimizer="sgd", lr0=0.01, momentum=0.937,
weight_decay=5e-4, scheduler="yoloxwarmcos", epochs=300, batch=16,
imgsz=640 и amp=True. Три примера того, как далеко семейство от них уходит:
| Поле | База | YOLOv9 | D-FINE | YOLO-NAS |
|---|---|---|---|---|
optimizer | sgd | sgd | adamw | adamw |
lr0 | 0.01 | 0.01 | 2e-4 | 5e-4 |
weight_decay | 5e-4 | 5e-4 | 1e-4 | 1e-5 |
scheduler | yoloxwarmcos | linear | flat_cosine | cos |
epochs | 300 | 300 | 132 | 300 |
amp | True | True | True | True |
D-FINE, DEIM, RT-DETRv4 и детекция YOLO-NAS по умолчанию используют amp=True с amp_dtype="float16". Dome-DETR, PP-YOLOE и YOLO-NAS OBB сохраняют FP32 по умолчанию. Передайте amp=False, когда нужен FP32.
Чтобы прочитать настоящие значения по умолчанию семейства, а не гадать:
from dataclasses import fields from libreyolo import LibreYOLO9from libreyolo.training.config import TrainConfig family_cfg = LibreYOLO9.TRAIN_CONFIG()base_cfg = TrainConfig() for f in fields(family_cfg): family_value = getattr(family_cfg, f.name) base_value = getattr(base_cfg, f.name, None) if not hasattr(base_cfg, f.name) or family_value != base_value: print(f"{f.name}: {family_value}")# Печатает значения по умолчанию для train, val и predict, включая переопределения семейств.libreyolo cfgРазмер батча
batch — это глобальный батч. При обучении на нескольких GPU каждый ранг
загружает batch // world_size, поэтому переданное число — это число
изображений на шаг оптимизатора независимо от того, сколько GPU задействовано.
См. Обучение на нескольких GPU.
batch=-1 включает autobatch. Модель прогоняется в режиме обучения с настоящим
обратным проходом на степенях двойки, по кривой потребления памяти строится
прямая, и берётся наибольшая степень двойки строго ниже экстраполированного
значения, которая укладывается в 60 процентов всей VRAM.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # batch=-1 замеряет память GPU и превращается в конкретную степень двойки.model.train(data="my-dataset.yaml", batch=-1, imgsz=640)libreyolo train model=LibreYOLO9s.pt data=my-dataset.yaml batch=-1Замер именно в режиме обучения и с обратным проходом — это принципиально: замер в режиме инференса не учитывает сохранённые активации и тензоры градиентов, а для глубокой CNN они в несколько раз превышают объём, нужный для инференса. RF-DETR снижает целевую долю до 45 процентов, потому что синтетический обратный проход при замере всё равно недооценивает, во что обходятся его функция потерь и вспомогательные слои декодера.
Autobatch работает только с CUDA. На CPU или MPS он пишет в лог одну строку и оставляет батч по умолчанию.
min_samples=0 оставляет длину эпохи неизменной. Положительный минимум выбирает примеры из коротких датасетов детекции с возвращением. class_balanced=False при включении задаёт повторную выборку изображений с коэффициентами повторения; она сочетается с min_samples и DDP. Специализированные загрузчики, обходящие общий семплер, отклоняют включённую балансировку.
Накопление градиентов
nbs задаёт номинальный, он же эффективный, размер батча. На один шаг
оптимизатора накапливается round(nbs / batch) микробатчей.
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # 4 микробатча по 16 на шаг оптимизатора, эффективный батч 64.model.train(data="my-dataset.yaml", batch=16, nbs=64)Если оставить None — значение по умолчанию, — накопление выключено и обучение
идёт как обычно.
Скорость обучения и расписание
lr0 — начальная скорость обучения, а optimizer принимает sgd, adam и
adamw. momentum — это момент SGD или beta1 у Adam, weight_decay —
L2-слагаемое, а nesterov относится к SGD.
Форму расписания задают scheduler, warmup_epochs, warmup_lr_start и
min_lr_ratio. no_aug_epochs задаёт, сколько последних эпох идёт без сильной
аугментации, и несколько расписаний используют его ещё и для формы своего
хвоста, так что это не только настройка аугментации. Что каждое семейство делает
с аугментационной половиной этого параметра, описано на странице
Аугментации.
Некоторые семейства добавляют свои настройки скорости обучения.
backbone_lr_mult масштабирует группу бэкбона относительно головы,
clip_max_norm задаёт обрезку градиентов, а SegFormer использует
head_lr_mult, чтобы его декодирующая голова обучалась со скоростью в десять раз
выше, чем у бэкбона. Эти поля живут в подклассе конфигурации семейства, а не в базовом.
clip_max_norm обрезает L2-норму градиента до этого значения перед каждым шагом
оптимизатора, а 0 отключает обрезку. У YOLOv9, YOLOv9-E2E и YOLOv9-P2 по
умолчанию он равен 10. У D-FINE, Dome-DETR, DEIM, DEIMv2, TinyFormer, RT-DETR,
RT-DETRv2, RT-DETRv4, RF-DETR, DINOv2, GTR и EC по умолчанию он равен 0.1. В
CLI это clip_max_norm= или --clip-max-norm; семейства, которые принимают его
там, перечислены в libreyolo train.
EMA
ema=True держит экспоненциальное скользящее среднее весов рядом с обученными.
По умолчанию оно включено везде, кроме FOMO.
ema_decay — целевой коэффициент затухания. Затухание нарастает, а не
начинается сразу с целевого значения: фактическая величина на обновлении n
равна ema_decay * (1 - exp(-n / tau)), где tau по умолчанию 2000, поэтому
ранние обновления точнее следуют за моделью, а поздние её сглаживают. Значения по
умолчанию у семейств идут от 0.997 у YOLO-NAS pose через 0.9998 у YOLOX до
0.9999 у YOLOv9 и линейки DETR.
Валидируются именно веса EMA, и они же лежат в best.pt и last.pt. Исходные
обученные веса тоже сохраняются, под ключом train_model, поэтому возобновление
продолжает обученную траекторию, а не среднее.
Точность вычислений
amp=True выполняет прямой проход под CUDA autocast. amp_dtype выбирает
float16 (по умолчанию) или bfloat16; написания fp16 и bf16 тоже
принимаются.
Float16 нуждается в динамическом масштабировании функции потерь и получает
работающий GradScaler. Bfloat16 с его более широким диапазоном экспоненты в
этом не нуждается, поэтому его scaler создаётся, но остаётся выключенным, а путь
оптимизатора при этом не меняется. Запрос bfloat16 на устройстве с CUDA без поддержки bfloat16 приводит к
ошибке на этапе настройки, а не к тихой деградации.
Вывод, чекпойнты и остановка
Запуски пишутся в project/name. project везде по умолчанию равен
runs/train, а вот name — одно из полей, переопределяемых на уровне
семейства: базовое значение по умолчанию — exp, тогда как YOLOv9 использует
yolo9_exp, а D-FINE — dfine_exp. При exist_ok=False, значении по
умолчанию, к существующему каталогу добавляется числовой суффикс, вместо того
чтобы перезаписать его.
save_period пишет дополнительный weights/epoch_<N>.pt каждые N эпох —
вдобавок к weights/last.pt после каждой эпохи и weights/best.pt всякий раз,
когда отслеживаемая метрика улучшается. eval_interval задаёт, как часто
запускается валидация, а последняя эпоха проходит валидацию всегда; val=False
выключает валидацию, и такой запуск не записывает best.pt. patience
останавливает запуск после указанного числа эпох без улучшения; 0 отключает
раннюю остановку.
cache ускоряет повторные эпохи, держа декодированные изображения в RAM (True
или "ram") либо в виде файлов .npy рядом с исходниками ("disk"). Чтение из
кэша побайтово совпадает с обычным. Если работают воркеры загрузчика данных, из
двух вариантов безопаснее "disk".
average_best=0 отключает усреднение чекпойнтов; положительное N записывает weights/average.pt из не более N лучших снимков. Тензоры с плавающей точкой усредняются равномерно, а целочисленные буферы берутся из лучшего снимка. export_check=False можно включить, чтобы остановить запуск до первой эпохи при ошибке экспорта ONNX. Совпадающие сырые выходы сравниваются с rtol=1e-3, atol=1e-4; для несовместимых структур журнал сообщает о пропуске сравнения.
precise_bn=0 отключает финальную перекалибровку BatchNorm. Положительное значение ограничивает число изображений загрузчика обучения перед финальной валидацией; в DDP лимит применяется к каждому участвующему рангу. Замороженный BatchNorm остаётся замороженным. Собственные колбэки fitness могут управлять выбором лучших чекпойнтов и patience.
Возобновление
resume=True продолжает прерванный запуск с загруженного чекпойнта;
resume="path/to/last.pt" вместо этого продолжает с указанного файла.
from libreyolo import LibreYOLO # Загрузить чекпойнт прерванного запуска, затем попросить продолжить.model = LibreYOLO("runs/train/yolo9_exp/weights/last.pt")model.train(data="my-dataset.yaml", resume=True)libreyolo train model=runs/train/yolo9_exp/weights/last.pt \ data=my-dataset.yaml resume=trueВозобновление восстанавливает сохранённые аргументы обучения запуска, а явно
переданный аргумент переопределяет сохранённый. Оно продолжает писать в каталог
запуска чекпойнта. Оно восстанавливает обученные веса, состояние оптимизатора,
веса EMA и счётчик обновлений, отслеживание лучшей метрики, масштаб GradScaler, а также
состояния генераторов случайных чисел PyTorch, CUDA и NumPy. Оно стартует с
эпохи чекпойнта плюс один и прокручивает расписание до этой точки.
Трёх вещей оно не сделает. resume=True нельзя сочетать с pretrained — это
приводит к ошибке. В опубликованных весах и в запуске, который уже дошёл до
своего epochs, возобновлять нечего, и они вызывают ValueError, который об
этом сообщает. И если ключ лучшей метрики в чекпойнте отличается от ключа
текущего запуска, отслеживание лучшей метрики сбрасывается в ноль с
предупреждением, вместо того чтобы сравнивать величины, которые означают разное.
Рецепты в файле
cfg= загружает YAML-словарь с именами полей TrainConfig и подкладывает его
под явные именованные аргументы, так что kwarg всегда побеждает файл.
from libreyolo import LibreYOLO # Ключи в yaml — имена полей TrainConfig. Явные kwargs побеждают.model = LibreYOLO("LibreYOLO9s.pt")model.train(data="my-dataset.yaml", cfg="my-recipe.yaml", epochs=50)size и num_classes из файла вырезаются, потому что они уже принадлежат
экземпляру модели. Флага --cfg в CLI нет; путь к файлу — это аргумент Python.
Смотрите также
- Датасеты — что принимает
data=. - Аугментации — настройки аугментации и то, какие семейства их учитывают.
- Заморозка слоёв и LoRA — обучение части весов.
- Валидация и метрики — что сообщает запуск.
Выбор классов и взвешивание функции потерь
Для детекции YOLO9, RF-DETR, EdgeCrafter, RT-DETR, D-FINE, DEIM, TinyFormer и YOLO-NAS параметр classes=None сохраняет все классы датасета; список фильтрует разметку, сохраняя исходные ID, nc и names. single_cls=False можно включить, чтобы переназначить сохранённые метки классу 0 с именем object. Возобновление и валидация наследуют сохранённые настройки. Обучение OBB отклоняет single_cls.
ResNet, ConvNeXt, ConvNeXt V2, MobileNetV4, EfficientNetV2 и DINOv2 поддерживают cls_pw=0.0: значения в [0, 1] взвешивают каждый класс обратной частотой в этой степени с нормализацией к среднему 1. class_weights=False при включении выбирает альтернативное взвешивание N / (C * n_c). Оно не сочетается с положительным cls_pw; возобновление требует совпадения настроек взвешивания.
plot_samples=8 задаёт лимит примеров изображений валидации. Используйте 0, чтобы не выводить их, или -1 для всех; это не уменьшает число оцениваемых изображений.