.. _norm guide: Normalization ============= .. jupyter-execute:: :hide-code: import torch We define two kind of normalizations: ``component`` and ``norm``. Definition ---------- component """"""""" ``component`` normalization refers to tensors with each component of value around 1. More precisely, the second moment of each component is 1. .. math:: \langle x_i^2 \rangle = 1 Examples: * ``[1.0, -1.0, -1.0, 1.0]`` * ``[1.0, 1.0, 1.0, 1.0]`` the mean **don't** need to be zero * ``[0.0, 2.0, 0.0, 0.0]`` this is still fine because :math:`\|x\|^2 = n` .. jupyter-execute:: torch.randn(10) norm """" ``norm`` normalization refers to tensors of norm close to 1. .. math:: \|x\| \approx 1 Examples: * ``[0.5, -0.5, -0.5, 0.5]`` * ``[0.5, 0.5, 0.5, 0.5]`` the mean **don't** need to be zero * ``[0.0, 1.0, 0.0, 0.0]`` .. jupyter-execute:: torch.randn(10) / 10**0.5 There is just a factor :math:`\sqrt{n}` between the two normalizations. Motivation ---------- Assuming that the weights distribution obey .. math:: \langle w_i \rangle = 0 \langle w_i w_j \rangle = \sigma^2 \delta_{ij} It imply that the two first moments of :math:`x \cdot w` (and therefore mean and variance) are only function of the second moment of :math:`x` .. math:: \langle x \cdot w \rangle &= \sum_i \langle x_i w_i \rangle = \sum_i \langle x_i \rangle \langle w_i \rangle = 0 \langle (x \cdot w)^2 \rangle &= \sum_{i} \sum_{j} \langle x_i w_i x_j w_j \rangle &= \sum_{i} \sum_{j} \langle x_i x_j \rangle \langle w_i w_j \rangle &= \sigma^2 \sum_{i} \langle x_i^2 \rangle Testing ------- You can use ``e3nn.util.test.assert_normalized`` to check whether a function or module is normalized at initialization: .. code:: from e3nn.util.test import assert_normalized from e3nn import o3 assert_normalized(o3.Linear("10x0e", "10x0e"))