Repository navigation
Releases
A release is the dataset compiled into one file for training: a snapshot you can name, pin in a config, share and reproduce. This page covers what a release is, how to build one for a purpose, what its id does and does not promise, and how to use it.
vidlabel build my_dataset (or ds.build()):
- validates the dataset and refuses to continue if there are errors;
- merges every video's annotation table into one, sorted by (
video_id,start_frame,annotation_id); - leaves out
rejectedrows unless you ask; - writes
compiled/<release_id>/annotations.parquet, a snapshotvocab.json, andrelease.json(rows, filters, spec version, time); - points
compiled/LATESTat it.
compiled/
LATEST the newest release id
r3fa91c0b2d44/
annotations.parquet
vocab.json the labels as they were at build time
release.json
Releases are small compared with the videos they describe, and old ones stay until you delete them.
All filters are optional and combine.
argument (ds.build(...)) |
meaning | default |
|---|---|---|
statuses |
which review states to include | ("unreviewed", "approved") |
origins |
only rows from these origins, e.g. ["human"]
|
all |
kinds |
only "marker", "box", "mask" rows |
all |
video_ids |
only these videos (a train/validation split is two releases) | all |
view_ids |
only rows tagged with these views; None inside the list means whole-frame rows |
all |
Command line: vidlabel build my_dataset and --include-rejected. Everything else is Python.
Examples:
ds.build(statuses=["approved"]) # only work a person confirmed
ds.build(origins=["human"]) # no model output at all
ds.build(video_ids=train_videos) # a training split
ds.build(view_ids=[None]) # whole-frame rows only, leaving out view copiesA release that includes rejected rows (--include-rejected, or statuses containing "rejected") is meant for inspection: it is
written, but LATEST is not moved to it. Refer to it by its id.
The release id is "r" plus the first 12 hexadecimal characters of the SHA-256 of annotations.parquet.
- Building the same dataset folder twice with no changes gives the same id.
- Changing any annotation, or any filter that changes which rows are included, gives a different id.
- The id is a hash of the file's bytes. Those bytes include each row's random
annotation_idand the Parquet writer's version. So re-creating a dataset from a script (which draws new random ids) gives a different id for the same content, and a very different PyArrow version could in principle change the bytes for the same rows.
What this means in practice: share the dataset folder, including compiled/. Anyone who has the folder has the release with the
id you pinned, and FrameSamples(release="r3fa91c0b2d44") reads exactly those rows. Do not expect to regenerate an id by re-running a
converter. Content-derived ids were considered and are not planned; see design decisions.
Class indices (the labels in a sample) are positions in the vocabulary. A release carries a snapshot of vocab.json as it was when
built, so adding or reordering labels in the dataset later never changes the class indices of a pinned release. Releases made by a
version that did not save the snapshot fall back to the live vocabulary.
from vidlabel import Dataset, VideoMetadata, FrameSamples
from vidlabel.build import Compiled
ds = Dataset.create("demo")
ds.add_video(VideoMetadata(video_id="v", frame_count=100, fps={"num": 25, "den": 1}, width=64, height=48))
ds.add_labels(["thing"])
ds.add_annotations([{"kind": "box", "label": "thing", "start_frame": f, "box": (5, 5, 30, 30), "origin": "human"}
for f in range(0, 100, 5)], "v")
release, path = ds.build()
samples = FrameSamples(ds, release=release.release_id) # pinned: the same rows and class indices every time
print(len(samples), samples.describe()["release_id"]) # log describe() next to a training run
compiled = Compiled(path) # read the release table directly
print(compiled.read(columns=["video_id", "start_frame", "label"]).num_rows)
print(compiled.clip("v", 10, 30).num_rows) # rows overlapping frames 10..30, reading only needed row groupsFrameSamples(release="latest") follows LATEST; release=None reads the live, unreviewed-or-approved annotations and can change
between runs, which is convenient while labelling and wrong for a result you want to reproduce.
- Label and review in the dataset.
-
buildwith the filters for the experiment; write the id in your config and in the experiment log (samples.describe()givesrelease_id, view, kinds, class names). - Keep the
compiled/<id>/folder with the dataset when you share or archive it. - When labels change, build again; the new id marks the new data, and the old release still reproduces the old run.
Source: docs/releases.md
vidlabel 0.6.0 · pages are generated from the repository's docs/ folder; to change one, edit docs/ and run python docs/build_wiki.py.
Start here
Tutorials
Guides
Reference
Background
- Architecture
- Design decisions
- Performance
- Compatibility and versioning
- Limitations and roadmap
- Security
- Web interface design
Project