当前位置: 首页 > news >正文

【Ultralytics】「14」数据增强策略:马赛克、混合、仿射变换与分类增强

Ultralytics YOLO 框架的数据增强系统是一个高度模块化、基于组合模式的管线架构,通过将独立的增强算子串联成有序的Compose链来处理训练数据。整个系统的设计哲学是:每个增强算子仅关注自己的变换逻辑(图像变换 + 标注同步),而由统一的Instances数据结构负责承载和传播边界框、分割掩码、关键点等多模态标注信息。本文将从管线架构的宏观设计出发,逐步深入到每个增强算子的内部机制,覆盖检测/分割任务使用的马赛克(Mosaic)、混合增强(MixUp/CutMix)、仿射变换(RandomPerspective)、HSV 颜色增强、翻转、CopyPaste 以及分类任务专用的增强策略。

Sources: augment.py

增强管线架构总览

整个增强系统建立在三个核心抽象之上:BaseTransform定义单个增强算子的接口规范,Compose实现算子的有序串联,BaseMixTransform为需要多图混合的增强策略(Mosaic、MixUp、CutMix)提供统一的多图索引与标签合并框架。训练时的增强管线由v8_transforms()函数统一构建,按照固定的执行顺序编排所有增强算子。

数据流

v8_transforms 增强管线

Mosaic
马赛克拼接 (p=1.0)

CopyPaste
复制粘贴 (分割专用)

RandomPerspective
仿射/透视变换

MixUp
像素混合 (p=0.0)

CutMix
区域剪切混合 (p=0.0)

Albumentations
第三方增强库

RandomHSV
HSV 颜色抖动

RandomFlip (垂直)

RandomFlip (水平)

单个图像
+ 标注

Format
格式化输出

PyTorch Tensor
送入模型

管线的执行顺序并非随意排列,而是遵循从粗粒度到细粒度的原则:先执行涉及多图拼接的大尺度变换(Mosaic),再进行几何变换(RandomPerspective),随后是像素级混合(MixUp/CutMix),最后施加颜色和翻转等轻量变换。这种顺序确保了每个后续算子接收到的输入都是前序算子已正确处理过的数据。

Sources: augment.py

组合模式与基础框架

BaseTransform:增强算子的接口契约

BaseTransform是所有增强算子的基类,定义了三个虚方法:apply_image处理图像、apply_instances处理实例标注、apply_semantic处理语义分割掩码。其__call__方法按固定顺序依次调用这三个方法,确保图像和标注的一致性。这种设计使得子类只需覆盖自己关心的方法,而无需关心整体调度。

Sources: augment.py

Compose:增强链的有序编排器

Compose类实现了增强算子的有序串联,是整个管线的中枢调度器。它持有一个transforms列表,在__call__时依次将数据传递给每个算子——前一个算子的输出即是后一个算子的输入。Compose还提供了appendinsert__getitem____setitem__等方法,支持在运行时动态修改增强链,这对于close_mosaic等需要关闭特定增强的场景至关重要。

Sources: augment.py

BaseMixTransform:多图混合增强的统一基类

BaseMixTransform专为需要从数据集中采样多张图像进行混合的增强策略设计。其__call__方法的核心逻辑是:首先以概率p决定是否执行增强;若执行,则通过get_indexes()获取额外的图像索引,从数据集中加载对应的标签数据,应用可选的pre_transform,最后调用子类实现的_mix_transform完成实际的混合操作。这种模板方法模式将公共的多图索引与加载逻辑抽象到基类,使子类仅需关注混合算法本身。

Sources: augment.py

马赛克增强(Mosaic)

马赛克增强是 YOLO 系列最具标志性的数据增强策略,它将 4 张(或 9 张)训练图像拼接成一张大图,使模型在单次训练迭代中同时"看到"多个场景上下文,从而显著降低对大批量的依赖并提升对小目标的检测能力。

工作原理

Mosaic类继承自BaseMixTransform,通过n参数控制网格类型(4=2×2,9=3×3)。对于_mosaic4方法,核心逻辑如下:

  1. 创建 2×imgsz 大小的画布:以(114, 114, 114)灰色填充
  2. 随机生成拼接中心点(yc, xc):中心点在(-imgsz/2, 3*imgsz/2)范围内随机偏移
  3. 放置四张图像:分别放置到中心点的左上、右上、左下、右下四个象限
  4. 坐标同步:对每张图像的Instances执行反归一化 + 偏移量修正
  5. 标注合并与裁剪:将所有图像的标注合并后,裁剪到画布边界并移除零面积框

Sources: augment.py

输出

2×imgsz 拼接图
+ 合并标注

Mosaic 4 图拼接

xc, yc 随机中心

xc, yc 随机中心

xc, yc 随机中心

xc, yc 随机中心

图像 0
(左上)

