定义数据集规范
在采集前规划场景、配额、变化维度、边缘案例和背景图像,并依据 Ultralytics 的数据量目标确定计划规模。
没有规范的团队最终会得到 5,000 张来自同一台摄像机、光线充足的白天照片,而模型在投入生产的第一天黄昏时就会失效。数据集规范是一份图像采购清单:模型必须应对的每种场景、每种场景需要的图像数量,以及需要超额采集的罕见情况。编写规范只需一小时,却决定了采集工作该投向何处。
实践操作
规范在流程中的位置#
规范是目标与摄像机之间的桥梁。它指导数据采集;当第一个模型未达到目标时,你也会回到这一页:
流程会回到规范,而不是训练设置:未达到目标通常意味着规范没有覆盖某种场景。计算机视觉项目的各个步骤指南介绍了相同的生命周期。
按行列出场景#
场景是模型必须处理的一种采集条件组合。按行列出场景并设置配额,可以在有人拿起摄像机之前就让数据缺口显现出来:
| 场景 | 摄像机 | 地点 | 一天中的时段 | 条件 | 配额 | 说明 |
|---|---|---|---|---|---|---|
| 白天装卸区 | cam-1 至 cam-4 | A–C 月台 | 08:00–17:00 | 不限 | 1,200 | 最繁忙时段 |
| 夜间装卸区 | cam-1 至 cam-4 | A–C 月台 | 22:00–04:00 | 不限 | 400 | 钠灯照明,人较少 |
| 雨天装货 | cam-2、cam-3 | B 月台 | 不限 | 仅雨天 | 200 | 罕见但关键 |
| 堆叠托盘 | 不限 | 不限 | 不限 | 高度 > 2 个托盘 | 150 | 会挡住后面的人 |
| 背景 | 不限 | 不限 | 不限 | 空置装卸区 | 150 | 没有对象,也没有标签 |
你无法写明的场景,模型就不会在训练中见到;它最终会成为生产环境中失效的场景。
依据数据量目标确定规范规模#
Ultralytics 的获得最佳训练效果的技巧提供了适用于生产环境的经验法则:
| 目标 | 建议 |
|---|---|
| 每个类别的图像数 | ≥ 1,500 |
| 每个类别的已标注实例数 | ≥ 10,000 |
| 背景图像数(无标签) | 占数据集的 0–10%;COCO 约为 1% |
| 多样性 | 不同的时间、季节、天气、光照、角度、来源和摄像机 |
这些是生产模型应达到的基准。每个类别有几百个已标注对象就足以开始试验,而第一个模型是最快了解哪些场景需要更多数据的方式。要了解数据集距离基准有多远,就统计一下。这个脚本可以在 COCO128 上运行;这是 COCO 中一个包含 128 张图像的子集,会自动下载:
from collections import Counter
from pathlib import Path
from ultralytics.data.utils import IMG_FORMATS, check_det_dataset, img2label_paths
IMAGES_PER_CLASS, INSTANCES_PER_CLASS = 1500, 10_000 # Ultralytics production targets
data = check_det_dataset("coco128.yaml") # downloads COCO128 (~7 MB) on first run; swap in your data YAML
images = [p for p in Path(data["train"]).rglob("*.*") if p.suffix[1:].lower() in IMG_FORMATS]
image_count, instance_count, background = Counter(), Counter(), 0
for label in map(Path, img2label_paths([str(p) for p in images])):
classes = [int(r.split()[0]) for r in label.read_text().splitlines() if r.strip()] if label.exists() else []
instance_count.update(classes)
image_count.update(set(classes))
background += not classes
print(f"{len(images)} images, {background} background ({background / len(images):.0%}, target 0-10%)")
print(f"{'class':>12} {'images':>7} {'instances':>10} {'of target':>10}")
ranked = instance_count.most_common()
for cls, n in ranked[:3] + ranked[-3:]: # best and worst covered classes
coverage = min(image_count[cls] / IMAGES_PER_CLASS, n / INSTANCES_PER_CLASS)
print(f"{data['names'][cls]:>12} {image_count[cls]:>7} {n:>10} {coverage:>10.1%}")
never_labeled = [name for i, name in data["names"].items() if i not in instance_count]
print(f"{len(never_labeled)} classes in names with zero labels: {never_labeled[:4]} ...")128 images, 2 background (2%, target 0-10%)
class images instances of target
person 61 254 2.5%
car 12 46 0.5%
cup 10 36 0.4%
bear 1 1 0.0%
banana 1 1 0.0%
skis 1 1 0.0%
9 classes in names with zero labels: ['fire hydrant', 'parking meter', 'sheep', 'cow'] ...如何解读:
- 覆盖率取图像比例和实例比例中的较小值,因为每个类别两方面都必须达到要求。即使是覆盖率最高的类别
person,也只达到生产基准的 2.5%。 - 只有一个实例的类别(
bear、banana、skis)无法用于学习或评估。在你的数据集中,要么采集更多此类数据,要么从 v1 中移除这些类别。 - 没有标签的类别列在 YAML 中,却从未被标注。模型仍会把容量用于预测这些类别。请从
names中移除这些类别,或在训练前采集相应数据。
覆盖变化维度#

