Ultralytics YOLO27: Join the waitlist.
Get Started
Lessonbeginner

Use Augmentation Carefully

Test every augmentation against the deployment camera, build a justified profile, train with it, and check the result in training batches.

Picture a sorting line that separates red capsules from orange ones, trained with the default hue jitter. Every epoch shows the model red capsules tinted orange, so it learns that color doesn't matter, which is the one thing it had to learn. Augmentation makes a model sturdier only when each transform is something the deployment camera could really produce. This lesson gives you the test that decides which transforms stay.

Outcome

Choose an augmentation profile with a one-line deployment justification for every changed argument, train with it, and verify it in train_batch0.jpg.

Fast Track
If you already know your way around, here's the short version.
  1. Train with default augmentation first and record the baseline.

  2. Disable transforms the camera can never produce, such as hue shifts when color defines a class.

  3. Enable transforms it can produce, such as flipud for top-down views.

  4. Open train_batch0.jpg and confirm boxes stay tight and class cues survive.

Hands-on

What augmentation does#

Augmentations of one macaw photo: horizontal flip, crop, median blur, contrast, hue-saturation-value shift, and gamma

Data augmentation transforms training images on the fly, so the model sees a slightly different version of each image every epoch. Done well, it improves robustness to lighting, scale, and orientation and reduces overfitting, because the model can't memorize images that keep changing. Done badly, it teaches physically impossible scenes and hides dataset gaps you should be fixing.

Look at the hue panel above: the red macaw turns yellow. That's harmless for "macaw vs. not macaw" and destructive if color is what separates two of your classes.

The defaults that matter#

These are the defaults in Ultralytics 8.4; the augmentation settings reference lists every argument:

ArgumentDefaultWhat it doesChange it when
hsv_h0.015Hue jitterSet to 0 when color defines a class
hsv_s / hsv_v0.7 / 0.4Saturation and brightness jitterLower if lighting is fixed and controlled
degrees0.0Random rotation (±degrees)Raise when objects appear at any angle
translate / scale0.1 / 0.5Shift and zoomLower if crops can cut off class-defining parts
fliplr0.5Horizontal flip probabilitySet to 0 when left and right matter, as with text
flipud0.0Vertical flip probabilityRaise for top-down, aerial, or microscope views
mosaic1.0Stitches four images into oneRarely; see close_mosaic
close_mosaic10Turns mosaic off for the final N epochsLower for very short runs
mixup / cutmix0.0 / 0.0Blend two images / paste a patch of one onto anotherTry on small datasets, after a baseline
copy_paste0.0Pastes object instances between imagesSegment, semantic, and OBB datasets with rare classes

Depth datasets are the exception: mosaic, mixup, cutmix, and copy_paste would produce invalid paired depth maps, so the depth loader sets them to 0 automatically.

The deployment test#

Every enabled transform must pass one question, then a second:

TransformRealistic?Verdict
Brightness ±30% on an outdoor cameraYes: time of dayKeep
Horizontal flip on a security cameraYes: people walk both waysKeep
Vertical flip on a wall-mounted cameraNo: the floor stays at the bottomDisable
Vertical flip on a top-down conveyor cameraYes: there's no "up" in the frameEnable
90° rotation on a fixed road cameraNo: the camera never rotatesDisable
Hue shift when red and green parts are different classesNo: destroys the signalDisable

Rotation augmentation of 180 degrees: an upside-down macaw, a view a fixed upright camera never produces

An upside-down macaw is a fine training image for a drone looking straight down, and a wasted one for a camera bolted to a wall. Transforms that fail the test produce negative training signal: the model learns to recognize images it will never see, at the cost of capacity for the ones it will.

A worked profile#

A top-down camera over a conveyor sorts parts whose classes differ only by color. Hue jitter must go, while vertical flips and small rotations become realistic. This runs as shown on the COCO8 demo set; swap in your data YAML and a real epoch count:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
model.train(
    data="coco8.yaml",
    epochs=1,
    imgsz=320,
    hsv_h=0.0,  # color is the class signal: keep hues true
    flipud=0.5,  # top-down view: no "up" in the frame
    degrees=10.0,  # parts land at any small angle
)

Open train_batch0.jpg in the run folder and check three things: boxes stay tight after the transform, class-defining cues (color, shape, text) survive, and nothing looks physically impossible. Scale back any transform that breaks one of them. Train Your First Model covers the training run itself.

Mosaic and close_mosaic#

Mosaic augmentation stitching four parrot photos into one training image

Mosaic stitches four images into one and is on by default. It's the highest-leverage augmentation for detection: every training image packs several scenes, scales, and object contexts. The catch is that mosaic images don't look like deployment frames, so close_mosaic=10 turns it off for the final 10 epochs and the model finishes on realistic inputs. Closing mosaic also switches off mixup, cutmix, and copy_paste, while flips, HSV, and the geometric transforms keep running.

Short runs never use mosaic

In runs no longer than close_mosaic epochs, including the one-epoch profile above, mosaic is off from the first epoch. Judge mosaic from train_batch0.jpg of a full-length run, not a smoke test.

What augmentation cannot fix#

Augmentation is a multiplier on what's already there. If the dataset has no nighttime images, no setting produces night: it produces brighter and darker versions of day. If a class only works with aggressive augmentation, you don't have enough of that class. Go back to Collect High-Quality, Representative Data.

Cranking every knob hides the real problem

A small dataset with every augmentation at its maximum trains on images further and further from deployment, and val mAP often falls. Change one argument at a time, with a reason, and compare against the default baseline on the same split.

When crops erase the class

If a class is defined by a small part of the object, such as the corner symbol on a playing card, mosaic, translate, and scale can crop that part away and create a training image that looks exactly like a different class. Lower those values for that dataset, and confirm the fix in train_batch0.jpg.

Try It

Mark each argument in the defaults table as keep, change, or disable for your deployment, with one line of justification per change. Train once with defaults and once with your profile on the same split, and record val mAP50-95 for both. Deliverable: the annotated table, both scores, and a train_batch0.jpg from the custom run.

Done When
You've finished the lesson when all of these are true.
  • Every changed argument has a one-line deployment justification.

  • Default and custom profiles are compared on the same val split.

  • train_batch0.jpg from the custom run shows tight boxes and intact class cues.

Show solution

A drone surveys a port from straight above, detecting ships with oriented boxes. From that viewpoint there's no "up", ships point in every direction, and color doesn't define the class:

ArgumentChoiceJustification
flipud0.5A top-down view looks the same flipped vertically
degrees180Ships appear at every heading
hsv_hdefaultHull color varies and isn't a class signal
mosaicdefaultMany small objects per image; mosaic helps

On the DOTA8 aerial demo set:

yolo obb train data=dota8.yaml model=yolo26n-obb.pt epochs=1 imgsz=320 flipud=0.5 degrees=180

For a fixed street camera, the same two changes would fail the deployment test: cars are never upside down on a wall-mounted feed.

What's next

Dataset, splits, and augmentation are in place; the next lesson decides objectively whether the dataset is ready to train.