首页
/ Ultralytics SKU-110K 零售货架密集场景检测数据集:从 YAML 配置到 YOLO 训练全流程解析

Ultralytics SKU-110K 零售货架密集场景检测数据集:从 YAML 配置到 YOLO 训练全流程解析

2026-09-04 20:29:45作者:董宙帆

SKU-110K 是 Ultralytics 官方支持的一个单类、高目标密度的零售货架目标检测数据集,常用于训练和评测 YOLO 系列模型在拥挤场景下的检测能力。本文基于仓库中的 SKU-110K 数据集文档SKU-110K.yaml 配置文件 展开,讲清该数据集的划分、YAML 配置、自动下载与标注转换机制,以及训练 YOLO26 的完整命令与代码写法,帮助你把这套"13.6 GB 一键下载 + 自动转 YOLO 格式"的数据集真正用起来。

一、SKU-110K 数据集概览

SKU-110K 是一个由 Eran Goldman 等人(CVPR 2019 论文《Precise Detection in Densely Packed Scenes》)创建的单类目标检测数据集,包含 11,743 张密集排列的零售货架图像,划分为 8,219 张训练、588 张验证、2,936 张测试图像。

理解这个数据集有三个关键数字:

  • 1 个检测类别:所有商品都标注为一个 object 框(names: {0: object}),标注中不包含任何逐 SKU 的品类信息;
  • 11 万个 SKU:"SKU-110K" 的 "110K" 指的是横跨全部图像的不重复 store-keeping unit(商品单元)数量超过 11 万,而不是 11 万个检测类别——这是该数据集最常见的误解;
  • 170 万个标注框:全部图像累计超过 170 万个商品标注框,平均每张图像约 147 个紧密排列的商品目标。

这种"同类目标高度相似、彼此紧邻"的密集排列,使 SKU-110K 成为检验检测器在拥挤零售环境中定位精确性的典型基准。数据集许可为 Research-Only(仅研究用途),实际工程使用前应自行确认授权范围。

二、关键特性与适用场景

文档归纳了 SKU-110K 的三大关键特性:

  1. 单类检测(Single-class detection):每个商品一个边界框,全部归入唯一类别 object,模型只需学习"哪里有商品",而不需要区分具体商品种类;
  2. 极致的目标密度(Extreme object density):图像来自世界各地的商店货架,平均每张约 147 个目标,且外观相近甚至相同的商品常常紧贴在一起,对 NMS、小目标定位和重叠框区分都是强考验;
  3. 大规模(Large scale):11 万+ 唯一 SKU、170 万+ 标注框、11,743 张图像,足以训练并压测最先进的检测器。

文档列出的典型应用方向包括:

  • 零售库存管理与自动化(retail inventory management);
  • 电商平台中的商品识别(product recognition);
  • 陈列图合规校验(planogram compliance verification);
  • 门店自助结账系统(self-checkout);
  • 仓库中的机器人抓取与分拣(robotic picking and sorting)。

如果你的目标恰好是"数货架上的商品"、"检测漏摆/错摆位置"这类任务,SKU-110K 提供的高密度单类标注形态与实际业务高度吻合。

三、数据集划分

SKU-110K 的三个子集共享同一个 object 类别:

划分 图像数 用途
Train 8,219 模型训练的图像与标注
Validation 588 训练期间用于 验证 的留出图像
Test 2,936 训练完成后的最终评测图像

三个子集各自以图像清单文件(train.txt / val.txt / test.txt)形式引用,这也是理解其 YAML 配置的关键。

四、数据集 YAML 配置详解

数据集配置由 ultralytics/cfg/datasets/SKU-110K.yaml 定义,包含数据集路径、类别名和一段内嵌的下载/转换脚本。完整内容如下:

# Ultralytics AGPL-3.0 License - https://ultralytics.com/license

# SKU-110K retail items dataset by Trax Retail
# Example usage: yolo train data=SKU-110K.yaml
# parent
# ├── ultralytics
# └── datasets
#     └── SKU-110K ← downloads here (13.6 GB)

# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, ...]
path: SKU-110K # dataset root dir
train: train.txt # train images (relative to 'path') 8219 images
val: val.txt # val images (relative to 'path') 588 images
test: test.txt # test images (optional) 2936 images

# Classes
names:
  0: object