图像 1
(右上)

图像 2
(左下)

图像 3
(右下)

缓冲区索引策略

当数据集缓存模式不为"ram"时,Mosaic启用buffer_enabled,从数据集缓冲区中使用random.choices(带放回采样)选取额外图像索引,而非从整个数据集中random.randint。这在内存受限时提供了更高效的索引策略。

Sources: augment.py

Mosaic 9 图变体

_mosaic9方法将 9 张图像按 3×3 网格排列,以第一张图像为中心,后续 8 张依次放置在中心图像的上、右上、右、右下、下、左下、左、左上方向。每张图像的放置位置依赖于前一张图像的尺寸,形成一种"链式拼贴"的效果。最终的输出通过裁剪border区域得到。

Sources: augment.py

close_mosaic 调度机制

训练器在训练的最后close_mosaic个 epoch(默认 10)会关闭马赛克增强。具体实现在BaseTrainer._close_dataloader_mosaic()中,它将hyp.mosaichyp.copy_pastehyp.mixuphyp.cutmix全部设为 0.0 后重新构建增强管线。这一策略的目的是让模型在训练末期适应单张图像的真实分布,避免马赛克引入的分布偏移影响最终精度。

Sources: trainer.py, dataset.py

混合增强:MixUp 与 CutMix

MixUp:像素级加权混合

MixUp增强将两张图像按随机比例进行像素级加权平均,同时合并两者的标注。混合比例r从 Beta(32.0, 32.0) 分布中采样,这意味着r通常接近 0.5 但存在随机波动。图像混合公式为img = img1 * r + img2 * (1 - r),标注则直接拼接。MixUp 默认关闭(p=0.0),可通过超参数mixup开启。

Sources: augment.py

CutMix:区域级剪切混合

CutMix是一种更加结构化的混合策略:它从源图像中剪切一个矩形区域,粘贴到目标图像的对应位置,并将该区域内的源图像标注合并到目标标注中。其核心流程包括:

  1. 随机生成候选剪切区域:生成num_areas(默认 3)个候选矩形框
  2. 筛选不重叠区域:计算候选区域与目标图像现有标注的交叉面积比(IoA),选择 IoA 之和为 0 的区域,确保剪切不会覆盖已有目标
  3. 源图像筛选:检查源图像标注在候选区域内的重叠度,分割任务要求 IoA ≥ 0.01,检测任务要求 IoA ≥ 0.1
  4. 标注裁剪与合并:将源图像在剪切区域内的标注裁剪到区域边界后合并

Sources: augment.py

MixUp 与 CutMix 对比

特性MixUpCutMix
混合方式全图像素加权平均矩形区域替换
标注处理直接拼接全部标注仅合并区域内的标注
采样分布Beta(32, 32)Beta(1, 1)
默认概率0.0(关闭)0.0(关闭)
保留空间结构否(全图混合)是(局部区域)
适用场景小目标检测泛化多尺度目标训练

Sources: augment.py

仿射与透视变换(RandomPerspective)

RandomPerspective是增强管线中最复杂的几何变换算子,它通过齐次坐标下的矩阵乘法统一实现了旋转、平移、缩放、剪切和透视畸变五种几何变换。变换矩阵M由五个 3×3 矩阵按特定顺序组合而成:

M = T ⋅ S ⋅ R ⋅ P ⋅ C M = T \cdot S \cdot R \cdot P \cdot CM=TSRPC

其中从右到左依次为:中心化矩阵 C(将坐标原点移到图像中心)、透视矩阵 P(控制透视畸变)、旋转+缩放矩阵 R(由cv2.getRotationMatrix2D生成)、剪切矩阵 S(通过tan(shear_angle)计算剪切系数)、平移矩阵 T(控制整体位移)。矩阵运算的顺序至关重要——右乘意味着 C 先作用于坐标,T 最后作用。

Sources: augment.py

标注变换的同步机制

RandomPerspective提供了三种标注类型的变换方法,确保几何变换后标注与图像保持一致:

  • apply_bboxes:将边界框的四个角点通过仿射矩阵变换后,取变换后角点集的最小外接矩形作为新的边界框。对于透视变换,还需进行齐次坐标的归一化(除以 w 分量)
  • apply_segments:对多边形分割掩码的所有顶点执行矩阵变换,然后通过segment2box重新计算边界框,并将顶点裁剪到新边界内
  • apply_keypoints:变换关键点坐标后,将超出图像边界的关键点可见性设为 0

Sources: augment.py

box_candidates:变换后的质量过滤

变换完成后,box_candidates方法通过四个条件过滤掉被几何变换严重破坏的标注:宽度 >wh_thr(2 像素)、高度 >wh_thr、长宽比 <ar_thr(100)、面积保留比 >area_thr(分割 0.01 / 检测 0.1)。这一机制确保了极端缩放、大角度旋转等情况下不会产生无效的训练样本。

