Dataset Consumption¶
Warning
Pre-implementation. This page describes proposed contracts. Class signatures, parameter types, config field names, and behavior are subject to change before code lands. Once implementation exists, content here will be regenerated from docstrings or sourced from running tests.
Dataset consumption starts after records have been written. Training code needs to choose records from a store, batch them for a task, and hand tensors to a training framework such as PyTorch without rerunning generation.
The six producer layers (Emitters, Channels, Scenes, Labels, Annotations, Storage) describe how Record objects are produced and stored. Once stored, downstream training and evaluation pipelines consume them through three additional abstractions. These are not a seventh producer layer. They are a consumer-side toolkit that wraps the storage layer’s read API.
Place In The System¶
Producers run during dataset generation; consumers run during model training and evaluation. The two sides only communicate through stored Record objects: a producer writes a record, the consumer reads it. There is no shared in-process state.
Phase 1 is the synthetic radio-frequency (RF) generation pass described by the six producer layers. Phase 2 is the optional annotation pass that appends text metadata, such as captions or scene summaries, after in-phase/quadrature (IQ) samples and labels already exist.
Phase |
Side |
What runs |
|---|---|---|
Phase 1 |
Producer |
Generate records with the six producer layers; write via StoreHandle. |
Phase 2 |
Producer |
Annotator appends text fields to existing records. |
Training |
Consumer |
BaseSampler selects records, BaseCollator shapes batches, RfgenTorchDataset adapts to PyTorch. |
Data Flow¶
BaseSampler ──► sample_id iteration order
│
▼
StoreHandle.read(sample_id) ──► Record
│
▼
BaseCollator ──► batched tensors shaped for the task
│
▼
RfgenTorchDataset ──► torch.utils.data.DataLoader compatible
sample_id is the stable record identifier stored in the dataset index. The index is the store’s list of available records, usually represented by the storage backend’s metadata or manifest. The ID may be content-derived or supplied by the storage backend, but consumer code treats it as the key passed to StoreHandle when reading a record.
Abstract Base Classes¶
These abstract base classes (ABCs) are proposed extension contracts for the consumer side.
Concept |
ABC |
Module |
|---|---|---|
Read order |
|
|
Batch shape |
|
|
Framework adapter |
|
BaseSampler controls which sample_id values are yielded and in what order. Samplers read metadata from stored records and yield IDs in an order chosen for the training objective. Implementations may shuffle, stratify by class, balance by signal-to-noise ratio (SNR) bucket, or use curriculum ordering, where easier examples appear before harder examples.
BaseCollator turns a list of Record objects into batched tensors shaped for a specific task. For example, detection returns IQ tensors plus time-frequency bounding boxes around emitters, while classification returns IQ tensors plus class labels. Different downstream tasks need different batch shapes, so the collator is task-specific while the records are not.
RfgenTorchDataset is the optional PyTorch adapter behind the rfgen[torch] extra. It bridges BaseSampler and BaseCollator to torch.utils.data.DataLoader. When a collator is configured, RfgenTorchDataset.__iter__ already yields collated batches; use DataLoader(batch_size=None) so PyTorch does not add an unwanted outer batch dimension. JAX, TensorFlow, or framework-specific adapters can be added without touching the producer layers.
Boundaries¶
StoreHandle does not inherit from any consumer-side ABC. The store is producer-side; only the adapter layer touches consumer types.
Producers do not know about samplers or collators. A scene composer writes records; whether those records are later consumed in shuffled order or stratified order is a consumer choice.
Collators are task-specific; records are not. A single Record may feed both a detection task (bboxes) and a classification task (per-emitter labels) via different collators.
Minimal Example¶
from rfgen.dataset.collators import DetectionCollator
from rfgen.dataset.samplers import RandomSampler
from rfgen.dataset import RfgenTorchDataset
from rfgen.storage import open_store
from torch.utils.data import DataLoader
# This assumes the quickstart or local-dataset how-to has written
# detection records to ./out/local-smoke.
with open_store("./out/local-smoke") as store:
dataset = RfgenTorchDataset(
store=store,
sampler=RandomSampler(seed=1337),
collator=DetectionCollator(),
)
# batch_size=None keeps the DetectionCollator's batch shape unchanged.
loader = DataLoader(dataset, batch_size=None, num_workers=4)
for batch in loader:
iq = batch["iq"]
boxes = batch["bboxes"]
...
RandomSampler gives a deterministic random order over stored sample_id values. DetectionCollator returns detection batches in rfgen terms: IQ tensors, time-frequency bounding boxes, class IDs, and emitter counts. Exact tensor shapes and units belong in the dataset API reference.
See Also¶
Storage: the producer-side ABC that consumer-side tools wrap.
Architecture: how the six producer layers fit together.
How-To / Generate a Local Dataset: proposed commands that write a local store for inspection and training experiments.
Reference / API / Dataset: sampler and collator contracts, including RandomSampler and DetectionCollator.
Reference / API / Dataset: exact signatures for RfgenTorchDataset.
Background / Design Decisions § Tensor library for why
torch.Tensoris canonical on the consumer side and where NumPy enters at the storage boundary.