Download GR00T-WholeBodyControl/gear_sonic/utils/batch_normalizer.py from Timsty/groot_deployment: direct link, hf CLI and curl.
- Browser
- Download file 1.73 kB
-
https://huggingface.co/Timsty/groot_deployment/resolve/main/GR00T-WholeBodyControl/gear_sonic/utils/batch_normalizer.py
- Command line
-
hf download hf://Timsty/groot_deployment/GR00T-WholeBodyControl/gear_sonic/utils/batch_normalizer.py
-
curl -L -o batch_normalizer.py https://huggingface.co/Timsty/groot_deployment/resolve/main/GR00T-WholeBodyControl/gear_sonic/utils/batch_normalizer.py
1.73 kB
| import torch | |
| import torch.nn as nn | |
| class BatchNormNormalizer(nn.Module): | |
| def __init__(self, insize, epsilon=1e-05, per_channel=False, norm_only=False): | |
| super().__init__() | |
| assert len(insize) == 1, "BatchNormNormalizer only supports 1D observation spaces" | |
| self._normalizer = nn.SyncBatchNorm(num_features=insize[0], affine=False) | |
| def num_features(self): | |
| return self._normalizer.num_features | |
| def forward(self, x: torch.Tensor) -> torch.Tensor: | |
| input_shape = x.shape | |
| if len(x.shape) == 3: | |
| x = x.reshape(-1, x.shape[-1]) | |
| x = self._normalizer(x) | |
| x = x.view(input_shape) | |
| return x | |
| def update(self, input: torch.Tensor): | |
| """Update running stats from input. No-op in eval mode. | |
| Calls SyncBatchNorm.forward() for its side effect of updating | |
| running_mean/running_var (and multi-GPU sync). Output is discarded. | |
| """ | |
| if not self.training: # do nothing if in evaluation mode | |
| return | |
| if len(input.shape) == 3: | |
| input = input.reshape(-1, input.shape[-1]) | |
| with torch.no_grad(): | |
| self._normalizer(input) | |
| def normalize(self, input: torch.Tensor) -> torch.Tensor: | |
| """Normalize using current running stats without updating them.""" | |
| input_shape = input.shape | |
| if len(input.shape) == 3: | |
| input = input.reshape(-1, input_shape[-1]) | |
| y = (input - self._normalizer.running_mean) / torch.sqrt( | |
| self._normalizer.running_var + self._normalizer.eps | |
| ) | |
| y = torch.clamp(y, min=-5.0, max=5.0) | |
| if len(input_shape) == 3: | |
| y = y.view(input_shape) | |
| return y | |