MatterGen / model /common /gemnet /initializers.py
dadadaxi's picture
Upload folder using huggingface_hub
f15d29e verified
Raw
History Blame Contribute Delete
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