Weight Initialization
Symmetry breaking, Xavier and He initialization, and the connection to gradient flow.
Before a network takes a single training step, the *starting* values of its weights already decide whether it can learn at all. Two things can go wrong at the very beginning, and both are worth understanding.
The first is a surprise: do not set all the weights to zero. It sounds harmless, but it is fatal. If every neuron in a layer starts with identical weights, they all compute the same output, all receive the same gradient, and all take the same update — so they stay identical forever. A 512-neuron layer initialised to zero behaves exactly like a *single* neuron; the other 511 are wasted. The fix is random initialisation: the randomness is what makes neurons different from one another so they can learn different features. This is called breaking symmetry.
The second problem: getting the scale right
So the weights must be random — but *how big* should those random numbers be? This turns out to matter enormously, and it connects straight to the gradient-flow story from the last lesson.
Picture a signal passing forward through the layers, multiplied by the weights at each one. If the weights are too small, the signal shrinks a little at every layer, and after 20 layers it has faded to essentially zero — the network cannot tell its inputs apart, and since a dead forward signal means a dead backward signal too, nothing learns. If the weights are too large, the opposite happens: the signal grows until it blows up, or it slams activations like sigmoid and tanh into their flat "saturated" zones where their sensitivity drops to zero — and again the gradient dies. The weights need to be *just* the right size to keep the signal steady as it travels through the network.
The recipes: Xavier and He
Happily, the right size can be worked out exactly, and it depends on how many inputs feed into a layer. The idea is simple: pick the random scale so the signal comes out of each layer at about the same size it went in — no shrinking, no growing.
Xavier (Glorot) initialisation computes that scale for symmetric activations like tanh, and it was the fix that first let deep tanh networks train reliably.
He (Kaiming) initialisation adjusts it for ReLU. Because ReLU throws away all the negative values, it roughly *halves* the signal at every layer — so He simply doubles the variance to make up for the half that ReLU discards. Use He for ReLU networks and Xavier for tanh; use the wrong one on a deep network and it will silently fail to learn.
One small but famous exception: biases can safely start at zero (the random weights already break symmetry), *except* the LSTM's "forget gate" bias, which is usually set to 1. That nudges the gate to *remember* by default at the start, keeping the memory highway open long enough for the network to learn when it actually should forget.
The actual formulas, and fan-in vs fan-out
Worth carrying the numbers. Let fan_in be the number of inputs to a layer and fan_out the number of outputs. He/Kaiming (for ReLU) uses variance 2/fan_in. Xavier/Glorot (for tanh/sigmoid) uses either 1/fan_in or the symmetric 2/(fan_in + fan_out). Why the two versions of Xavier? Preserving the signal's variance on the forward pass wants 1/fan_in; preserving the gradient's variance on the backward pass wants 1/fan_out; averaging the two (2/(fan_in+fan_out)) is the compromise that keeps both roughly stable. He fixes on fan_in because for ReLU the forward-pass halving is the dominant effect to correct.
Uniform or normal?
Both Xavier and He come in a normal and a uniform flavour, and they're near-equivalent in practice. The normal version draws from N(0, variance). The uniform version draws from U(−limit, +limit) with the limit chosen to give the *same* variance (for Xavier uniform, limit = √(6/(fan_in+fan_out))). Frameworks default to one or the other; the difference rarely matters, but know that "Xavier uniform" and "Xavier normal" are the same idea with different sampling shapes.
Orthogonal initialisation for recurrence
For RNNs and very deep near-linear stacks, there's a better choice than random Gaussian: orthogonal initialisation, where the weight matrix is initialised to be orthogonal (its rows/columns are unit vectors at right angles). An orthogonal matrix has the property that it preserves vector norms under multiplication — so applying it repeatedly (as an RNN does across time steps) neither grows nor shrinks the signal. That's exactly the property you want when the *same* matrix is multiplied hundreds of times, which is why orthogonal init helps recurrent and deep-linear networks specifically.
Modern architectures soften the sensitivity — but don't remove it
Here's the honest caveat: "use the wrong init and the network silently fails" is true for a deep plain network, but much less so once you add residual connections and BatchNorm/LayerNorm. Normalisation re-centres and re-scales activations at every layer, which repairs a lot of a bad initial scale, and residual shortcuts keep gradients flowing regardless. So a ResNet or a normalised transformer is far more *forgiving* of initialisation than an old-style plain net. Init still matters — it affects early-training stability and final quality — but it's a smaller cliff than the unqualified claim suggests.
Transformer-specific initialisation
Very deep transformers need extra care beyond He/Xavier. Because each layer adds to the residual stream, naive init lets the residual-stream variance grow with depth, destabilising training — so large models scale the residual-branch weights down by a factor related to depth (e.g. 1/√(2N) schemes) to keep the stream stable. The embedding and output layers often get their own scaling, and the LayerNorm gain/bias start at 1/0. This is why deep transformers historically needed careful warmup — and why good residual-scaling schemes let them train more stably.
Diagnosing an init problem
You can catch a bad initialisation before wasting a training run. Check the loss at step zero: for a K-class classifier it should be ≈ ln(K) (e.g. ~2.3 for 10 classes) — a wildly different value means the output scale is off. Log the activation variance per layer on the first forward pass: healthy init keeps it roughly constant across layers; a steady decay or explosion means the scale is wrong. Also check per-layer gradient norms, the dead-ReLU count, and run NaN/Inf checks. These five-minute checks tell you the init is sane before you commit GPU hours.
Key points
- First rule: never initialise all weights to zero — break symmetry with randomness. If every neuron in a layer starts identical, they compute the same output, get the same gradient, and update in lockstep, so they stay identical forever — a whole layer collapses to the behaviour of one neuron. Random initial weights make neurons different from the start, which is the only way they can specialise into different features. Biases can safely start at zero, since the random weights already do the symmetry-breaking.
- Second rule: get the scale right, because it decides whether the signal survives. Too-small weights shrink the signal a little at each layer until, several layers deep, it has faded to zero and nothing learns. Too-large weights either blow the signal up or push tanh and sigmoid into their flat saturated zones where the gradient dies. The right scale keeps the signal about the same size from layer to layer — and it can be computed exactly from how many inputs each layer has.
- Match the recipe to the activation: Xavier for tanh, He for ReLU. Xavier (Glorot) picks the scale that preserves signal size through symmetric activations like tanh. He (Kaiming) adjusts it for ReLU: since ReLU discards the negative half of the signal, halving it each layer, He doubles the variance to compensate. Use the wrong one on a deep network — Xavier with ReLU, say — and the signal quietly decays layer by layer, and the network fails to train even though nothing looks obviously broken.
- One famous exception: the LSTM forget-gate bias starts at 1, not 0. A forget gate initialised at zero passes only about half the memory forward each step, so long-range information is erased before the model ever learns when to keep it. Setting the bias to 1 makes the gate lean toward "remember" by default, keeping the memory highway open at the start of training. Everywhere else, zero is a perfectly good default for biases.
- Carry the formulas and the specialised variants. He (ReLU): variance 2/fan_in. Xavier (tanh/sigmoid): 1/fan_in (preserves forward variance) or 2/(fan_in+fan_out) (compromise between forward and backward — fan_out preserves the gradient's variance). Uniform and normal flavours are equivalent (same variance, different sampling shape). For RNNs and deep near-linear stacks, orthogonal initialisation preserves vector norms under repeated multiplication, which is exactly what you want when the same matrix is applied many times.
- Modern architectures forgive init more, transformers need residual scaling, and you can diagnose it fast. "Wrong init = silent failure" holds for deep plain nets but is softened a lot by residual connections and BatchNorm/LayerNorm, which repair bad scale at every layer — init still matters for stability and final quality, just less of a cliff. Deep transformers scale residual-branch weights down with depth (so the residual stream doesn't grow) and this is why they needed warmup. Sanity-check init before a full run: loss at step 0 ≈ ln(K), roughly constant activation variance across layers, healthy per-layer gradient norms, low dead-ReLU count, and no NaN/Inf.
Initialization is gradient flow at step zero. Before the optimizer runs, the parameters must already be at a scale where signals neither vanish nor explode in the forward pass — because if they vanish in the forward pass, they also vanish in the backward pass. The correct variance formula depends on the activation function, and using the wrong formula (Xavier for ReLU, or He for tanh) produces a deep network that silently fails to learn.
Recap
- Never initialize all weights to zero: every neuron in a layer then computes the same thing and receives the same gradient, so they stay identical forever and the layer has the capacity of one neuron — you must break symmetry with randomness.
- Scale decides survival: too-small weights fade the forward signal toward zero over depth (and vanish the backward gradient with it); too-large weights blow the signal up or saturate tanh/sigmoid into their flat regions. Init is gradient flow at step zero.
- Match the recipe to the activation: Xavier/Glorot for tanh/sigmoid, He/Kaiming for ReLU — He uses 2× the variance specifically to offset ReLU discarding the negative half of its inputs. Using Xavier for ReLU (or He for tanh) makes a deep net silently fail to learn.
- LSTM exception: initialize the forget-gate bias to 1 so the gate leans toward *remember* from the start, keeping the cell-state memory highway open; the other biases can be 0.
- Formulas: He = variance 2/fan_in; Xavier = 1/fan_in (forward) or 2/(fan_in+fan_out) (a forward+backward compromise); uniform and normal draws work about equally well.
- Orthogonal init for RNNs and deep linear stacks: an orthogonal matrix preserves vector norms under repeated multiplication, so the signal neither shrinks nor grows as it passes through many identical transforms.
- Residuals + norm forgive bad init a lot (they repair scale at every layer), so it's a soft failure not a cliff in modern nets; deep Transformers still scale residual-branch weights down with depth (why they needed warmup). Sanity-check init before a full run: loss at step 0 should be ≈ ln(K) for K classes.
Check your understanding
Q1. A 30-layer tanh network is initialised with weights from N(0, 1). Training loss barely moves. What is happening, and what is the fix?
- `A) N(0,1) is meant for networks with no activations; with tanh you should use N(0,0) — zero-variance weights that start the network as an identity — and the σ=1 is introducing neuron correlations that stall training.`
- `B) The weights are too large: each layer amplifies the signal, driving tanh into saturation where sensitivity is near zero — the signal dies. Fix: Xavier initialisation, keeping the signal steady in tanh's range.`
- `C) The weights are too *small*, not too large — with 256 inputs each product is tiny, so activations shrink toward zero by layer five; the fix is to raise the scale to about √(n_in) so activations stay at unit size.`
- `D) The weights are too spread out, so a few neurons saturate while others learn nothing; the fix is orthogonal initialisation, which gives every neuron an equal norm and prevents any single one from saturating.`
Q2. Why is He initialisation made specifically for ReLU, and what goes wrong if you use Xavier on a deep ReLU network?
- `A) He is for ReLU because ReLU only outputs positive values, doubling the activations' running mean at each layer; Xavier assumes zero-mean signals, so He deliberately shrinks the weight scale to stop the positive-shifted activations from compounding into overflow.`
- `B) Xavier balances the forward and backward passes equally; for ReLU the backward pass behaves fundamentally differently because gradients only flow through active units, so He optimises purely for the backward-pass gradient variance and lets the forward-pass variance drift by a small amount.`
- `C) He specifically handles ReLU's kink at zero — Xavier's derivation assumes a smooth derivative everywhere, and ReLU's corner in the derivative changes the integral used to derive the variance formula, which is where the extra factor of 2 in He actually comes from.`
- `D) Xavier preserves signal size for symmetric activations, but ReLU zeros the negative half of its inputs, halving the signal each layer — with Xavier's scale, 30 ReLU layers shrink by ~0.5^30 ≈ 10⁻⁹ and collapse. He doubles the variance to cancel that.`
Q3. Why can biases be initialised to zero when weights cannot, and what is the LSTM exception? Select the two true statements.
- `A) Zeroing all weights is fatal because it makes every neuron identical forever — symmetry never breaks; zeroing biases is fine because the random weights already make neurons differ, so a zero bias does no harm.`
- `B) The LSTM forget gate is the deliberate exception: at bias 0 it passes only about half the memory forward each step, quickly erasing long-range information — so it is set to 1 instead, leaning toward "remember" at the start and keeping the memory highway open.`
- `C) Biases must be zero to satisfy the zero-mean-activation assumption that Xavier and He rely on; a non-zero bias shifts the pre-activations and breaks the variance formulas used to derive both initialisation schemes.`
- `D) Both weights and biases can safely be zero — zero weights simply train more slowly because all neurons temporarily share one gradient, not incorrectly; the LSTM bias is a special case needed to offset tanh saturation at the edges of its range.`
Q4. Xavier initialisation has two common variance formulas: 1/fan_in and 2/(fan_in + fan_out). Why do both exist?
- `A) 1/fan_in is the correct formula specifically for classification networks with a softmax output layer, while 2/(fan_in+fan_out) is required for regression networks with linear outputs — the choice is determined entirely by task type.`
- `B) Preserving forward-pass signal variance calls for 1/fan_in; preserving backward-pass gradient variance calls for 1/fan_out. Since one scale can't satisfy both when fan_in ≠ fan_out, 2/(fan_in+fan_out) averages them as a compromise.`
- `C) 2/(fan_in+fan_out) is simply the newer, strictly better formula published after further research corrected an error in the original derivation; 1/fan_in is the deprecated legacy version and should never be used.`
- `D) They give identical values in all cases because fan_in always equals fan_out in fully-connected layers by construction, so the two formulas are just notational variants of the same underlying quantity.`
Q5. You're training a plain (non-normalised) RNN and want the recurrent weight matrix to neither vanish nor explode the signal as it's applied across hundreds of time steps. Which initialisation is especially suited, and why?
- `A) He initialisation, because the RNN's gates behave like ReLU units and He's variance-2/fan_in formula is calibrated for exactly this repeated-multiplication case, making it the universal right choice for any recurrent architecture.`
- `B) Orthogonal initialisation: an orthogonal matrix preserves vector norms under multiplication, so the same matrix applied repeatedly neither grows nor shrinks the signal. Random Gaussian init lacks this and tends to vanish or explode.`
- `C) Zero initialisation, so the recurrent weight matrix starts as an exact zero matrix and the network begins by ignoring all recurrent history entirely, forcing it to learn recurrence from scratch without any inherited growth or shrink bias.`
- `D) Very large Gaussian weights with variance well above 1/fan_in, because a recurrent matrix with larger entries guarantees the signal norm grows enough at each step to survive being multiplied across hundreds of time steps.`
Try it interactively
ML Systems Lab is a free interview-prep platform for ML engineers — work through the full interactive module, quizzes, and drills.
Open ML Systems Lab →