Download data_loader.py from JustAGeek/dloc-code: direct link, hf CLI and curl.
- Browser
- Download file 4.04 kB
-
https://huggingface.co/JustAGeek/dloc-code/resolve/main/data_loader.py
- Command line
-
hf download hf://JustAGeek/dloc-code/data_loader.py
-
curl -L -o data_loader.py https://huggingface.co/JustAGeek/dloc-code/resolve/main/data_loader.py
4.04 kB
| #!/usr/bin/python | |
| # A simple data loader that imports the train and test mat files | |
| # from the `filename` and converts them to torch.tesnors() | |
| # to be loaded for training and testing DLoc network | |
| # `features_wo_offset`: targets for the consistency decoder | |
| # `features_w_offset` : inputs for the network/encoder | |
| # `labels_gaussian_2d`: targets for the location decoder | |
| import torch | |
| import h5py | |
| import scipy.io | |
| import numpy as np | |
| def load_data(filename): | |
| print('Loading '+filename) | |
| arrays = {} | |
| f = h5py.File(filename,'r') | |
| features_wo_offset = torch.tensor(np.transpose(np.array(f.get('features_wo_offset'), dtype=np.float32)), dtype=torch.float32) | |
| features_w_offset = torch.tensor(np.transpose(np.array(f.get('features_w_offset'), dtype=np.float32)), dtype=torch.float32) | |
| labels_gaussian_2d = torch.tensor(np.transpose(np.array(f.get('labels_gaussian_2d'), dtype=np.float32)), dtype=torch.float32) | |
| return features_wo_offset,features_w_offset, labels_gaussian_2d | |
| class LazyMultiHDF5Dataset(torch.utils.data.Dataset): | |
| """Reads samples on demand from multiple HDF5 .mat files. | |
| Uses ~0 RAM regardless of dataset size. Each __getitem__ does 3 small | |
| HDF5 slice reads (~700 KB total per sample). | |
| Returns the same tuple ordering as the original TensorDataset: | |
| (features_wo_offset, features_w_offset, labels_gaussian_2d) | |
| """ | |
| def __init__(self, file_paths): | |
| self.file_paths = file_paths | |
| self._handles = {} # lazy-opened per worker/process | |
| self.cum_sizes = [] | |
| self.var_names = {} # per file: (w_name, wo_name, lbl_name) | |
| total = 0 | |
| for fp in file_paths: | |
| with h5py.File(fp, 'r') as f: | |
| keys = list(f.keys()) | |
| w_name = 'features_w_offset' if 'features_w_offset' in keys else 'features_with_offset' | |
| wo_name = 'features_wo_offset' if 'features_wo_offset' in keys else 'features_without_offset' | |
| lbl_name = 'labels_gaussian_2d' | |
| self.var_names[fp] = (w_name, wo_name, lbl_name) | |
| # HDF5 stores MATLAB dims reversed: last dim = N | |
| n = f[w_name].shape[-1] | |
| total += n | |
| self.cum_sizes.append(total) | |
| print(f' Indexed {fp}: {n} samples') | |
| self.total_len = total | |
| print(f' Total: {self.total_len} samples (lazy, ~0 MB RAM)') | |
| def __len__(self): | |
| return self.total_len | |
| def _get_handle(self, fp): | |
| if fp not in self._handles: | |
| self._handles[fp] = h5py.File(fp, 'r') | |
| return self._handles[fp] | |
| def __getitem__(self, idx): | |
| # Find which file this idx belongs to | |
| file_idx = 0 | |
| for i, cs in enumerate(self.cum_sizes): | |
| if idx < cs: | |
| file_idx = i | |
| break | |
| offset = self.cum_sizes[file_idx - 1] if file_idx > 0 else 0 | |
| local_idx = idx - offset | |
| fp = self.file_paths[file_idx] | |
| f = self._get_handle(fp) | |
| w_name, wo_name, lbl_name = self.var_names[fp] | |
| # HDF5 dims are reversed vs MATLAB: | |
| # features: MATLAB [N,4,161,361] -> HDF5 [361,161,4,N] | |
| # labels: MATLAB [N,161,361] -> HDF5 [361,161,N] | |
| feat_w = np.array(f[w_name][:, :, :, local_idx], dtype=np.float32).transpose() # -> [4,161,361] | |
| feat_wo = np.array(f[wo_name][:, :, :, local_idx], dtype=np.float32).transpose() # -> [4,161,361] | |
| label = np.array(f[lbl_name][:, :, local_idx], dtype=np.float32).transpose() # -> [161,361] | |
| label = label[np.newaxis, :, :] # -> [1,161,361] | |
| return ( | |
| torch.from_numpy(feat_wo), | |
| torch.from_numpy(feat_w), | |
| torch.from_numpy(label) | |
| ) | |
| def __del__(self): | |
| for f in self._handles.values(): | |
| try: | |
| f.close() | |
| except Exception: | |
| pass | |