3、数据集准备:标注格式详解、划分策略与数据增强基础
数据集准备,说白了就是给模型喂饭。饭好不好吃,直接决定模型能不能干活。我见过太多同学花大把时间调参,结果模型死活不收敛,最后发现是标注格式搞错了——这种坑,我踩过不止一次。
今天咱们就把数据集准备这块掰开揉碎。从标注格式到划分策略,再到数据增强,一条龙讲清楚。
3.1 标注格式:COCO vs YOLO
目标检测领域,标注格式五花八门。但最主流的就两个:COCO 和 YOLO。你想想看,一个来自学术界标杆,一个来自工业界神器,各有各的脾气。
3.1.1 COCO 格式
COCO 格式用 JSON 文件存储所有标注信息。结构清晰,但文件体积大。我个人习惯在需要做复杂数据分析和可视化时用 COCO 格式。
{
"images": [
{
"id": 1,
"file_name": "000001.jpg",
"width": 640,
"height": 480
}
],
"annotations": [
{
"id": 1,
"image_id": 1,
"category_id": 1,
"bbox": [100, 150, 200, 300],
"area": 60000,
"iscrowd": 0
}
],
"categories": [
{"id": 1, "name": "person"}
]
}
关键字段说明:
| 字段 | 含义 | 注意事项 |
|---|---|---|
| bbox | [x, y, width, height] | 左上角坐标 + 宽高 |
| area | bbox 面积 | width * height |
| iscrowd | 是否密集人群 | 1 表示该区域包含多个目标 |
我曾经踩过的坑:COCO 的 bbox 坐标是 (x, y, w, h),不是 (x1, y1, x2, y2)。有一次我直接用 (x1, y1, x2, y2) 喂给模型,训练了三天才发现 loss 一直降不下去。嗯,这种低级错误,犯一次就够了。
3.1.2 YOLO 格式
YOLO 格式就简单粗暴多了。每个图片对应一个 .txt 文件,每行一个目标。我建议新手直接上手 YOLO 格式,省心。
class_id x_center y_center width height
注意:所有坐标都是归一化的,范围 0~1。
# 对应图片 000001.jpg 的标注文件 000001.txt
0 0.5 0.5 0.3 0.4
1 0.2 0.3 0.1 0.2
归一化公式:
x_center = (x1 + x2) / 2 / image_width
y_center = (y1 + y2) / 2 / image_height
width = (x2 - x1) / image_width
height = (y2 - y1) / image_height
3.1.3 格式对比
| 对比维度 | COCO | YOLO |
|---|---|---|
| 存储方式 | 单个 JSON 文件 | 每个图片一个 .txt |
| 坐标类型 | 坐标 (x, y, w, h) | 归一化坐标 (cx, cy, w, h) |
| 可读性 | 结构清晰,但文件大 | 简洁,但不易直接查看 |
| 适用场景 | 学术研究、复杂数据集 | 工业部署、YOLO 系列 |
我的建议:如果你用 YOLOv5/v8/v10,直接用 YOLO 格式。如果数据集来自 COCO 或需要做复杂分析,先转成 COCO,训练时再转 YOLO。我一般写个脚本一键转换,省得来回折腾。
3.2 数据集划分策略
数据划分看着简单,其实门道不少。我见过有人随机划分,结果验证集里全是同一类——模型过拟合了都不知道。
3.2.1 标准划分比例
| 数据集 | 比例 | 作用 |
|---|---|---|
| 训练集 | 70%~80% | 模型学习参数 |
| 验证集 | 10%~15% | 调参、早停、模型选择 |
| 测试集 | 10%~15% | 最终评估,不参与训练 |
3.2.2 划分策略详解
- 随机划分:最简单,适合数据量大且分布均匀的场景。
- 分层划分:按类别比例划分,保证每个子集类别分布一致。我建议小数据集必须用这个。
- 时序划分:按时间顺序划分,适合视频流或连续场景数据。
- K 折交叉验证:数据量小时使用,但训练成本高。
核心原则:测试集必须完全独立于训练过程。我见过有人用测试集调参,结果模型在真实场景中表现一塌糊涂——这叫数据泄露,是大忌。
3.2.3 代码示例
import os
import random
import shutil
def split_dataset(data_dir, train_ratio=0.8, val_ratio=0.1, test_ratio=0.1):
images = [f for f in os.listdir(data_dir) if f.endswith('.jpg')]
random.shuffle(images)
total = len(images)
train_end = int(total * train_ratio)
val_end = int(total * (train_ratio + val_ratio))
train_set = images[:train_end]
val_set = images[train_end:val_end]
test_set = images[val_end:]
return train_set, val_set, test_set
3.3 数据增强基础
数据增强,说白了就是给模型制造「困难」。你想想看,如果训练数据全是正着拍的汽车,模型看到侧面的车就认不出来了——这不就废了吗?
3.3.1 为什么需要数据增强
- 防止过拟合:增加数据多样性,让模型学得更泛化
- 提升鲁棒性:应对光照、角度、遮挡等真实场景变化
- 扩充小数据集:数据不够,增强来凑
3.3.2 常用增强方法
| 类别 | 方法 | 说明 |
|---|---|---|
| 几何变换 | 翻转、旋转、缩放、裁剪 | 改变目标位置和姿态 |
| 颜色变换 | 亮度、对比度、饱和度、色相 | 模拟不同光照条件 |
| 噪声注入 | 高斯噪声、椒盐噪声 | 模拟传感器噪声 |
| 模糊 | 高斯模糊、运动模糊 | 模拟相机失焦或运动 |
| 遮挡 | 随机擦除、CutOut | 模拟目标被遮挡 |
| 混合 | MixUp、CutMix、Mosaic | 多张图混合,YOLO 常用 |
我的经验:YOLOv5 默认启用了 Mosaic 增强,效果很好。但要注意,训练后期可以关掉 Mosaic,让模型适应正常比例的图片。我一般在前 70% 的 epoch 用 Mosaic,后面 30% 关掉。
3.3.3 增强注意事项
- 标注同步:几何变换后,bbox 坐标也要跟着变。YOLO 的增强库(如 albumentations)会自动处理。
- 不要过度增强:把猫变成紫色,模型可能学的是「紫色物体=猫」,而不是「猫=猫」。
- 验证集和测试集不做增强:只对训练集做,否则评估结果不真实。
我曾经犯过的错:有一次做目标检测,我把验证集也做了随机翻转增强。结果模型在验证集上 mAP 很高,但真实场景中表现很差。后来才发现,验证集的数据分布已经被我「污染」了。记住:验证集和测试集必须保持原始分布。
3.4 知识体系总览
下面这张图,把数据集准备的三个核心模块串起来了。你可以把它当作操作手册,每次准备数据时对照着来。