Sources: augment.py

颜色增强与翻转

RandomHSV:HSV 颜色空间抖动

RandomHSV在 HSV 颜色空间中对三个通道进行独立的随机调整。它采用LUT(Look-Up Table)方式实现高效的像素级变换:为每个通道预计算一个 256 元素的查找表,然后通过cv2.LUT一次性完成全图映射。三个通道的变换公式为:

  • Hue(色调)(x + r[0] * 180) % 180,注意是加性偏移而非乘性缩放
  • Saturation(饱和度)clip(x * (r[1] + 1), 0, 255),乘性缩放
  • Value(亮度)clip(x * (r[2] + 1), 0, 255),乘性缩放

其中r是从[-1, 1]均匀分布采样的随机增益向量,乘以对应的通道增益系数hgain/sgain/vgain。一个重要的实现细节是lut_sat[0] = 0,这确保了纯白像素(饱和度为 0)在增强后不会改变颜色。

Sources: augment.py

RandomFlip:随机翻转

RandomFlip支持水平和垂直两个方向的随机翻转,概率分别由超参数fliplr(默认 0.5)和flipud(默认 0.0)控制。对于关键点任务,翻转需要通过flip_idx索引数组来交换左右对称的关键点(如左眼 ↔ 右眼),确保翻转后关键点的语义正确性。

Sources: augment.py

CopyPaste 与 Albumentations 集成

CopyPaste:分割任务的复制粘贴增强

CopyPaste实现了"Simple Copy-Paste is a Strong Data Augmentation Method for Instance Segmentation"论文中提出的方法。它支持两种模式:

  • flip模式:从当前图像的翻转副本中提取实例,通过 IoA(Intersection over Area)过滤掉与现有实例重叠超过 30% 的对象,然后按概率p选择部分实例粘贴回原图。粘贴过程通过cv2.drawContours绘制分割掩码来实现像素级精确的复制
  • mixup模式:从数据集中的另一张图像获取实例进行粘贴

Sources: augment.py

Albumentations:第三方增强库集成

Albumentations类提供了与 Albumentations 库的集成接口。默认启用的增强包括 Blur(p=0.01)、MedianBlur(p=0.01)、ToGray(p=0.01)、CLAHE(p=0.01)等,它们的触发概率极低,在训练中偶尔生效。该类会自动检测增强列表中是否包含空间变换(如 Affine、Crop、Flip 等),若包含则自动配置bbox_params以确保边界框同步变换。用户也可通过超参数augmentations传入自定义的 Albumentations 增强列表。

Sources: augment.py

分类任务增强策略

分类任务使用独立的增强管线,基于torchvision transforms构建,与检测任务的管线完全不同。它由classify_augmentations函数组装,采用三段式结构:

增强阶段包含的算子作用
主要变换RandomResizedCrop, RandomHorizontalFlip, RandomVerticalFlip尺度与几何变换
辅助变换AutoAugment/RandAugment/AugMix 或 ColorJitter自动增强策略
最终变换ToTensor, Normalize, RandomErasing格式化与擦除

classify_augmentations函数通过auto_augment参数支持三种自动增强策略:randaugment(默认,需 torchvision ≥ 0.11)、augmix(需 ≥ 0.13)、autoaugment(需 ≥ 0.10)。当启用自动增强时,默认禁用 ColorJitter 以避免过度增强,可通过force_color_jitter=True强制启用。RandomErasing(默认 p=0.4)通过随机遮挡图像的矩形区域来提升模型的鲁棒性。

Sources: augment.py, dataset.py

管线构建与超参数映射

v8_transforms是检测/分割/姿态/OBB 任务的增强管线构建入口。它接收数据集对象、目标图像尺寸和超参数命名空间,返回一个Compose链。下表展示了各超参数与增强算子的映射关系:

超参数默认值控制的增强算子作用
mosaic1.0Mosaic马赛克拼接概率
copy_paste0.0CopyPaste分割复制粘贴概率
copy_paste_mode“flip”CopyPaste复制粘贴策略
degrees0.0RandomPerspective旋转角度范围
translate0.1RandomPerspective平移比例
scale0.5RandomPerspective缩放增益
shear0.0RandomPerspective剪切角度
perspective0.0RandomPerspective透视畸变系数
mixup0.0MixUpMixUp 概率
cutmix0.0CutMixCutMix 概率
hsv_h0.015RandomHSV色调增益
hsv_s0.7RandomHSV饱和度增益
hsv_v0.4RandomHSV亮度增益
fliplr0.5RandomFlip(水平)水平翻转概率
flipud0.0RandomFlip(垂直)垂直翻转概率
bgr0.0FormatBGR 通道交换概率
close_mosaic10训练调度最后 N epoch 关闭马赛克