单个画面中就已经同时出现了远近不同的行人、自行车、一只狗和汽车。真正的数据集规范必须有意识地规划这种范围。针对每个维度,写明规范是否覆盖它,或者说明为何不适用;留空的行就是你将在生产环境中才发现的场景:
| 维度 | 示例 |
|---|---|
| 时间 | 白天、夜晚、黎明、黄昏 |
| 天气 | 晴天、阴天、雨天、雾天、雪天 |
| 光照 | 明亮、昏暗、眩光、硬阴影、混合光源 |
| 摄像头 | 型号、镜头、安装高度、视场角 |
| 地理位置 | 地点、城市、国家 |
| 人员和操作员 | 班次、团队、制服、防护装备 |
| 产品变体 | SKU、包装修订版、颜色 |
| 物体尺寸 | 近处且较大、中距离、远处且较小 |
| 遮挡 | 无遮挡、部分遮挡、严重遮挡、隔着玻璃 |
| 设备状况 | 脏污或起雾的镜头、损坏的托盘、磨损的地面标记 |
多样性比数量更重要:分布在这些类别中的 1,500 张图像,价值高于同一摄像头在中午拍摄的 5,000 张图像。
规划背景图像和边缘情况#
背景图像是没有标注物体的画面,例如空荡的装卸区。它们让模型学会识别无物体的场景,从而减少误报。
在 Ultralytics YOLO 格式中,背景图像就是标签文件为空或没有标签文件的图像。训练扫描行(… 1200 images, 90 backgrounds, 0 corrupt)会同时统计这两种情况。请在第一个训练轮次之前,将该数量与 0–10% 的目标范围进行核对。
边缘情况包括严重遮挡、物体被画面边缘截断、非常规方向、堆叠物体,以及外观相似的物体,例如钢柱旁的叉车门架。为每种情况单独设置配额行。
如果每 200 帧中才有 1 帧显示一个人站在堆叠的托盘后面,那么按自然频率采集的数据集中,1,500 帧里大约只有 7 帧符合这种情况,远远不足以供模型学习。要有意增加边缘情况的采样量:它们在配额表中的数量应远高于它们在真实录像中的占比。
你不可能在纸面上想到所有场景。先把规范基本写好,尽快训练第一个模型,再让模型的错误揭示你遗漏的场景。
显示解答
配额应根据实例目标制定,而不只是图像目标。假设停车场计数器有两个类别,试点视频的平均每张图像包含 3 辆汽车和 0.5 辆卡车:
| 类别 | 每张图像的实例数 | 达到 10,000 个实例所需的图像数 | 达到 1,500 张图像下限所需的图像数 | 计划 |
|---|---|---|---|---|
car | 3.0 | ≈ 3,300 | 1,500 | 3,300 张图像 |
truck | 0.5 | ≈ 20,000 | 1,500 | 在装货入口定向采集,因为那里的卡车出现频率高出 10 倍 |
普通视频足以覆盖汽车。卡车需要 20,000 张随机图像,因此规格中会添加一个专门的场景行(装货入口,工作日 06:00–10:00),而不是把所有数据都多采六倍。再添加一行约占 5% 的背景场景(夜间空停车场),以及针对积雪覆盖和卡车部分超出画面的边缘情况行。