split: Assign Train/Val/Test Splits¶
The split command assigns a generated dataset's images and Pascal VOC annotations to
leakage-safe train/val/test splits, grouped by dive (video_sequence_name) so frames from the
same dive never end up split across train/val/test -- otherwise near-duplicate frames from one
dive would leak across the split, inflating validation/test scores.
Run this after any manual QA/QC on generate's output (filter, dedup, gallery,
fix-dimensions, etc.) and before converting to a training format (convert voc-yolo,
remap yolo) -- it's the last step before handing a dataset to a training framework:
Splitting only operates on whatever image/XML pairs are still present in DATASET_DIR at the
time it runs, so it's safe to run after QA/QC tools have deleted or modified files.
Usage¶
Required Parameters¶
DATASET_DIR: Dataset directory to split (post-QA/QC), expectingJPEGImages/andAnnotations/subfolders -- the same layoutgeneratewritesOUT_DATASET_DIR: Directory to write per-split dataset subdirectories to (eachOUT_DATASET_DIR/<split>/is itself aJPEGImages//Annotations/dataset dir)
Options¶
--manifest-path: Path to thegeneraterun'smanifest.json-- this is where dive (video_sequence_name) membership per image comes from (default:DATASET_DIR/manifest.json)--ratio NAME=VALUE: Split ratio, repeatable (defaulttrain=0.8 val=0.1 test=0.1)--seed: Random seed for split assignment (default:0)--split-manifest-path: Path to write the split manifest to (default:OUT_DATASET_DIR/split_manifest.json)--verbose, -v: Display additional debugging information
How It Works¶
- Loads the
generatemanifest and builds a filename → dive lookup from itsresults.images - Matches image/XML pairs currently present on disk (under
DATASET_DIR/JPEGImages/andDATASET_DIR/Annotations/) by filename stem, skipping (with a warning) any orphan -- an image with no matching XML annotation, or vice versa - Groups matched pairs into atomic assignment units: pairs sharing a dive are grouped together so a whole dive is assigned as one unit; pairs with no dive -- including any not present in the manifest at all, e.g. images added manually after the pull -- are each their own unit
- Assigns units to splits via a seeded greedy balancing pass, converging close to the requested ratios despite uneven dive sizes
- Symlinks (not copies) each pair's image and XML into
OUT_DATASET_DIR/<split>/JPEGImages/andOUT_DATASET_DIR/<split>/Annotations/-- ageneratepull can be hundreds of thousands of images, so symlinking avoids doubling disk usage. If you need real files (e.g. to hand a directory to a tool that doesn't follow symlinks), copy through the symlinks yourself afterward. - Writes
split_manifest.json, recording the ratios/seed used and, per split, the image/ localization counts and constituent dive names
Examples¶
Split with the default 80/10/10 ratios:
Split 90/10 train/val only, with a fixed seed:
Why symlinks depend on the source directory
Since OUT_DATASET_DIR/<split>/ contain symlinks back to DATASET_DIR, don't move or
delete the QA'd source directory after splitting without also updating (or re-running) the
split.