Download training_code/action_state_merger.py from SleepMastger/pusht-flashwam: direct link, hf CLI and curl.
- Browser
- Download file 2.52 kB
-
https://huggingface.co/SleepMastger/pusht-flashwam/resolve/main/training_code/action_state_merger.py
- Command line
-
hf download hf://SleepMastger/pusht-flashwam/training_code/action_state_merger.py
-
curl -L -o action_state_merger.py https://huggingface.co/SleepMastger/pusht-flashwam/resolve/main/training_code/action_state_merger.py
2.52 kB
| from typing import Dict | |
| import torch | |
| from torch.nn.functional import pad | |
| class ConcatLeftAlign: | |
| def __init__( | |
| self, | |
| action_target_dim: int | None = None, | |
| state_target_dim: int | None = None | |
| ): | |
| self.action_target_dim = action_target_dim | |
| self.state_target_dim = state_target_dim | |
| def set_shape_meta(self, shape_meta): | |
| self.action_meta = shape_meta["action"] | |
| self.state_meta = shape_meta["state"] | |
| def forward(self, batch): | |
| if "action" in batch: | |
| batch["action"] = self._concat(batch["action"], self.action_meta) | |
| batch["action"], batch["action_dim_is_pad"] = self._pad(batch["action"], self.action_target_dim) | |
| batch["state"] = self._concat(batch["state"], self.state_meta) | |
| batch["state"], batch["state_dim_is_pad"] = self._pad(batch["state"], self.state_target_dim) | |
| return batch | |
| def backward(self, batch): | |
| if self.state_target_dim is not None: | |
| assert batch["state"].shape[-1] == self.state_target_dim | |
| batch["state"] = self._crop(batch["state"], self.state_meta) | |
| batch["state"] = self._split(batch["state"], self.state_meta) | |
| if self.action_target_dim is not None: | |
| assert batch["action"].shape[-1] == self.action_target_dim | |
| batch["action"] = self._crop(batch["action"], self.action_meta) | |
| batch["action"] = self._split(batch["action"], self.action_meta) | |
| return batch | |
| def _pad(x: torch.Tensor, dim: int): | |
| if dim is None: | |
| dim = x.shape[-1] | |
| assert x.ndim == 2 and x.shape[-1] <= dim | |
| pad_dim = dim - x.shape[-1] | |
| x_padded = pad(x, (0, pad_dim)) | |
| mask = torch.zeros_like(x[0]).bool() | |
| mask = pad(mask, (0, pad_dim), value=True) | |
| return x_padded, mask | |
| def _crop(x: torch.Tensor, meta: int): | |
| assert x.ndim == 3 | |
| dim = sum([m["shape"] for m in meta]) | |
| x = x[:, :, :dim] | |
| return x | |
| def _concat(x: Dict[str, torch.Tensor], meta: Dict[str, Dict]): | |
| x = torch.cat([x[m["key"]] for m in meta], dim=-1) | |
| assert x.ndim == 2 | |
| return x | |
| def _split(x: torch.Tensor, meta: Dict[str, Dict]): | |
| assert x.ndim == 3 | |
| y = {} | |
| idx = 0 | |
| for m in meta: | |
| key, dim = m["key"], m["shape"] | |
| y[key] = x[:, :, idx: idx + dim] | |
| idx += dim | |
| return y |