""" Copyright (c) Facebook, Inc. and its affiliates. This source code is licensed under the MIT license found in the LICENSE file in the root directory of this source tree. """ import torch 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): """ 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