4、数据增强:Mosaic、MixUp、HSV变换、随机缩放与裁剪、Albumentations库实战、增强效果可视化
数据增强,说白了就是给训练集「加料」。我刚开始做检测项目时,总觉得数据不够就多拍点照片呗。后来发现,很多场景你根本拍不全——比如大雾天、强逆光、目标被遮挡一半的情况。这时候,数据增强就是你的救命稻草。
YOLO 系列能这么火,数据增强策略功不可没。尤其是 Mosaic 和 MixUp,简直是给模型灌了一剂「强心针」。这一章,咱们就把这些增强手段挨个拆解一遍。
4.1 Mosaic 增强:一张图里塞四张
Mosaic 是 YOLOv4 开始引入的「杀手锏」。它把四张训练图片随机裁剪后拼成一张大图。你想想看,模型一次训练就能看到四个不同场景、不同尺度的目标。这相当于把 batch size 翻倍了,而且特别有利于小目标检测。
我在项目中遇到过一个问题:检测高空俯拍的车辆,小目标总是漏检。后来把 Mosaic 的缩放范围调大了一点,让拼图里的小车变得更小,模型反而学得更好了。嗯,这里有个小技巧——Mosaic 的缩放因子不要固定,最好随机化。
4.2 MixUp 增强:两张图叠一起
MixUp 更「暴力」——直接把两张图按一定比例叠加。标签也跟着按比例混合。比如一张图有「猫」,另一张有「狗」,混合后标签就是 0.7 猫 + 0.3 狗。
说实话,刚开始我觉得这操作有点反直觉。但实践证明,MixUp 能大幅提升模型的泛化能力。它相当于在特征空间里做了插值,让模型学会处理「模糊边界」的情况。
| 增强方法 | 核心思想 | 适用场景 | 我踩过的坑 |
|---|---|---|---|
| Mosaic | 四图拼一,尺度多样 | 小目标、密集场景 | 拼图边界出现伪目标 |
| MixUp | 两图叠加,标签混合 | 类别不平衡、过拟合 | 混合比例太极端导致训练不稳定 |
| CutMix | 裁剪一块贴到另一张图上 | 遮挡、局部特征学习 | 裁剪区域与目标重叠过多 |
4.3 HSV 变换:让模型不怕「变色」
HSV 变换就是调整图像的色相、饱和度和明度。说白了,就是给图片换滤镜。我见过很多团队只做随机亮度调整,结果模型一到黄昏场景就崩了。
我的习惯是:H 通道调 ±5°,S 通道调 ±30%,V 通道调 ±30%。这个范围基本覆盖了自然光照变化,又不会让图片变得太诡异。
4.4 随机缩放与裁剪:模拟多尺度
YOLO 本身是多尺度检测,但训练时如果图片尺寸一成不变,模型对尺度的鲁棒性还是不够。随机缩放和裁剪就是解决这个问题的。
具体做法:
- 随机缩放:在 0.5x 到 1.5x 之间随机缩放图像
- 随机裁剪:从大图中随机裁出一块,再 resize 到网络输入尺寸
- 随机翻转:水平翻转概率 50%
我曾经犯过一个错误:把缩放范围设成了 0.3x 到 2.0x。结果很多图片被缩得太小,目标都变成像素点了。模型训练了 100 个 epoch,mAP 反而下降了。后来我把范围收窄到 0.6x 到 1.3x,效果立竿见影。
4.5 Albumentations 库实战
说到数据增强工具,Albumentations 是我最常用的库。它比 OpenCV 自带的函数快 3-5 倍,而且接口统一。你想想看,几十种增强方法,全用一套 API 调用,多省心。
下面是我在 YOLO 训练中常用的 Albumentations 配置:
import albumentations as A
from albumentations.pytorch import ToTensorV2
def get_train_augmentations(img_size=640):
return A.Compose([
# 几何变换
A.RandomResizedCrop(height=img_size, width=img_size, scale=(0.6, 1.3)),
A.HorizontalFlip(p=0.5),
# 色彩变换
A.HueSaturationValue(
hue_shift_limit=5,
sat_shift_limit=30,
val_shift_limit=30,
p=0.8
),
A.RandomBrightnessContrast(
brightness_limit=0.2,
contrast_limit=0.2,
p=0.8
),
# 噪声与模糊
A.GaussNoise(var_limit=(10.0, 30.0), p=0.3),
A.Blur(blur_limit=3, p=0.2),
# 归一化与张量化
A.Normalize(mean=[0, 0, 0], std=[1, 1, 1]),
ToTensorV2()
], bbox_params=A.BboxParams(
format='yolo',
label_fields=['class_labels']
))
bbox_params。否则增强后的图片和标注框对不上。我曾经忘了加这个参数,结果模型训练了三天,验证集 mAP 一直是 0。排查了半天才发现是标注框没跟着图片一起变换。
4.6 增强效果可视化
数据增强不是「黑盒操作」。我强烈建议你把增强后的图片可视化出来看看。很多时候,你以为的「增强」其实是在「破坏」数据。
可视化步骤:
- 从训练集中随机取 8-16 张图片
- 对每张图片应用增强 pipeline
- 把原图和增强图并排显示
- 检查标注框是否对齐、图片是否失真
我一般用 Matplotlib 做可视化,代码很简单:
import matplotlib.pyplot as plt
import numpy as np
def visualize_augmentations(dataset, num_samples=4):
fig, axes = plt.subplots(num_samples, 2, figsize=(10, 4*num_samples))
for i in range(num_samples):
# 原图
img, boxes, _ = dataset[i]
axes[i, 0].imshow(img)
axes[i, 0].set_title('Original')
# 增强图
augmented = get_train_augmentations()(
image=np.array(img),
bboxes=boxes,
class_labels=['object']*len(boxes)
)
axes[i, 1].imshow(augmented['image'])
axes[i, 1].set_title('Augmented')
plt.tight_layout()
plt.show()
数据增强不是越多越好。我见过有人把十几种增强全堆上去,结果模型训练了 200 个 epoch 还在震荡。记住一个原则:增强策略要模拟真实场景,而不是创造「不存在」的场景。你想想看,如果训练集里全是扭曲变形的图片,模型怎么可能在正常图片上表现好?