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 划分策略详解

  1. 随机划分:最简单,适合数据量大且分布均匀的场景。
  2. 分层划分:按类别比例划分,保证每个子集类别分布一致。我建议小数据集必须用这个。
  3. 时序划分:按时间顺序划分,适合视频流或连续场景数据。
  4. 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 知识体系总览

下面这张图,把数据集准备的三个核心模块串起来了。你可以把它当作操作手册,每次准备数据时对照着来。

数据集准备知识体系 标注格式 划分策略 数据增强 COCO 格式 YOLO 格式 随机划分 分层划分 几何变换 颜色变换 核心原则 标注格式要统一 → 划分策略要合理 → 数据增强要适度 高质量训练数据集 标注格式决定数据质量 划分策略决定评估可信度 数据增强决定模型泛化能力