YOLODataset.build_transforms在调用v8_transforms时会额外检查rect模式——当启用矩形训练时,马赛克、MixUp、CutMix 会被强制关闭,因为它们与矩形批次互斥。

Sources: augment.py, default.yaml, dataset.py

LetterBox 与格式化输出

LetterBox:等比缩放与填充

LetterBox不属于增强算子,而是数据预处理中的尺寸标准化步骤。它将图像等比缩放到目标尺寸,并用灰色(默认 114)填充空白区域,保持原始宽高比。在增强管线中,它作为RandomPerspectivepre_transform使用,在仿射变换之前先完成 LetterBox 处理。

Sources: augment.py

Format:最终格式化与张量化

Format是增强管线的最后一个环节,负责将 NumPy 数组格式的数据转换为 PyTorch 张量,以供collate_fn打包成批次。它执行以下操作:将边界框转换为目标格式(xywh 或 xyxy)、归一化坐标到 [0,1]、将分割多边形转换为位图掩码、处理重叠掩码排序、将图像从 HWC 转置为 CHW 格式。

Sources: augment.py

增强策略的最佳实践

基于代码中默认超参数的设置和管线结构,以下是关键的设计考量:

马赛克增强是最核心的增强策略,默认概率为 1.0,意味着训练初期每张图像都会经过马赛克处理。它等效于将有效批量大小扩大 4 倍,对于小数据集训练尤其重要。然而,马赛克拼接引入的分布偏移(多目标、复杂背景)在训练末期可能影响收敛,因此close_mosaic=10在最后 10 个 epoch 关闭它。

MixUp 和 CutMix 默认关闭,这是因为它们在标准 COCO 训练中通常不会带来显著收益,但在特定场景(小数据集、长尾分布)下可能有效。启用时建议从较小的概率(0.1-0.3)开始。

RandomPerspective 的默认参数偏向保守——degrees=0.0shear=0.0perspective=0.0均为零,仅保留了translate=0.1scale=0.5的随机缩放平移。对于需要更强几何鲁棒性的场景(如航拍、文档检测),可以适度增大这些参数。

Sources: default.yaml, augment.py


http://www.jsqmd.com/news/792798/

相关文章:

  • IP5387微立芯支持三路C口快充的140W新国标移动电源管理芯片
  • 抛弃玩具级引擎!高危化工安全仿真如何利用UE5粒子系统与底层优化实现毫秒级防抖?
  • 基于对 goweb3 框架代码的深入分析,我为您提供以下评价
  • CoPaw:开源本地AI工作站部署与多智能体协作实战指南
  • Proteus仿真新手必看:从电阻到LCD,这30个元器件你放对了吗?
  • 基于开源AiChat搭建私有化AI对话应用:从架构设计到部署调优全指南
  • ctf show web入门37
  • 不到成衣价买定制?希颜西装体验:899起,商务休闲两穿
  • 企业团队如何利用Taotoken统一管理API密钥与下载用量报告
  • 【Redis 入门系列】为什么需要 Redis?一文串起缓存、分布式、读写分离、分库分表与微服务
  • MediaCreationTool.bat:一站式Windows系统部署与升级解决方案
  • 从“垃圾”收藏库看AI编程助手:Claude Code的幽默与协作文化
  • 企业知识库RAG到底有多难:实战3:向量化与存储
  • 开源材料信息学工具OpenClaw:模块化设计与机器学习流水线实践
  • Cursor AI 编辑器规则集:提升代码生成效率与标准化实践
  • Windows下CLion配置NDK的CMake项目,为什么你的Android.toolchain.cmake总报错?一篇讲清所有参数
  • AI赋能辅助生殖:多模态数据融合与深度学习在胚胎评估与妊娠预测中的应用
  • HIL仿真自动化测试框架:从手动验证到CI/CD持续集成的工程实践
  • 小猫爪:嵌入式小知识05-IAR icf链接文件实战:从零构建自定义内存布局
  • 单臂路由vlan综合实验
  • 存储级内存SCM:移动设备性能与功耗的革命
  • 2026届毕业生推荐的十大降重复率平台推荐榜单
  • Anthropic研究院议程:不止做AI大模型,更要定义AI时代的全球规则
  • 进程写文件时,进程发生了崩溃,已写入的数据会丢失吗?
  • DFT笔记46
  • 基于Prometheus与nvidia_gpu_exporter构建企业级GPU监控体系
  • 【三维路径规划】基于混合双向优化算法(双向A算法和人工势场法)的三维约束下平滑路径规划附Matlab代码
  • DeepRead技能包:为AI编程助手注入文档处理能力,提升OCR集成效率
  • STM32F407+LAN8720实战:手把手教你用Lwip和freeModbus搭建MODBUS TCP服务器(附完整工程)
  • 数据库连接池与性能调优详解