3、数据集准备:从标注到划分,一个都不能少

数据集的质量,直接决定了模型的天花板。你想想看,算法再牛,喂进去的数据全是错的,那结果能好吗?

这一章,我们就来聊聊数据准备的三个核心环节:标注工具的使用、格式转换、以及数据集划分策略。我个人习惯把这三步称为“数据流水线”,每一步都有坑,踩过你就记住了。

3.1 LabelImg:最顺手的标注工具

说到标注工具,我最早用的是 LabelMe,后来换成 LabelImg,就一直没换过。为什么?因为它轻量、跨平台、上手快。说白了,就是个 Python 写的图形界面工具,但该有的功能一个不少。

安装建议: 直接用 pip 安装最省事。别去 GitHub 下源码编译,浪费时间。
pip install labelImg
labelImg  # 启动

启动后,界面很简洁。左边是工具栏,中间是图片显示区,右边是标签列表。我一般会先设置好 自动保存 和 默认标签目录,省得每次手动点。

标注流程(三步走)

  1. 打开图片目录:点击 “Open Dir”,选择你的图片文件夹。
  2. 创建矩形框:按 w 键,在目标上拉个框。嗯,这里要注意,框要尽量贴合目标边缘,别留太多背景。
  3. 输入标签名:弹窗里输入类别名称,比如 person、car。按 Ctrl+S 保存。

快捷键能大幅提升效率。我常用的几个:d 下一张,a 上一张,Ctrl+u 打开目录。标注 1000 张图,用快捷键能省半小时。

避坑指南: 我曾经一次性标注了 2000 张图,结果发现标签名拼写不一致——比如 “person” 和 “Person” 混着用。模型训练时直接报错。所以,标签名必须统一大小写,最好提前列个清单。

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,省得手写。

我的经验: 如果你只是做 YOLO 训练,YOLO 格式(TXT) 是最直接的。COCO 格式更适合做多任务或模型评估。我个人习惯是:标注时用 VOC,训练前转成 YOLO 格式。

3.3 数据集划分策略:别让模型“作弊”

数据集划分,听起来简单,但做不好会出大问题。我见过有人把同一场景的图片分到训练集和验证集,结果模型在验证集上表现很好,一到真实场景就崩了。为什么?因为模型“记住”了背景,而不是目标本身。

标准划分比例

数据集 比例 用途
训练集 70% - 80% 模型学习参数
验证集 10% - 15% 调参、选模型
测试集 10% - 15% 最终评估

这个比例不是死的。数据量大的时候(比如 10 万张),验证集和测试集可以各取 5%。数据量小(比如 1000 张),就按 70/15/15 来。

划分原则

  • 随机性:用 random.shuffle 打乱数据,避免顺序偏差。
  • 分层采样:确保每个类别在训练/验证/测试集中的比例一致。比如,类别 A 占 30%,那每个子集里 A 也占 30% 左右。
  • 避免数据泄露:同一场景的图片(比如连续帧)只能出现在一个子集里。我一般会按 视频片段 或 拍摄时间 来分组,再划分。
我曾经踩过的坑: 有一次做行人检测,训练集和验证集里都包含了同一段监控视频的连续帧。模型在验证集上 mAP 高达 0.95,但上线后直接掉到 0.6。后来才发现,模型其实是“记住”了背景和行人出现的规律,而不是真正学会了检测行人。从那以后,我坚持按 视频片段 划分数据集。

3.4 知识体系总览

下面这张图,帮你把本章的核心逻辑串起来。从标注到格式转换,再到数据集划分,每一步都有对应的工具和策略。

数据集准备流程 数据集准备核心流程 原始图片 LabelImg 标注 VOC 格式 (XML) 格式转换 YOLO 格式 (TXT) COCO 格式 (JSON) 数据集划分 训练集 70% 验证集 15% 测试集 15% 核心原则:随机打乱 + 分层采样 + 避免数据泄露

3.5 实战建议

最后,给你几个实操建议:

  • 标注前先列标签清单:用 Excel 或 TXT 文件列好所有类别,标注时直接复制粘贴,避免拼写错误。
  • 转换脚本写一次,后面复用:我写了一个 convert_voc_to_yolo.py,每次新项目直接跑,省时省力。
  • 划分后检查分布:用脚本统计每个子集的类别数量,确保比例一致。我一般会打印出来看一眼,心里有底。
一句话总结: 标注要规范,转换要准确,划分要合理。这三步做好了,模型训练就成功了一半。