Source code for mygrad.nnet.initializers.glorot_uniform
import numpy as np
from mygrad.nnet.initializers.uniform import uniform
[docs]def glorot_uniform(*shape, gain=1, dtype=np.float32, constant=None):
r"""Initialize a :class:`mygrad.Tensor` according to the uniform initialization procedure
described by Glorot and Bengio.
Parameters
----------
shape : Sequence[int]
The shape of the output Tensor. Note that ``shape`` must be at least two-dimensional.
gain : Real, optional (default=1)
The gain (scaling factor) to apply.
dtype : data-type, optional (default=float32)
The data type of the output tensor; must be a floating-point type.
constant : bool, optional (default=False)
If ``True``, the returned tensor is a constant (it
does not back-propagate a gradient).
Returns
-------
mygrad.Tensor, shape=``shape``
A Tensor, with values initialized according to the glorot uniform initialization.
Notes
-----
Glorot and Bengio put forward this initialization in the paper
"Understanding the Difficulty of Training Deep Feedforward Neural Networks"
http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf
A Tensor :math:`W` initialized in this way should be drawn from a distribution about
.. math::
U[-\frac{\sqrt{6}}{\sqrt{n_j+n_{j+1}}}, \frac{\sqrt{6}}{\sqrt{n_j+n_{j+1}}}]
"""
if len(shape) == 1:
shape = shape[0]
if len(shape) < 2:
raise ValueError(
"Glorot Uniform initialization requires at least two dimensions"
)
fan_in = shape[1] * (np.prod(shape[2:]) if len(shape) > 2 else 1)
fan_out = shape[0] * (np.prod(shape[2:]) if len(shape) > 2 else 1)
bound = gain * np.sqrt(6 / (fan_in + fan_out))
return uniform(
shape, lower_bound=-bound, upper_bound=bound, dtype=dtype, constant=constant
)