About yolo-datasets
A practical reference skill for preparing, converting, splitting, and validating Ultralytics YOLO datasets before training. It is for developers and ML practitioners working with YOLO task formats, local code, or Platform datasets.
Key features
- 01Platform dataset preparation and versioning
- 02Image-label mirror layout guidance
- 03COCO and DOTA conversion utilities
- 04Dataset splitting and leakage checks
- 05Validation workflow before training
Use cases
- 01Diagnosing missing or misplaced labels
- 02Preparing datasets for YOLO training
- 03Converting COCO or DOTA annotations
- 04Checking split leakage across video frames
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ ultralytics/ skills --skill yolo-datasetsAfter installing, type/yolo-datasetsin Claude Code to confirm it loaded.
Bundled filesagents/openai.yamllabel-formats.md
Details
From the project READMEUltralytics YOLO datasets
The #1 cause of silent training failure is a malformed dataset — validate before training.
Fastest route: prepare data in Platform
- Open Platform, create a dataset under Annotate, and choose its task.
- Upload images, videos, ZIP/TAR archives, or NDJSON. Existing YOLO labels and COCO JSON can be imported; cloud-storage integrations can keep supported data in place.
- Open an image in the fullscreen editor. Use manual tools for detect, segment, semantic, classify, pose, or OBB. Switch to Smart mode to label with SAM (detect, segment, semantic, OBB) or a compatible official/custom YOLO model (those tasks plus pose).
- Review the Classes, Charts, and Errors tabs, fix the split, and create a numbered dataset version before important runs.
Platform datasets cover all seven YOLO tasks. Depth targets are imported rather than drawn in the editor. See Platform Data and the Annotation Editor.
To train on the same dataset from local code, create an API key under Settings > API Keys, set ULTRALYTICS_API_KEY, and pass the dataset's ul:// URI as data:
yolo train model=yolo26n.pt data=ul://username/datasets/dataset-slug epochs=100
Export NDJSON when you need a portable snapshot instead of live Platform access.
The images → labels mirror rule
Ultralytics finds a label file by replacing the last /images/ path segment with /labels/ and the image extension with .txt:
dataset/
├── data.yaml
├── images/train/ img001.jpg ... ├── images/val/ ...
└── labels/train/ img001.txt ... └── labels/val/ ...
- Labels next to images in an
images/dir, or in a dir not namedlabels, are not found → training stops withNo labels found; if only some are missing, those images train as backgrounds. - Filenames must match stems exactly (case-sensitive on Linux).
- An image with no/empty label file trains as a background image. A few percent of true backgrounds reduce false positives; accidentally missing labels destroy recall.
data.yaml anatomy
path: /abs/dataset/root # absolute, or omit to use this yaml's folder; a relative value (even `.`) resolves from the CWD (datasets_dir if missing there)
train: images/train # dir, .txt file of image paths, or list of dirs
val: images/val
test: images/test # optional
names: # 0-based, contiguous indices
0: person
1: helmet
# pose only:
kpt_shape: [17, 3] # [num_keypoints, dims]; dims 2 (x,y) or 3 (x,y,visibility)
flip_idx: [0, 2, 1, ...] # L/R keypoint swap map — without it, flip augs are auto-disabled
# semantic only (optional — polygon .txt labels in labels/ also work):
masks_dir: masks # per-pixel PNG mask images
# depth only (replace names above; pair depth/{train,val}/*.png or float .npy maps):
# nc: 1
# names: {0: depth}
# depth_scale: 1000 # PNG units per meter; default millimeters
- Classification datasets use no yaml: folder structure is the label (
dataset/train/<class>/*.jpg,dataset/val/<class>/*.jpg); train withdata=path/to/dataset. - Per-task label line formats and their gotchas: read
label-formats.md(this folder) whenever writing or debugging label files.
Converting from other formats — use built-ins first
from ultralytics.data.converter import convert_coco
convert_coco(labels_dir="coco/annotations/", use_segments=True, cls91to80=False) # → segment
convert_coco(labels_dir="coco/annotations/", use_keypoints=True, cls91to80=False) # → pose
Omit use_segments for detect labels. cls91to80=False keeps custom category IDs (as category_id - 1); leave the default True only for the official COCO 91-class IDs.
Also in ultralytics.data.converter: convert_dota_to_yolo_obb(dota_root_path) (DOTA → OBB), convert_segment_masks_to_yolo_seg(masks_dir, output_dir, classes) (index PNGs → polygons), yolo_bbox2segment(im_dir) (upgrade detect labels to segment via SAM), convert_to_multispectral(path, n_channels).
Auto-label a raw image folder (detector proposes boxes, SAM refines masks):
from ultralytics.data.annotator import auto_annotate
auto_annotate(
data="dataset/images/train", det_model="yolo26x.pt", sam_model="sam_b.pt", output_dir="dataset/labels/train"
)
For VOC XML/CSV there is no converter — write a small script emitting the per-task line format (normalize coords, center-based boxes).
Splitting
from ultralytics.data.split import autosplit
autosplit(path="dataset/images", weights=(0.9, 0.1, 0.0)) # writes autosplit_*.txt lists
Point train:/val: at the generated .txt files. Keep frames from the same video/scene in ONE split — per-image random splits of video frames leak near-duplicates into val and inflate mAP. For classify: split_classify_dataset(source_dir, 0.8).
Validate before training (use the task-relevant steps in order)
-
YAML/path check (non-classification) — validates required fields, resolves configured paths, checks the requested split (default
val), and may auto-download a known dataset. It does not count or parse individual images and targets:from ultralytics.data.utils import check_det_dataset check_det_dataset("data.yaml") # detect/segment/pose/obb/semantic/depth -
Detection-only visual spot check — this helper accepts five-column
class cx cy w hrows; wrong normalization or swapped axes become visible:from ultralytics.data.utils import visualize_image_annotations visualize_image_annotations( "images/train/img001.jpg", "labels/train/img001.txt", label_map={0: "person", 1: "helmet"}, )Do not use this helper for segment, pose, OBB, semantic, depth, or classify targets; use their task-aware trainer plots instead.
-
Task-loader smoke test — run one epoch with matching task/model/data; this builds the real dataset and produces task-aware training plots (detection example):
yolo detect train data=data.yaml model=yolo26n.pt epochs=1 fraction=0.1 # inspect runs/detect/train/train_batch0.jpg — boxes must sit on objects -
Distribution sanity — check task-appropriate class/target balance and split leakage. For box tasks, also inspect very small boxes at train
imgszand the background-image share.
Known-good tiny datasets for pipeline smoke tests (auto-download): coco8.yaml, coco8-seg.yaml, coco8-pose.yaml, dota8.yaml, cityscapes8.yaml, depth8.yaml, imagenet10.
Related pages
label-formats.md— exact per-task label line formats + symptom→cause table. Read when writing labels, converting formats, or any label-related error.
If the installed version rejects an argument or format here, trust its error message and yolo checks over this file.