Augmentations

Augmentation is configured by knobs on TrainConfig, but each model family runs its own training pipeline, and a pipeline that has no mosaic branch ignores mosaic_prob rather than approximating it.

Setting the knobs

The augmentation knobs are ordinary train() arguments.

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")model.train(    data="my-dataset.yaml",    epochs=100,    mosaic_prob=1.0,    mixup_prob=0.15,    hsv_prob=1.0,    flip_prob=0.5,    no_aug_epochs=15,)
CLI
# The CLI spells mosaic_prob as mosaic and mixup_prob as mixup.libreyolo train model=LibreYOLO9s.pt data=my-dataset.yaml \  epochs=100 mosaic=1.0 mixup=0.15 hsv_prob=1.0 \  flip_prob=0.5 no_aug_epochs=15

Two of them have shorter CLI spellings: mosaic maps to mosaic_prob and mixup maps to mixup_prob. Every other knob is spelled identically in both places.

Three states, not two

Whether a knob does anything depends on the family. The library keeps a declarative table of that, and each entry is one of three states.

used means the knob reaches the pipeline and changes samples. ignored means it never reaches the pipeline, so setting it does nothing. gated_by_mosaic means it only applies to samples that took the mosaic branch, so with mosaic_prob=0 it never fires even though it is wired up.

That third state is the one that surprises people. On a YOLOX-style pipeline the affine warp runs on the mosaic canvas and MixUp blends a mosaic sample, so mosaic_prob=0 silently disables degrees, translate, shear, perspective, mosaic_scale, mixup_prob and mixup_scale all at once. The trainer logs a warning for the MixUp case specifically:

mixup_prob=0.15 has no effect for YOLOv9: mixup only applies to mosaic samplesand mosaic_prob=0. Set mosaic_prob > 0 to enable mixup.

The CLI warns about ignored knobs too, listing only the ones you actually typed:

Warning: RF-DETR ignores these parameters: degrees, mosaic

Four pipeline shapes

Families cluster into four training pipelines, and the pipeline determines almost all of the answers.

The YOLOX-style mosaic pipeline applies HSV jitter and flips per sample, then runs affine and MixUp inside the mosaic branch. It covers YOLOX, YOLOv7, YOLOv9 and its E2E and P2 variants, RTMDet, PicoDet, RT-DETR, RT-DETRv2 and FOMO.

The DETR-style pass-through pipeline has no mosaic and no affine warp. Its photometric distortion, zoom-out and IoU crop are recipe constants rather than config knobs, so only flip_prob and no_aug_epochs are live. It covers D-FINE, Dome-DETR, DEIM, DEIMv2, RT-DETRv4, EC and, with one change, RF-DETR.

The classification ImageFolder pipeline ignores every detection knob. Its horizontal flip is a fixed 0.5 that flip_prob does not reach. It has its own knob pack instead, described below.

YOLO-NAS is a shape of its own: no mosaic at all, an always-on per-sample affine, and MixUp applied independently rather than gated. Its mosaic_scale value is reused as the affine scale range.

SegFormer and NAFNet each run a task-specific pipeline whose randomness is fixed in the family rather than configurable. For SegFormer the live knobs are the class attributes semantic_scale_jitter and semantic_hsv_prob, not mosaic_scale and hsv_prob. NAFNet's crop and flips are coupled input and target operations at a fixed 0.5 probability.

Which family honors which knob

The table below is the shipped spec at libreyolo/data/augment/spec.py, which is asserted against the real pipeline plumbing by the library's own tests. Read it there rather than inferring from the architecture.

Read the support table for a family
from libreyolo.data.augment.spec import AUG_KNOBS, aug_support for knob, description in AUG_KNOBS.items():    support = aug_support("yolo9")[knob]    print(f"{knob:16} {support.status:16} {support.note or description}")
Just the ignored ones
from libreyolo.data.augment.spec import ignored_aug_params print(sorted(ignored_aug_params("rfdetr")))

