3、数据集准备:从标注到划分,一个都不能少
数据集的质量,直接决定了模型的天花板。你想想看,算法再牛,喂进去的数据全是错的,那结果能好吗?
这一章,我们就来聊聊数据准备的三个核心环节:标注工具的使用、格式转换、以及数据集划分策略。我个人习惯把这三步称为“数据流水线”,每一步都有坑,踩过你就记住了。
3.1 LabelImg:最顺手的标注工具
说到标注工具,我最早用的是 LabelMe,后来换成 LabelImg,就一直没换过。为什么?因为它轻量、跨平台、上手快。说白了,就是个 Python 写的图形界面工具,但该有的功能一个不少。
pip install labelImg
labelImg # 启动
启动后,界面很简洁。左边是工具栏,中间是图片显示区,右边是标签列表。我一般会先设置好 自动保存 和 默认标签目录,省得每次手动点。
标注流程(三步走)
- 打开图片目录:点击 “Open Dir”,选择你的图片文件夹。
- 创建矩形框:按
w键,在目标上拉个框。嗯,这里要注意,框要尽量贴合目标边缘,别留太多背景。 - 输入标签名:弹窗里输入类别名称,比如
person、car。按Ctrl+S保存。
快捷键能大幅提升效率。我常用的几个:d 下一张,a 上一张,Ctrl+u 打开目录。标注 1000 张图,用快捷键能省半小时。
3.2 COCO / VOC 格式:两种主流格式的转换
LabelImg 默认保存为 Pascal VOC 格式(XML 文件)。但 YOLO 训练通常用 COCO 格式(JSON 文件)或 YOLO 格式(TXT 文件)。所以,格式转换是绕不开的一步。
我见过不少新手,拿着 VOC 的 XML 直接喂给 YOLO,结果训练失败。其实转换逻辑很简单,就是 坐标系的换算。
VOC 格式(XML)
每个图片对应一个 XML 文件,里面记录了图片尺寸、目标类别、以及 左上角 + 右下角坐标(xmin, ymin, xmax, ymax)。
<annotation>
<filename>000001.jpg</filename>
<size>
<width>1920</width>
<height>1080</height>
</size>
<object>
<name>car</name>
<bndbox>
<xmin>100</xmin>
<ymin>200</ymin>
<xmax>300</xmax>
<ymax>400</ymax>
</bndbox>
</object>
</annotation>
YOLO 格式(TXT)
YOLO 用的是 归一化的中心点坐标 + 宽高。公式如下:
x_center = (xmin + xmax) / 2 / width
y_center = (ymin + ymax) / 2 / height
box_width = (xmax - xmin) / width
box_height = (ymax - ymin) / height
转换后的 TXT 文件长这样:
0 0.1042 0.2778 0.1042 0.1852
1 0.5208 0.5556 0.1562 0.2222
第一列是类别 ID(从 0 开始),后面四个是归一化后的坐标。
COCO 格式(JSON)
COCO 格式把所有标注信息放在一个 JSON 文件里。结构稍微复杂点,包含 images、annotations、categories 三个字段。我一般用现成的转换脚本,比如 voc2coco.py,省得手写。
3.3 数据集划分策略:别让模型“作弊”
数据集划分,听起来简单,但做不好会出大问题。我见过有人把同一场景的图片分到训练集和验证集,结果模型在验证集上表现很好,一到真实场景就崩了。为什么?因为模型“记住”了背景,而不是目标本身。
标准划分比例
| 数据集 | 比例 | 用途 |
|---|---|---|
| 训练集 | 70% - 80% | 模型学习参数 |
| 验证集 | 10% - 15% | 调参、选模型 |
| 测试集 | 10% - 15% | 最终评估 |
这个比例不是死的。数据量大的时候(比如 10 万张),验证集和测试集可以各取 5%。数据量小(比如 1000 张),就按 70/15/15 来。
划分原则
- 随机性:用
random.shuffle打乱数据,避免顺序偏差。 - 分层采样:确保每个类别在训练/验证/测试集中的比例一致。比如,类别 A 占 30%,那每个子集里 A 也占 30% 左右。
- 避免数据泄露:同一场景的图片(比如连续帧)只能出现在一个子集里。我一般会按 视频片段 或 拍摄时间 来分组,再划分。
3.4 知识体系总览
下面这张图,帮你把本章的核心逻辑串起来。从标注到格式转换,再到数据集划分,每一步都有对应的工具和策略。
3.5 实战建议
最后,给你几个实操建议:
- 标注前先列标签清单:用 Excel 或 TXT 文件列好所有类别,标注时直接复制粘贴,避免拼写错误。
- 转换脚本写一次,后面复用:我写了一个
convert_voc_to_yolo.py,每次新项目直接跑,省时省力。 - 划分后检查分布:用脚本统计每个子集的类别数量,确保比例一致。我一般会打印出来看一眼,心里有底。