# Download script/URL (optional)
download: |
  import shutil
  from pathlib import Path
  import numpy as np
  import polars as pl
  from ultralytics.utils import TQDM
  from ultralytics.utils.downloads import download
  from ultralytics.utils.ops import xyxy2xywh

  # Download
  dir = Path(yaml["path"])  # dataset root dir
  parent = Path(dir.parent)  # download dir
  urls = ["http://trax-geometry.s3.amazonaws.com/cvpr_challenge/SKU110K_fixed.tar.gz"]
  download(urls, dir=parent)

  # Rename directories
  if dir.exists():
      shutil.rmtree(dir)
  (parent / "SKU110K_fixed").rename(dir)  # rename dir
  (dir / "labels").mkdir(parents=True, exist_ok=True)  # create labels dir

  # Convert labels
  names = "image", "x1", "y1", "x2", "y2", "class", "image_width", "image_height"  # column names
  for d in "annotations_train.csv", "annotations_val.csv", "annotations_test.csv":
      x = pl.read_csv(dir / "annotations" / d, has_header=False, new_columns=names, infer_schema_length=None).to_numpy()
      images, unique_images = x[:, 0], np.unique(x[:, 0])
      with open((dir / d).with_suffix(".txt").__str__().replace("annotations_", ""), "w", encoding="utf-8") as f:
          f.writelines(f"./images/{s}\n" for s in unique_images)
      for im in TQDM(unique_images, desc=f"Converting {dir / d}"):
          cls = 0  # single-class dataset
          with open((dir / "labels" / im).with_suffix(".txt"), "a", encoding="utf-8") as f:
              for r in x[images == im]:
                  w, h = r[6], r[7]  # image width, height
                  xywh = xyxy2xywh(np.array([[r[1] / w, r[2] / h, r[3] / w, r[4] / h]]))[0]
                  f.write(f"{cls} {xywh[0]:.5f} {xywh[1]:.5f} {xywh[2]:.5f} {xywh[3]:.5f}\n")  # write label

逐项解读配置语义:

  • path: SKU-110K:数据集根目录,相对于数据集下载目录(默认 datasets/,即解压后位于 datasets/SKU-110K)。注释中的目录树提示了最终落盘位置,总大小约 13.6 GB
  • train/val/test: *.txt:这里采用的是 Ultralytics 数据集 YAML 三种引用形式中的"图像清单文件"形式(另一种是直接指向图像目录,或目录列表)。train.txtval.txttest.txt 每行一条 ./images/xxx 相对路径,由下方下载脚本自动生成;
  • names: {0: object}:唯一的检测类别。check_det_dataset 会据此推导 nc = 1
  • download: | 内嵌 Python 脚本:这是理解"第一次训练自动下载"行为的核心。脚本分三步:
    1. 从 Trax Retail 官方 S3 地址下载 SKU110K_fixed.tar.gz 并解压,将 SKU110K_fixed 重命名为 SKU-110K
    2. 读取原始的 annotations/annotations_{train,val,test}.csv(无表头,列为 image, x1, y1, x2, y2, class, image_width, image_height,坐标为像素级 xyxy),用 polars 高效解析;
    3. 为每张图像生成 YOLO 格式标签文件:类号固定写 0,像素坐标除以图像宽高归一化后再经 xyxy2xywh 转为归一化 xywh,每行以 5 位小数写入 labels/<image名>.txt;同时把每个子集的去重图像列表写成对应的 .txt 清单。

xyxy2xywh 工具函数定义在 ultralytics/utils/ops.py,是 YOLO 标签格式的通用坐标转换入口。

五、自动下载机制:源码层面的调用链

文档提示"SKU-110K 在第一次训练时自动下载,需要约 13.6 GB 磁盘空间,且标注转换可能需要几分钟"。这个行为的实现入口在 check_det_datasetultralytics/data/utils.py),调用链可以概括为:

  1. 解析 YAMLcheck_det_dataset(dataset, autodownload=True) 被训练流程调用后,先加载 YAML,校验 train/val 键存在、namesnc 存在、类型合法,并把 train/val/test 路径解析为绝对路径;
  2. 判定是否需要下载:解析后的 val(或指定 split)路径若不存在,且 YAML 中含有 download 字段、autodownload 为真,则触发下载;
  3. 执行内嵌脚本download 字段以 http 开头且以 .zip 结尾时按 URL 直接下载;以 bash 开头时执行 shell 脚本;否则——SKU-110K 正属于这种情况——以 exec(s, {"yaml": data}) 执行内嵌 Python 脚本,脚本内可以直接引用 yaml 字典(这就是上面脚本能使用 yaml["path"] 的原因)。
# ultralytics/data/utils.py 中的核心分支(节选)
if s.startswith("http") and s.endswith(".zip"):  # URL
    safe_download(url=s, dir=DATASETS_DIR, delete=True)
elif s.startswith("bash "):  # bash script
    subprocess.run(s.split(), check=True)
else:  # python script
    exec(s, {"yaml": data})

