| """Stacking windows into batches. |
| |
| The only thing this does that ``torch``'s default collate would not is keep the |
| lattice out of the batch. A lattice is static metadata; collating it would |
| allocate an identical copy per sample per step for no benefit, and worse, would |
| invite treating it as per-sample data when it is a property of the whole |
| dataset. |
| """ |
|
|
| from __future__ import annotations |
|
|
| from collections.abc import Sequence |
|
|
| import torch |
|
|
| from torch_dimensions.data.source import Sample |
|
|
| __all__ = ["Batch", "collate_lattice"] |
|
|
|
|
| class Batch(dict): |
| """A stacked batch. ``batch.x`` is ``(B, T, *shape, F)``.""" |
|
|
| |
| |
| def __getattr__(self, name: str): |
| try: |
| return self[name] |
| except KeyError: |
| raise AttributeError(name) from None |
|
|
|
|
| def collate_lattice(samples: Sequence[Sample]) -> Batch: |
| """Stack samples along a new leading batch dimension. |
| |
| Windows of differing length are rejected rather than padded: a ragged |
| time axis in an N-D batch is far more likely to be a windowing bug than an |
| intention, and padding it silently would hide that. |
| """ |
| if not samples: |
| raise ValueError("cannot collate an empty list of samples") |
|
|
| lengths = {s["x"].shape[0] for s in samples} |
| if len(lengths) != 1: |
| raise ValueError(f"samples have differing input lengths {sorted(lengths)}") |
|
|
| |
| |
| |
| |
| with_y = sum("y" in s for s in samples) |
| if 0 < with_y < len(samples): |
| raise ValueError( |
| f"{with_y} of {len(samples)} samples have a target and the rest do not; " |
| "mixed-horizon samples cannot share a batch" |
| ) |
|
|
| batch = Batch(x=torch.stack([s["x"] for s in samples])) |
| if with_y: |
| y_lengths = {s["y"].shape[0] for s in samples} |
| if len(y_lengths) != 1: |
| raise ValueError(f"samples have differing target lengths {sorted(y_lengths)}") |
| batch["y"] = torch.stack([s["y"] for s in samples]) |
| batch["windows"] = tuple(s["window"] for s in samples) |
| return batch |
|
|