Weight Initialization › Variance Analysis of Forward Propagation
Language AI HandbookAll chapters Weight Initialization › Variance Analysis of Forward PropagationOne section · Sections in this chapter5 / 19 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
The experiments reveal the symptoms, but to find the cure we need to understand the cause mathematically. The key question is: how does the variance of activations change as they pass through each layer?
If we can answer this question, we can work backward to determine what weight variance preserves activation variance across layers. This is the central insight behind principled initialization: treat variance preservation as a design constraint, then solve for the weight scale that satisfies it. The beauty of this approach is that it converts a vague intuition ("weights shouldn't be too big or too small") into a concrete formula with a clear derivation.
The Pre-Activation Equation
Consider a single layer with input neurons. Each output neuron computes a weighted sum of its inputs before applying the activation function. For a single output neuron, this pre-activation value is:
where:
- : the pre-activation value (the raw weighted sum before any activation function is applied)
- : the weight connecting input neuron to this output neuron
- : the activation value from input neuron
- : the number of input neurons (the fan-in)
The pre-activation is a sum of random terms. We want to understand how its variance relates to the variances of the weights and inputs.
Deriving the Variance Relationship
To derive how variance propagates, we make two assumptions that hold approximately during the early stages of training: weights and inputs are independent random variables with zero mean.
Step 1: Variance is additive for independent random variables. Because the terms are independent of each other (each uses a different weight-input pair):
Step 2: Variance of a product of two independent zero-mean variables. For any two independent, zero-mean random variables and :
Step 3: Combine. Assuming all weights share variance and all inputs share variance :
where:
- : the number of input neurons (fan-in)
- : the variance of each weight, assumed identical across all weights in the layer
- : the variance of each input activation, assumed identical across all inputs
This formula immediately explains the explosion problem. With and unit-variance weights (), the output variance is . Each layer multiplies variance by , producing exponential growth.
For a weight matrix connecting two layers, fan-in () is the number of input connections per output neuron, and fan-out () is the number of output connections per input neuron. For a fully connected layer with an weight matrix, fan-in equals the input dimension and fan-out equals the output dimension.
The assumptions we made (independence, zero mean) are strictly true only at initialization, before any training has occurred. As training proceeds, weights and activations become correlated. However, the variance relationships remain approximately valid throughout early training, which is precisely the period when initialization matters most. By the time the network has trained for many epochs, the optimization landscape has been significantly reshaped and initialization conditions matter much less.
Solving for the Optimal Weight Variance
To maintain stable variance across layers, we want . Starting from:
Setting and dividing both sides by :
Solving for the weight variance:
The weight variance should scale inversely with the number of input connections. Summing independent random terms amplifies variance by , so each weight's variance must be to counteract this amplification.
This result is sometimes called LeCun initialization, after Yann LeCun who described it in his 1998 work on convolutional networks. It is the optimal forward-pass initialization for networks with linear or nearly-linear activation functions, and it forms the theoretical foundation for both Xavier and He initialization.
def analyze_variance_propagation(n_layers, layer_size, weight_variance):
"""Track variance across layers with specified weight variance (no activation)."""
weights = [
np.random.randn(layer_size, layer_size) * np.sqrt(weight_variance)
for _ in range(n_layers)
]
x = np.random.randn(1000, layer_size)
x = x / np.std(x) # Normalize to unit variance
variances = [np.var(x)]
for W in weights:
x = x @ W
variances.append(np.var(x))
return variances
variance_choices = {
"Too small (1/n^2)": 1 / (layer_size**2),
"Just right (1/n)": 1 / layer_size,
"Too large (1)": 1.0,
}Variance propagation through 10 layers (no activation): Layer size: 256 ------------------------------------------------------------ Too small (1/n^2): Initial variance: 1.0000 Final variance: 8.2928e-25 Ratio (final/initial): 8.2928e-25 Just right (1/n): Initial variance: 1.0000 Final variance: 1.0596e+00 Ratio (final/initial): 1.0596e+00 Too large (1): Initial variance: 1.0000 Final variance: 1.1612e+24 Ratio (final/initial): 1.1612e+24
With weight variance , the output variance stays close to the input variance, confirming our derivation. The other choices cause variance to explode or collapse exponentially with depth.
