Download model/common/gemnet/initializers.py from OneScience-Group/MatterGen: direct link, hf CLI and curl.
- Browser
- Download file 1.65 kB
-
https://huggingface.co/OneScience-Group/MatterGen/resolve/main/model/common/gemnet/initializers.py
- Command line
-
hf download hf://OneScience-Group/MatterGen/model/common/gemnet/initializers.py
-
curl -L -o initializers.py https://huggingface.co/OneScience-Group/MatterGen/resolve/main/model/common/gemnet/initializers.py
1.65 kB
| """ | |
| Copyright (c) Facebook, Inc. and its affiliates. | |
| Copyright (c) Microsoft Corporation. | |
| Licensed under the MIT License. | |
| Adapted from https://github.com/FAIR-Chem/fairchem/blob/main/src/fairchem/core/models/gemnet/initializers.py. | |
| """ | |
| import torch | |
| # This function is not type annotated because mypy complains that axis could be either an integer or a tuple of integers, | |
| # even though this is precicely how torch.var_mean works | |
| def _standardize(kernel): | |
| """ | |
| Makes sure that N*Var(W) = 1 and E[W] = 0 | |
| """ | |
| eps = 1e-6 | |
| if len(kernel.shape) == 3: | |
| axis = (0, 1) # last dimension is output dimension | |
| else: | |
| axis = 1 | |
| var, mean = torch.var_mean(kernel, dim=axis, unbiased=True, keepdim=True) | |
| kernel = (kernel - mean) / (var + eps) ** 0.5 | |
| return kernel | |
| def he_orthogonal_init(tensor: torch.Tensor) -> torch.Tensor: | |
| """ | |
| Generate a weight matrix with variance according to He (Kaiming) initialization. | |
| Based on a random (semi-)orthogonal matrix neural networks | |
| are expected to learn better when features are decorrelated | |
| (stated by eg. "Reducing overfitting in deep networks by decorrelating representations", | |
| "Dropout: a simple way to prevent neural networks from overfitting", | |
| "Exact solutions to the nonlinear dynamics of learning in deep linear neural networks") | |
| """ | |
| tensor = torch.nn.init.orthogonal_(tensor) | |
| if len(tensor.shape) == 3: | |
| fan_in = tensor.shape[:-1].numel() | |
| else: | |
| fan_in = tensor.shape[1] | |
| with torch.no_grad(): | |
| tensor.data = _standardize(tensor.data) | |
| tensor.data *= (1 / fan_in) ** 0.5 | |
| return tensor | |