zea.DataloaderΒΆ
- class zea.Dataloader(file_paths, key, *, batch_size=16, n_frames=None, shuffle=True, return_metadata=None, seed=None, limit_n_examples=None, limit_n_frames=None, offset_n_frames=0, drop_remainder=False, image_size=None, resize_type=None, resize_axes=None, resize_kwargs=None, image_range=None, normalization_range=None, clip_image_range=False, assert_image_range=True, dtype=None, dataset_repetitions=None, cache=False, additional_axes_iter=None, sort_files=True, overlapping_blocks=False, augmentation=None, on_incomplete_blocks='error', on_missing_metadata='error', frame_index_stride=1, frame_axis=-1, validate=True, revision=None, lazy=True, shard_index=None, num_shards=1, num_threads=16, prefetch_buffer_size=500, reshuffle_each_epoch=True, convert_to_tensor=True, axis_selections=None, file_filter=None, **kwargs)[source]ΒΆ
Bases:
objectHigh-performance HDF5 dataloader built on Grain.
grain threads (N) β h5py (thread-local handles) β numpy -> cpu tensor β user
The entire pipeline runs using numpy, and the resizing is done on the selected backend, all on cpu.
Does the following in order to load a dataset:
Find all .hdf5 files in the director(ies)
Load the data from each file using the specified key
Apply the following transformations in order (if specified):
offset_n_frames / axis_selections (applied at HDF5 read time)
limit_n_frames
limit_n_examples
shuffle
shard
add channel dim
clip image range
assert image range
resize
repeat
batch
cast to
dtype(if specified)normalize
augmentation
convert_to_tensor
- Parameters:
file_paths (
Union[List[str],str]) β Path(s) to directory(ies) and/or HDF5 file(s).key (
str) β HDF5 dataset key.batch_size (
int|None) β Batch size. Set toNoneto disable batching. Default is16. Stacking two or more samples (incl. metadata) requires them to have the same shape. This is checked when the loader is built. Note thatimage_sizecan resolve differing sample shapes; for the rest, usebatch_size=None(or1, which stacks nothing) and batch it yourself.n_frames (
int|None) β Number of consecutive frames per sample, placed onframe_axis. Default isNone, which loads single frames without a frame axis, so a sample keeps the fileβs own layout for one frame. Set an int to group consecutive frames into blocks β includingn_frames=1, which gives a length-1 frame axis. Frames are read from whichever axis the zea file spec namesn_framesforkey.shuffle (
bool) β Shuffle dataset each epoch. Default isTrue.return_metadata (
bool|str|Sequence[str] |None) βReturn a
(sample, metadata)tuple instead of a bare sample.False(default) returns arrays only.Truereturns just the file identity. An iterable of dotted paths additionally loads those fields from the file, e.g.["scan.sampling_frequency", "metadata.subject"]; a path pointing at a group loads everything below it. Paths use the same syntax asfile_filter. The returned dict mirrorsFileSpec, with the loaderβs own provenance under a"file"key:{ "scan": {"sampling_frequency": 40e6}, "metadata": {"subject": {"age": 61}}, "file": {"fullpath": ..., "filename": ..., "indices": ...}, }
Fields whose leading dimension is
n_framesin the spec are sliced to the sampleβs frames so they stay aligned with the returned images, and fields sharing a dimension with anaxis_selectionsentry are narrowed the same way. During construction, the loader checks that all files can supply the requested paths and that they have the same shapes, raisingKeyErrororValueErrornaming the offending files. They can be dropped withon_missing_metadata="skip"orfile_filter. Usebatch_size=Nonefor metadata that genuinely varies in shape between files.seed (
int|None) β Random seed used for dataloader (e.g. shuffling). Default isNone. IfNonea random seed is generated.limit_n_examples (
int|None) β Cap the total number of examples (== item before batching) the loader yields, across all files (useful for debugging). Default isNone(no limit). Note that this happens before shuffle.limit_n_frames (
int|None) β Maximum number of frames to load per file, counted fromoffset_n_frames. Default isNone(no limit).offset_n_frames (
int) β Frame index to start iteration from within each file. Combined withlimit_n_framesthis selects the half-open range[offset_n_frames, offset_n_frames + limit_n_frames). Default is0.drop_remainder (
bool) β Drop the final incomplete batch. Default isFalse.image_size (
tuple|None) β Target(height, width). Default isNone(no resizing). Setting it is what lets files of differing image size be batched together, since they arrive at the batch op already sharing a shape.resize_type (
str|None) β Resize strategy. One of"resize","center_crop","random_crop"or"crop_or_pad". Default isNone, which resolves to"resize"when image_size is set.resize_axes (
tuple|None) β Axes to resize along, must have length 2 (height, width). Only needed when data has more than(h, w, c)dimensions. Axes are interpreted after frame-axis insertion/reordering. Default isNone.resize_kwargs (
dict|None) β Extra keyword arguments passed toResizer. Default isNone.image_range (
tuple|None) β Source value range of images, e.g.(-60, 0). Used for clipping/asserting/normalization. Default isNone.normalization_range (
tuple|None) β Target value range, e.g.(0, 1). If set,image_rangemust also be set. Default isNone.clip_image_range (
bool) β Clip values toimage_rangebefore normalization. Default isFalse.assert_image_range (
bool) β Assert values stay withinimage_range. Default isTrue.dtype (
str|dtype|None) β Cast samples to this dtype (e.g."float32",np.float16) after batching and before normalization. Must be floating point whenevernormalization_rangeis set. Default isNone, which keeps the dtype the files hold β except that files holding integers are promoted tofloat32, since normalizing has no integer-valued result.dataset_repetitions (
int|None) β Repeat dataset this many times. Repetition happens after sharding. Default isNone(no repetition).cache (
bool) β Cache loaded samples in RAM. Default isFalse. Note that withoverlapping_blocks=True, the same frame can be part of multiple samples, so caching will consume more memory.additional_axes_iter (
tuple|None) β Additional axes to iterate over, on top of the frame axis. Each becomes an integer index, so those axes are dropped from the sample. Default isNone.sort_files (
bool) β Sort files numerically before indexing. Default isTrue.overlapping_blocks (
bool) β IfTrue, frame blocks overlap byn_frames - 1. Has no effect unlessn_frames > 1. Default isFalse.on_incomplete_blocks (
str) β What to do with files holding too few frames to fill one block ofn_frames(spaced byframe_index_stride)."error"(default) refuses to build the loader and names the offending files;"skip"drops them from the dataset.on_missing_metadata (
str) β What to do with files that cannot supply a path requested throughreturn_metadata."error"(default) refuses to build the loader and names the offending files;"skip"drops them from the dataset. Default is"error".augmentation (
Callable|None) β Callable applied to each batch after normalization. Default isNone.frame_index_stride (
int) β Step between selected frames, for example,2takes every other frame,3every third. Samples still follow one another without gaps β withn_frames=2, frame_index_stride=2a file yields frames(0, 2), then(3, 5). Default is1.frame_axis (
int) β The frames are put in this axis. Only applies whenn_framesis set. Default is-1: an image batch comes out as(batch, height, width, n_frames), the channels-last layoutResizerand keras expect. That is why resizing without explicitresize_axesrequiresframe_axis=-1. Forraw_datait makes sense to setframe_axis=0to keep frames in front.validate (
bool) β Validate discovered files against the zea format, raising if any file is not a valid zea file. Default isTrue. The verdict is cached, so only the first run over a given dataset opens every file.revision (
str|None) β HuggingFace revision (branch, tag, or commit hash) forhf://paths. Defaults toNone(uses the default branch, typically"main").lazy (
bool) β Streamhf://files over HTTP instead of downloading them up front. Default isTrue: a read fetches only the chunks it touches, so reading a slice of a few large files costs a fraction of them, and the bytes land in the on-disk chunk cache (zea.data.chunk_cache) for the next read. PassFalseto download every file in full before the pipeline is built, which is the better trade for training: shuffled access over a dataset larger than that cache re-fetches it every epoch, and a bulk download is both faster per byte and resumable. Ignored for local paths.shard_index (
int|None) β Shard index to select whennum_shards > 1. Must satisfy0 <= shard_index < num_shards.num_shards (
int) β Total number of shards for distributed loading. Sharding happens before downstream transforms. Default is1.num_threads (
int) β Number of Grain read threads (0means main thread only). Default is16.prefetch_buffer_size (
int) β How many elements the Grain buffer holds, per Python process (not per thread). An element here is whatever this loader yields, so with abatch_sizeit counts batches:prefetch_buffer_size=500, batch_size=16keeps up to 8000 examples in RAM. Useful when reading from a distributed file system. Default is500. Set to0to disable prefetching and read sequentially instead.reshuffle_each_epoch (
bool) β Whether to reshuffle the dataset after each epoch. Default isTrue. For evaluation it might be useful to set this toFalse. Or when you want to use a persistent iterator between epochs, usingdataset_repetitionsto specify the number of epochs.convert_to_tensor (
bool) β Whether to convert the data to a tensor (on cpu). Default isTrue.axis_selections (
dict|None) β Map of{axis: indices}applied at HDF5 read time to pre-filter non-frame axes. For example{1: [0, 2, 5]}loads only those indices along axis 1, avoiding reading unused data chunks from disk. This can save time and memory.return_metadatafields carrying the selected dimension are cut to match, wherever that dimension sits in their own layout: selecting transmits ondata/raw_dataalso selects them inscan.t0_delays. Default isNone.file_filter (
Callable[[File],bool] |dict|None) β Keep only files whose content matches a predicate, discarding the rest before any frames are indexed. Either a callableFile -> bool(a file is kept when it returnsTrue), or a declarative dotted-path dict mapping a path on theFileto a condition: theEXISTS()helper (field must be present), a plain value (equality), or a callable on the resolved value. All dict entries are ANDed. Files whose predicate raises (e.g. they have nometadatagroup) are excluded. Default isNone(no filtering).
Example
loader = Dataloader( file_paths="/data/camus", key="data/image/values", batch_size=32, image_range=(-60, 0), normalization_range=(0, 1), image_size=(256, 256), ) for batch in loader: ... # batch.shape == (32, 256, 256, 1)
- Filtering examples:
from zea import Dataloader, EXISTS # callable: keep only files that record a subject fat percentage loader = Dataloader( file_paths="filter-demo-dataset", key="data/image/values", file_filter=lambda f: f.metadata.subject is not None and f.metadata.subject.fat_percentage is not None, ) # metadata: load selected fields alongside each sample loader = Dataloader( file_paths="filter-demo-dataset", key="data/image/values", batch_size=None, return_metadata=["scan.center_frequency", "metadata.subject"], ) sample, meta = next(iter(loader)) assert meta["scan"]["center_frequency"] in (5e6, 9e6) assert meta["metadata"]["subject"]["sex"] in ("f", "m") assert meta["file"]["filename"] in ("a", "b") # dict: presence + equality + a value-level predicate (all ANDed) loader = Dataloader( file_paths="filter-demo-dataset", key="data/image/values", file_filter={ "metadata.subject.fat_percentage": EXISTS, "metadata.subject.sex": "f", "scan.center_frequency": lambda v: 4e6 <= v <= 6e6, }, )
- property datasetΒΆ
The underlying
grain.MapDataset.
- property sample_shapes: dict[tuple, list[str]]ΒΆ
Each shape this loader yields, mapped to a few files that produce it.
One entry for a well-formed dataset; more than one means the files disagree and only
batch_size=Nonecan iterate them.
- property shapeΒΆ
Output shape of one batch (or sample if unbatched).
With
drop_remainder=Falsethe final batch is shorter than the rest whenever the sample count is not a multiple ofbatch_size; the batch axis is reported asNonein that case, since no single size describes every batch.- Raises:
ValueError β If the loader yields more than one shape, which only an unbatched loader can do β there is no single shape to report. Inspect
sample_shapesfor the shapes it does yield.