Ultralytics YOLO27: 加入候补名单。
Get Started
构建高性能 YOLO 数据集·定义·课程 2/10
课程初级

定义数据集规范

在采集前规划场景、配额、变化维度、边缘案例和背景图像,并依据 Ultralytics 的数据量目标确定计划规模。

没有规范的团队最终会得到 5,000 张来自同一台摄像机、光线充足的白天照片,而模型在投入生产的第一天黄昏时就会失效。数据集规范是一份图像采购清单:模型必须应对的每种场景、每种场景需要的图像数量,以及需要超额采集的罕见情况。编写规范只需一小时,却决定了采集工作该投向何处。

学习成果

编写场景表,为涵盖变化维度和边缘案例的场景设置配额,并衡量任何已标注数据集与生产数据量目标之间的差距。

快速通道
如果你已经熟悉相关内容,以下是简要版。
  1. 按行列出场景:摄像机、地点、时间和条件,并为每项设置配额。

  2. 生产环境的配额应达到每个类别 ≥1,500 张图像和 ≥10,000 个已标注实例。

  3. 为每个已知边缘案例单独列一行,并超额采集。

  4. 预留 0–10% 的图像作为不含对象的背景图像。

实践操作

规范在流程中的位置#

规范是目标与摄像机之间的桥梁。它指导数据采集;当第一个模型未达到目标时,你也会回到这一页:

流程会回到规范,而不是训练设置:未达到目标通常意味着规范没有覆盖某种场景。计算机视觉项目的各个步骤指南介绍了相同的生命周期。

按行列出场景#

场景是模型必须处理的一种采集条件组合。按行列出场景并设置配额,可以在有人拿起摄像机之前就让数据缺口显现出来:

场景摄像机地点一天中的时段条件配额说明
白天装卸区cam-1 至 cam-4A–C 月台08:00–17:00不限1,200最繁忙时段
夜间装卸区cam-1 至 cam-4A–C 月台22:00–04:00不限400钠灯照明,人较少
雨天装货cam-2、cam-3B 月台不限仅雨天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 中移除这些类别,或在训练前采集相应数据。

覆盖变化维度#

Ultralytics YOLO 在海滨步道上的检测结果:近处有行人和骑行者,还有一只狗和不同距离处的汽车,每个对象都带有标注框和置信度分数

单个画面中就已经同时出现了远近不同的行人、自行车、一只狗和汽车。真正的数据集规范必须有意识地规划这种范围。针对每个维度,写明规范是否覆盖它,或者说明为何不适用;留空的行就是你将在生产环境中才发现的场景:

维度示例
时间白天、夜晚、黎明、黄昏
天气晴天、阴天、雨天、雾天、雪天
光照明亮、昏暗、眩光、硬阴影、混合光源
摄像头型号、镜头、安装高度、视场角
地理位置地点、城市、国家
人员和操作员班次、团队、制服、防护装备
产品变体SKU、包装修订版、颜色
物体尺寸近处且较大、中距离、远处且较小
遮挡无遮挡、部分遮挡、严重遮挡、隔着玻璃
设备状况脏污或起雾的镜头、损坏的托盘、磨损的地面标记

多样性比数量更重要:分布在这些类别中的 1,500 张图像,价值高于同一摄像头在中午拍摄的 5,000 张图像。

规划背景图像和边缘情况#

背景图像是没有标注物体的画面,例如空荡的装卸区。它们让模型学会识别无物体的场景,从而减少误报。

背景图像的存储方式

在 Ultralytics YOLO 格式中,背景图像就是标签文件为空或没有标签文件的图像。训练扫描行(… 1200 images, 90 backgrounds, 0 corrupt)会同时统计这两种情况。请在第一个训练轮次之前,将该数量与 0–10% 的目标范围进行核对。

边缘情况包括严重遮挡、物体被画面边缘截断、非常规方向、堆叠物体,以及外观相似的物体,例如钢柱旁的叉车门架。为每种情况单独设置配额行。

自然频率会让边缘情况样本不足

如果每 200 帧中才有 1 帧显示一个人站在堆叠的托盘后面,那么按自然频率采集的数据集中,1,500 帧里大约只有 7 帧符合这种情况,远远不足以供模型学习。要有意增加边缘情况的采样量:它们在配额表中的数量应远高于它们在真实录像中的占比。

规范不必面面俱到

你不可能在纸面上想到所有场景。先把规范基本写好,尽快训练第一个模型,再让模型的错误揭示你遗漏的场景。

试试看

为你的项目起草一张场景表,列出 5–10 行,每行设置一个数字配额,另外添加一行背景场景,并为每种已知边缘情况各添加一行。请一位在部署地点工作的人审核这张表,并补上他们提到的所有场景。然后在已有标注数据(或 COCO128)上运行 volume_gap.py,记录覆盖最充分和最不足的类别。交付物:包含该表和覆盖数量的 spec.md。

完成条件
满足以下所有条件,即表示你已完成本课程。
  • 场景表至少包含 5 行,每行都有数字配额,另外还包含背景和边缘情况行。

  • 10 个多样性维度中,至少有 5 个已覆盖或明确排除。

  • 各配额的总和至少达到每个类别的图像和实例目标,或者将差额记录为 v1 例外。

显示解答

配额应根据实例目标制定,而不只是图像目标。假设停车场计数器有两个类别,试点视频的平均每张图像包含 3 辆汽车和 0.5 辆卡车:

类别每张图像的实例数达到 10,000 个实例所需的图像数达到 1,500 张图像下限所需的图像数计划
car3.0≈ 3,3001,5003,300 张图像
truck0.5≈ 20,0001,500在装货入口定向采集,因为那里的卡车出现频率高出 10 倍

普通视频足以覆盖汽车。卡车需要 20,000 张随机图像,因此规格中会添加一个专门的场景行(装货入口,工作日 06:00–10:00),而不是把所有数据都多采六倍。再添加一行约占 5% 的背景场景(夜间空停车场),以及针对积雪覆盖和卡车部分超出画面的边缘情况行。

接下来做什么

写好规格后,下一课将采集真正满足规格要求的图像。

登录以保存学习进度