也就是说,你在训练命令中只需写 data="SKU-110K.yaml",框架会自动完成"下载 13.6 GB 压缩包 → 解压改名 → 逐张图像把 CSV 像素标注转换为 YOLO 标签"的全过程,无需任何手工步骤。下载目录默认是 DATASETS_DIRdatasets/),若空间不足可通过设置文件调整该路径。

六、训练 YOLO26 的完整用法

训练文档 的参数体系下,SKU-110K 的训练示例如下(图像尺寸 640、100 个 epoch,从预训练权重开始):

Python API

from ultralytics import YOLO

# Load a model
model = YOLO("yolo26n.pt")  # load a pretrained model (recommended for training)

# Train the model
results = model.train(data="SKU-110K.yaml", epochs=100, imgsz=640)

CLI

# Start training from a pretrained *.pt model
yolo detect train data=SKU-110K.yaml model=yolo26n.pt epochs=100 imgsz=640

几个实用要点:

  • 首次运行耗时构成:约 13.6 GB 下载 + 170 万级标注的 CSV→YOLO 转换,文档明确提示"可能需要几分钟",属于预期行为而非卡死;
  • 磁盘与网络:训练前请确认 datasets/ 所在分区有 ≥ 13.6 GB 空闲空间以及到 Trax S3 源点的稳定网络;
  • 参数查阅epochsimgsz 之外的完整训练参数(批大小、增强开关、早停等)参见 Training 文档训练技巧指南
  • 评测:训练完成后可用 data="SKU-110K.yaml", split="test" 在 2,936 张测试图上做最终评测,验证流程见 Validation 文档

对于更小的入门需求,检测数据集总览 还列有 coco8、coco128 等体量更小的数据集可用于快速验证管线。

七、样本数据与标注形态

SKU-110K 的图像真实还原了商店货架:数十个外观几乎相同的产品并排陈列,同一张图中既有大目标也有大量小目标。文档给出的示例说明:图像以密集货架为背景,所有商品均用边界框标注在唯一的 object 类下。

从标注转换脚本可以进一步推断其标注形态的细节:原始标注 CSV 中每行含像素坐标 (x1, y1, x2, y2) 及图像宽高,转换后每张图像对应一个 labels/<image名>.txt,每行格式为 cls cx cy w h(归一化、5 位小数)。高物体密度意味着单张图像平均写出约 147 行标注,这也是转换阶段耗时较长的直接原因。这种标注形态对检测器的要求集中在两点:密集小目标不遗漏、相邻相似目标不合并。

八、引用与致谢

在研究或使用该数据集时,建议引用原始论文:

@inproceedings{goldman2019dense,
  author    = {Eran Goldman and Roei Herzig and Aviv Eisenschtat and Jacob Goldberger and Tal Hassner},
  title     = {Precise Detection in Densely Packed Scenes},
  booktitle = {Proc. Conf. Comput. Vision Pattern Recognition (CVPR)},
  year      = {2019}
}

文档同时致谢了 Eran Goldman 等人为计算机视觉研究社区创建并维护 SKU-110K 数据集。

九、常见问题(FAQ)

SKU-110K 有 11 万个类别吗? 没有。它是单类数据集:所有商品都标注为 object 类(names: {0: object})。"110K" 指的是图像中出现的唯一 SKU 数量超过 11 万,而非检测类别数。

数据集具体有多少图像和类别? 11,743 张图像(8,219 训练 / 588 验证 / 2,936 测试),1 个检测类别 object。详见上文"数据集划分"一节及 SKU-110K.yaml

下载体积多大?需要手动下载吗? 约 13.6 GB,无需手动下载——首次以 data="SKU-110K.yaml" 训练时,check_det_dataset 会自动触发 YAML 中内嵌的下载与标注转换脚本。

如何用它训练 YOLO 模型? 直接按第六节的 Python 或 CLI 示例执行即可:加载 yolo26n.pt 预训练权重,data="SKU-110K.yaml"epochs=100imgsz=640,首次运行会自动完成数据准备。

小结

SKU-110K 在 Ultralytics 中的定位非常清晰:一个开箱即用的单类、高密度、大规模零售检测基准。它的 YAML 配置展示了 Ultralytics 数据集描述文件"声明路径 + 内嵌下载/转换脚本"的完整形态——path/train/val/test 声明数据布局,names 声明类别,download 脚本负责从 CSV 像素标注一键生成 YOLO 格式标签。理解 check_det_dataset 中的自动下载分支后,你就能把同样的机制迁移到自己的工作数据集 YAML 中,实现"一条训练命令完成数据准备 + 模型训练"。

登录后查看全文
热门项目推荐
相关项目推荐