Summarized by pipeline, for the base knobs:

KnobYOLOX-styleYOLO-NASDETR-styleClassification
mosaic_probusedignoredignoredignored
mixup_probgated by mosaicusedignoredignored
hsv_probusedusedignoredignored
flip_probusedusedusedignored
flipudusedusedignoredignored
degreesgated by mosaicusedignoredignored
translategated by mosaicusedignoredignored
sheargated by mosaicusedignoredignored
perspectivegated by mosaicusedignoredignored
mosaic_scalegated by mosaicusedignoredignored
mixup_scalegated by mosaicusedignoredignored
no_aug_epochsusedusedusedused

Exceptions inside those columns, all of them narrowing:

  • RTMDet, PicoDet, RT-DETR, RT-DETRv2 and FOMO have no vertical flip, so flipud is ignored. FOMO's mosaic wrapper is also built without perspective.
  • RF-DETR's native pipeline has no HSV jitter, so hsv_prob is ignored on top of the DETR-style column.
  • EC honors hsv_prob, degrees and translate, but only for task="pose", whose keypoint-aware transform reads them. Its detect and segment paths use fixed photometric recipes.
  • DINOv2 follows the DETR-style column for its detect and semantic tasks and adds the classification pack for task="classify".

no_aug_epochs is used everywhere, but it does not mean the same thing everywhere. On the mosaic pipelines it turns mosaic and MixUp off for the final epochs. On the DETR-style pipelines it stops the photometric, zoom-out and crop augmentations and shapes the schedule's tail. On the classification and semantic pipelines it only shapes the tail.

The classification pack

Four knobs drive the classification pipeline and nothing else. Detection families ignore all four.

Classification pack
from libreyolo import LibreYOLO model = LibreYOLO("LibreConvNeXtt-cls.pt")model.train(    data="my-classification-dataset",    epochs=50,    auto_augment="randaugment",    erasing=0.25,    mixup=0.2,    cutmix=0.2,)

auto_augment takes "randaugment", "autoaugment", "augmix" or None. erasing is the RandomErasing probability. mixup and cutmix are per-batch probabilities producing soft labels; at most one runs per batch, MixUp first, so the two are additive and should sum to at most 1.

All four default off, so classification training is unchanged unless you ask.

One naming collision is worth stating plainly: on the CLI, mixup is the alias for the detection mixup_prob. The classification mixup field has no CLI spelling of its own and is reachable only through model.train(mixup=...) in Python.

Family-specific knobs

Some knobs live on a family's config subclass rather than on the base class, so they exist for that family only and have no CLI flag.

FamilyKnobEffect
YOLOv9, YOLOv9-E2E, YOLOv9-P2copy_pasteCopy-paste instance augmentation probability, task="segment" only
YOLOv9, YOLOv9-E2E, YOLOv9-P2copy_paste_mode"flip" reuses the same sample mirrored, "mixup" pulls a second sample
YOLOv9, YOLOv9-E2E, YOLOv9-P2rot90Random 90 degree rotation probability
YOLOv9max_labelsPer-image ground-truth cap in the train transforms, default 100
RF-DETRcopy_paste, copy_paste_modeCopy-paste for task="segment", "flip" mode only
RF-DETR, D-FINE, ECcrop_resize_probRandom crop-resize probability
EC, YOLO-NASbrightness_contrast_prob, affine_probPose-path jitter and keypoint-aware affine probabilities

max_labels is the one that silently loses data. Boxes past the cap are dropped without an error, so dense imagery such as aerial photography needs it raised.

Mosaic and MixUp are disabled for oriented-box training regardless of the knobs, because corner-aware augmentation for rotated boxes is not implemented.

  • Hyperparameters for no_aug_epochs as a schedule argument and the rest of train().
  • Datasets for the label formats these transforms consume.

Verified against LibreYOLO v1.5.0.