第四节:数据增强策略——让小目标无处遁形
数据增强,说白了就是给训练集“变花样”。
我刚开始做小目标检测时,总觉得模型效果差是网络结构的问题。后来才发现,很多时候是数据没喂对。你想想看,一张1080p的图片里,小目标可能只占几十个像素,模型看都看不清,怎么学?
这一节,我把自己常用的几种增强策略掰开揉碎了讲。每种方法我都踩过坑,也总结了一些实用技巧。
4.1 Mosaic:四张图拼一张,小目标密度翻倍
Mosaic是YOLOv4开始用的经典策略。它把四张训练图片随机裁剪后拼成一张新图。
为什么对小目标有效?
- 四张图拼在一起,相当于一张图里的小目标数量变成了原来的4倍
- 模型被迫学习在更复杂的背景中定位小目标
- BN层能看到更多样的统计分布
我的经验:Mosaic的拼图比例很关键。我习惯让四张图的面积占比在0.3-0.7之间随机,而不是固定各占25%。这样模型不会产生“目标总在固定位置”的错觉。
# 伪代码示例:Mosaic实现要点
def mosaic_augmentation(images, targets):
# 1. 随机选择中心点
center_x = random.uniform(0.25, 0.75) * W
center_y = random.uniform(0.25, 0.75) * H
# 2. 对每张图随机裁剪
for i in range(4):
crop_img = random_crop(images[i])
# 3. 拼接到对应象限
paste_to_quadrant(crop_img, i, center_x, center_y)
# 4. 注意:小目标的边界框可能被切掉
# 我一般会过滤掉面积小于原来30%的框
return mosaic_img, filtered_targets
避坑指南:我曾经在训练后期还开着Mosaic,结果发现模型对小目标的定位精度反而下降了。后来才意识到,Mosaic会改变目标的原始尺度分布。建议训练前80%的epoch使用Mosaic,后20%关掉,让模型回归到原始尺度上微调。
4.2 MixUp:两张图叠加,让模型学会“模糊”定位
MixUp最早是图像分类里的trick,后来被YOLOv5引入检测任务。它把两张图按一定比例叠加,标签也按同样比例混合。
对小目标检测来说,MixUp有个意想不到的好处:
- 小目标在叠加后可能变得更清晰(因为背景被半透明化了)
- 模型被迫学习从“半透明”特征中识别目标,泛化能力更强
- 相当于一种软标签学习,减少过拟合
我的习惯:MixUp的叠加系数alpha我一般取0.2-0.5。太小了没效果,太大了目标完全看不清。另外,我建议只对包含小目标的图片做MixUp,纯大目标的图没必要。
4.3 Copy-Paste:把小目标“复制”到更多场景
这个策略很直观——把小目标从原图中抠出来,粘贴到其他图片上。
我特别喜欢这个方法,因为它直接解决了小目标“样本少、场景单一”的问题。
# Copy-Paste 实现要点
def copy_paste(source_img, source_boxes, target_img):
# 1. 只选择小目标(面积 < 32x32)
small_boxes = [b for b in source_boxes if b.area < 1024]
# 2. 随机选择2-5个小目标
selected = random.sample(small_boxes, min(3, len(small_boxes)))
# 3. 粘贴到目标图上的随机位置
for box in selected:
# 注意:避免遮挡其他目标
paste_position = find_non_overlap_position(target_img, box)
# 可以做一些微小的缩放和旋转
paste_with_augmentation(source_img, box, target_img, paste_position)
return target_img, updated_boxes
关键技巧:粘贴时不要原样复制。我习惯对复制的小目标做±15°旋转、±10%缩放,甚至加一点高斯噪声。这样模型不会记住“某个小目标只出现在特定位置”。
4.4 随机裁剪与缩放:让模型适应不同尺度
这个策略听起来简单,但做起来有讲究。
随机裁剪不是随便裁。我见过有人把整张图裁得只剩大目标,小目标全丢了——那还不如不裁。
- 裁剪策略:我建议以目标为中心裁剪,保证每个目标至少出现在50%的裁剪图中
- 缩放策略:小目标要放大看,大目标要缩小看。我一般对原图做0.5x-2x的随机缩放
- 组合使用:先缩放再裁剪,或者先裁剪再缩放,效果不一样。我个人习惯先缩放后裁剪
我曾经踩过的坑:有一次做随机缩放,把图片缩放到0.3x,结果小目标变成了1-2个像素点,标签都变成无效的了。后来我加了一个保护机制:缩放后如果目标面积小于16像素,就重新采样。
4.5 针对小目标的过采样:让模型多看几眼
过采样不是新概念,但针对小目标做需要一些技巧。
简单来说:包含小目标的图片,多喂几次。
| 策略 | 实现方式 | 我的推荐参数 |
|---|---|---|
| 图片级过采样 | 包含小目标的图片重复2-3次 | 重复因子:2x |
| 目标级过采样 | 同一张图里的小目标复制多份 | 复制2-4份,位置随机 |
| 混合过采样 | 结合Copy-Paste和过采样 | 每张图增加3-5个小目标 |
我的建议:过采样不是越多越好。我曾经试过把包含小目标的图片重复5次,结果模型过拟合了——它记住了小目标的位置,而不是学会了检测小目标。一般2-3次就够了。
4.6 策略组合:1+1 > 2
单独用某一种策略效果有限,组合起来才是王道。
我常用的组合方案:
- 基础组合:Mosaic + MixUp + 随机缩放。适合大多数场景
- 进阶组合:Mosaic + Copy-Paste + 过采样。适合小目标极度稀疏的场景
- 终极组合:所有策略一起上,但每个策略的概率降低到0.3-0.5。适合数据量少、目标尺度差异大的场景
实战经验:我去年做一个无人机航拍项目,小目标(行人、车辆)只有10-20像素。用了Mosaic+Copy-Paste+过采样的组合,mAP从0.32直接涨到0.51。说白了,数据增强就是让模型“见多识广”。
4.7 总结与建议
数据增强没有银弹。不同的数据集、不同的模型,效果天差地别。
我的建议是:
- 先跑一个baseline,看看小目标的recall是多少
- 如果recall低(<0.3),优先用Mosaic和Copy-Paste
- 如果precision低(<0.5),优先用MixUp和随机缩放
- 如果两者都低,那就组合策略全上
嗯,这一节就到这里。下一节我们聊聊损失函数的改进——怎么让模型更关注小目标的错误。