Download dataset/blockpush_lowdim_dataset.py from ducido/diffusion_policy_gbc: direct link, hf CLI and curl.
- Browser
- Download file 4.61 kB
-
https://huggingface.co/ducido/diffusion_policy_gbc/resolve/main/dataset/blockpush_lowdim_dataset.py
- Command line
-
hf download hf://ducido/diffusion_policy_gbc/dataset/blockpush_lowdim_dataset.py
-
curl -L -o blockpush_lowdim_dataset.py https://huggingface.co/ducido/diffusion_policy_gbc/resolve/main/dataset/blockpush_lowdim_dataset.py
4.61 kB
| from typing import Dict | |
| import torch | |
| import numpy as np | |
| import copy | |
| from diffusion_policy.common.pytorch_util import dict_apply | |
| from diffusion_policy.common.replay_buffer import ReplayBuffer | |
| from diffusion_policy.common.sampler import SequenceSampler, get_val_mask | |
| from diffusion_policy.model.common.normalizer import LinearNormalizer, SingleFieldLinearNormalizer | |
| from diffusion_policy.dataset.base_dataset import BaseLowdimDataset | |
| class BlockPushLowdimDataset(BaseLowdimDataset): | |
| def __init__(self, | |
| zarr_path, | |
| horizon=1, | |
| pad_before=0, | |
| pad_after=0, | |
| obs_key='obs', | |
| action_key='action', | |
| obs_eef_target=True, | |
| use_manual_normalizer=False, | |
| seed=42, | |
| val_ratio=0.0 | |
| ): | |
| super().__init__() | |
| self.replay_buffer = ReplayBuffer.copy_from_path( | |
| zarr_path, keys=[obs_key, action_key]) | |
| val_mask = get_val_mask( | |
| n_episodes=self.replay_buffer.n_episodes, | |
| val_ratio=val_ratio, | |
| seed=seed) | |
| train_mask = ~val_mask | |
| self.sampler = SequenceSampler( | |
| replay_buffer=self.replay_buffer, | |
| sequence_length=horizon, | |
| pad_before=pad_before, | |
| pad_after=pad_after, | |
| episode_mask=train_mask) | |
| self.obs_key = obs_key | |
| self.action_key = action_key | |
| self.obs_eef_target = obs_eef_target | |
| self.use_manual_normalizer = use_manual_normalizer | |
| self.train_mask = train_mask | |
| self.horizon = horizon | |
| self.pad_before = pad_before | |
| self.pad_after = pad_after | |
| def get_validation_dataset(self): | |
| val_set = copy.copy(self) | |
| val_set.sampler = SequenceSampler( | |
| replay_buffer=self.replay_buffer, | |
| sequence_length=self.horizon, | |
| pad_before=self.pad_before, | |
| pad_after=self.pad_after, | |
| episode_mask=~self.train_mask | |
| ) | |
| val_set.train_mask = ~self.train_mask | |
| return val_set | |
| def get_normalizer(self, mode='limits', **kwargs): | |
| data = self._sample_to_data(self.replay_buffer) | |
| normalizer = LinearNormalizer() | |
| if not self.use_manual_normalizer: | |
| normalizer.fit(data=data, last_n_dims=1, mode=mode, **kwargs) | |
| else: | |
| x = data['obs'] | |
| stat = { | |
| 'max': np.max(x, axis=0), | |
| 'min': np.min(x, axis=0), | |
| 'mean': np.mean(x, axis=0), | |
| 'std': np.std(x, axis=0) | |
| } | |
| is_x = np.zeros(stat['max'].shape, dtype=bool) | |
| is_y = np.zeros_like(is_x) | |
| is_x[[0,3,6,8,10,13]] = True | |
| is_y[[1,4,7,9,11,14]] = True | |
| is_rot = ~(is_x|is_y) | |
| def normalizer_with_masks(stat, masks): | |
| global_scale = np.ones_like(stat['max']) | |
| global_offset = np.zeros_like(stat['max']) | |
| for mask in masks: | |
| output_max = 1 | |
| output_min = -1 | |
| input_max = stat['max'][mask].max() | |
| input_min = stat['min'][mask].min() | |
| input_range = input_max - input_min | |
| scale = (output_max - output_min) / input_range | |
| offset = output_min - scale * input_min | |
| global_scale[mask] = scale | |
| global_offset[mask] = offset | |
| return SingleFieldLinearNormalizer.create_manual( | |
| scale=global_scale, | |
| offset=global_offset, | |
| input_stats_dict=stat | |
| ) | |
| normalizer['obs'] = normalizer_with_masks(stat, [is_x, is_y, is_rot]) | |
| normalizer['action'] = SingleFieldLinearNormalizer.create_fit( | |
| data['action'], last_n_dims=1, mode=mode, **kwargs) | |
| return normalizer | |
| def get_all_actions(self) -> torch.Tensor: | |
| return torch.from_numpy(self.replay_buffer['action']) | |
| def __len__(self) -> int: | |
| return len(self.sampler) | |
| def _sample_to_data(self, sample): | |
| obs = sample[self.obs_key] # T, D_o | |
| if not self.obs_eef_target: | |
| obs[:,8:10] = 0 | |
| data = { | |
| 'obs': obs, | |
| 'action': sample[self.action_key], # T, D_a | |
| } | |
| return data | |
| def __getitem__(self, idx: int) -> Dict[str, torch.Tensor]: | |
| sample = self.sampler.sample_sequence(idx) | |
| data = self._sample_to_data(sample) | |
| torch_data = dict_apply(data, torch.from_numpy) | |
| return torch_data | |