Download scripts/data_loader.py from OneScience-Group/SEEDS: direct link, hf CLI and curl.
- Browser
- Download file 2.99 kB
-
https://huggingface.co/OneScience-Group/SEEDS/resolve/main/scripts/data_loader.py
- Command line
-
hf download hf://OneScience-Group/SEEDS/scripts/data_loader.py
-
curl -L -o data_loader.py https://huggingface.co/OneScience-Group/SEEDS/resolve/main/scripts/data_loader.py
2.99 kB
| """Data loading and validation for the local SEEDS data contract.""" | |
| from __future__ import annotations | |
| from pathlib import Path | |
| from typing import Dict, Iterable, Optional | |
| import numpy as np | |
| import torch | |
| from torch.utils.data import DataLoader, Dataset, DistributedSampler | |
| class SEEDSDataset(Dataset): | |
| def __init__(self, path: str | Path, channels: int, faces: int, height: int, width: int, seed_count: int) -> None: | |
| self.path = Path(path) | |
| if not self.path.exists(): | |
| raise FileNotFoundError(f"dataset does not exist: {self.path}") | |
| archive = np.load(self.path, allow_pickle=False) | |
| self.seeds = np.asarray(archive["seeds"], dtype=np.float32) | |
| self.targets = np.asarray(archive["targets"], dtype=np.float32) | |
| self.climate = np.asarray(archive["climate"], dtype=np.float32) | |
| expected = (channels, faces, height, width) | |
| if self.seeds.ndim != 6 or tuple(self.seeds.shape[2:]) != expected or self.seeds.shape[1] != seed_count: | |
| raise ValueError(f"seeds in {self.path} must have shape [N, {seed_count}, {expected}]") | |
| if self.targets.ndim != 5 or tuple(self.targets.shape[1:]) != expected: | |
| raise ValueError(f"targets in {self.path} must have shape [N, {expected}]") | |
| if self.climate.ndim != 5 or tuple(self.climate.shape[1:]) != expected: | |
| raise ValueError(f"climate in {self.path} must have shape [N, {expected}]") | |
| if len(self.seeds) != len(self.targets) or len(self.targets) != len(self.climate): | |
| raise ValueError("seeds, targets and climate must have the same sample count") | |
| if not np.isfinite(self.seeds).all() or not np.isfinite(self.targets).all() or not np.isfinite(self.climate).all(): | |
| raise ValueError(f"dataset contains NaN or Inf: {self.path}") | |
| def __len__(self) -> int: | |
| return len(self.targets) | |
| def __getitem__(self, index: int) -> Dict[str, torch.Tensor]: | |
| return { | |
| "seeds": torch.from_numpy(self.seeds[index]), | |
| "targets": torch.from_numpy(self.targets[index]), | |
| "climate": torch.from_numpy(self.climate[index]), | |
| } | |
| def build_dataloader( | |
| path: str | Path, | |
| channels: int, | |
| faces: int, | |
| height: int, | |
| width: int, | |
| seed_count: int, | |
| batch_size: int, | |
| shuffle: bool, | |
| num_workers: int = 0, | |
| max_batches: Optional[int] = None, | |
| sampler=None, | |
| dataset: Optional[SEEDSDataset] = None, | |
| ) -> Iterable[Dict[str, torch.Tensor]]: | |
| if dataset is None: | |
| dataset = SEEDSDataset(path, channels, faces, height, width, seed_count) | |
| loader = DataLoader( | |
| dataset, | |
| batch_size=batch_size, | |
| shuffle=shuffle if sampler is None else False, | |
| sampler=sampler, | |
| num_workers=num_workers, | |
| pin_memory=torch.cuda.is_available(), | |
| ) | |
| if max_batches is None: | |
| return loader | |
| return (batch for batch_index, batch in enumerate(loader) if batch_index < max_batches) | |