Weight Initialization
Weight Initialization is the starting point of neural network training. A good initialization allows the training to converge quickly and stably; a poor initialization can lead to training stagnation, oscillation, or even collapse. This chapter will deeply analyze the importance of initialization, introduce two classic methods -- Xavier initialization and He initialization -- and verify the practical impact of initialization on training through experiments.
The Symmetry Breaking Problem
Before introducing weight initialization methods, let us first consider what happens if we do not initialize weights at all and instead let all neurons start from the same parameter value (e.g., zero). Consider a simple two-layer fully-connected network where input passes through a hidden layer to reach the output (i.e., , ), where is the weight matrix from the input layer to the hidden layer and is the weight matrix from the hidden layer to the output layer. If we initialize both matrices to zero (i.e., ), then during forward propagation, we find that the outputs of all hidden layer neurons are (because the weights are zero), and the outputs of all output layer neurons are also (because and the weights are zero). This means the network's expressive power completely degenerates -- the 100 hidden neurons intended to learn different features become 100 identical replicas.
The network cannot escape this predicament through training either, because the backpropagation phase is equally problematic. The gradient of the hidden layer weights is . When , the gradient is directly zero, meaning the parameters cannot update and the network remains at its initial state forever. Even if we only initialize to zero while keeping non-zero, since , the error propagates identically to all hidden neurons regardless of the different values in 's components. The hidden layer neurons all receive the same gradient, and the updated weights remain identical. This phenomenon, where all neurons are forced to learn the same function and the network's multi-layer, multi-neuron structure becomes meaningless, is called the Symmetry Breaking Problem. Zero initialization strips neurons of their distinctiveness, degrading a carefully designed network structure into a single neuron.
Weight Initialization
Since zero initialization suffers from the symmetry breaking problem, an intuitive solution naturally emerges: assign different random initial values to each neuron's weights to break the symmetry between neurons. We use two of the most common random distributions, the uniform distribution and the normal distribution, to attempt random initialization.
- Uniform Distribution Initialization: Randomly sample weights from the interval : , each weight sampled independently. The variance of the uniform distribution is .
- Normal Distribution Initialization: Sample weights from a zero-mean normal distribution: . Most weights are concentrated within the range , with a few possibly larger or smaller. The mean is 0 and the variance is .
Random initialization successfully breaks the symmetry between neurons, allowing each neuron to learn different features. However, we must address a key question: how should the distribution parameters ( or ) be set? This question determines the success or failure of training. Using the normal distribution as an example, consider two extreme scenarios:
- Parameters too large (e.g., ): During forward propagation, weights multiply the input to produce enormous activation values. For activation functions like Sigmoid and tanh, receiving an input like 100 pushes the output very close to 1. The activations are constantly at the saturation boundary, gradients during backpropagation are near zero, and little parameter update information is transmitted.
- Parameters too small (e.g., ): During forward propagation, activation values decay layer by layer. The signal grows weaker like whispers as it propagates. During backpropagation, gradients also shrink layer by layer. By the time they reach the earlier layers, there is no parameter update information left, and training nearly stalls.
These phenomena are classic instances of the vanishing gradient problem. It is clear that good initialization must find a balance between two goals: "breaking symmetry so each neuron has a unique identity" and "maintaining signal strength to avoid gradient vanishing, allowing the error signal to propagate stably back to the input layer." These two goals appear contradictory. Finding the ideal random distribution parameters is precisely the problem that Xavier initialization and He initialization aim to solve.
Xavier Initialization
By analyzing the signal propagation process through the network, we can derive the weight variance needed to maintain signal stability and precisely calculate the optimal initialization parameters. This method was first proposed in 2010 by Canadian computer scientist Xavier Glorot and his advisor Yoshua Bengio (2018 Turing Award winner). In their paper titled "Understanding the difficulty of training deep feedforward neural networks", they systematically analyzed the causes of training difficulties in deep networks and introduced the famous Xavier initialization method. This paper revealed the deep connection between initialization and training stability, becoming a landmark work in the field of deep learning optimization.
Let us begin by analyzing the simplest case: what weight variance allows a signal to propagate through layer after layer of the network. Consider a linear neuron (temporarily ignoring the activation function, or assuming it is linear). Suppose this neuron receives inputs and produces one output . To analyze the output variance, we need to make some reasonable assumptions. Let the weights and inputs satisfy the following conditions:
- Independent and identically distributed (each weight and each input is independently sampled)
- Zero mean (, )
- Fixed variance (, )
Under these assumptions, the variance of the output can be derived. First, by the definition of variance, . Since and are independent, using the variance of sum of independent variables property (), we obtain:
Furthermore, using the variance of product of independent variables property (), combined with the zero-mean assumption ( and ), we obtain:
This formula reveals a key insight about signal forward propagation: the output variance equals the product of three factors. is the number of inputs -- more inputs lead to larger variance. is the weight variance -- more dispersed weights lead to larger variance. is the input variance -- more dispersed inputs lead to larger variance. To maintain the signal strength of the input variance, the first two factors should cancel each other out through multiplication. That is, the weight variance should be to preserve signal strength.
So far, we have only completed half of the analysis, considering only the forward propagation direction from input to output. Training a neural network also requires backpropagation. The output layer gradient is propagated back through the weight matrix to the input layer, forming the input layer gradient. The propagation formula is . Since we are temporarily ignoring the activation function, its gradient is , giving us:
Rewriting the matrix form, the gradient of the -th neuron in the input layer is the weighted sum of the gradients of all neurons in the output layer:
where is the number of output neurons (called Fan-Out), and is the weight from input to output . This structure is exactly the same as equation (1). We similarly assume that the weights are independently and identically distributed, have zero mean, and fixed variance. Under these conditions, the variance of the input layer gradient can be derived using the same process as before, yielding:
To maintain the gradient strength unchanged (), we need . Therefore, the ideal weight variance should be . A contradiction has emerged in our derivation: forward propagation requires , while backpropagation requires . In practice, in general, and reality dictates that we cannot satisfy both conditions simultaneously.
To address this, Xavier Glorot proposed an elegant compromise solution. Forward propagation requires , while backpropagation requires . These two conditions are like a tug-of-war -- one pulls left, the other pulls right. When , we can only choose a compromise position. Xavier initialization adopts the harmonic mean of and :
Why choose the harmonic mean over the arithmetic mean? Glorot's reasoning is that the harmonic mean is more sensitive to smaller values. When and differ significantly, the harmonic mean leans toward the smaller value, avoiding excessively large variance that could lead to gradient explosion. Based on this variance formula, Xavier initialization has two specific implementations.
Xavier Uniform Initialization: Sample from a uniform distribution. The variance of a uniform distribution is . To make the variance equal to , we need , giving .
Xavier Normal Initialization: Sample from a normal distribution. The variance of a normal distribution is , so the standard deviation is directly taken as .
The derivation of Xavier initialization has a key assumption: the activation function is linear. This assumption certainly does not hold in practice (activation functions are meant for non-linear expression). However, consider this: if Xavier initialization controls the weight variance, most activation values will not deviate far from zero and fall into the saturation region, but instead remain concentrated near zero. Let us revisit the shape of the Sigmoid activation function. When the input is near 0, the behavior of the Sigmoid function can be approximated using a Taylor expansion:
This is a linear function. When the activation values fall near 0, Sigmoid approximates a linear transformation, and Xavier's linearity assumption is largely valid within this range. Similarly, the tanh activation function is also approximately linear near 0:
tanh's linear approximation near 0 is even more precise than sigmoid's (slope of 1 vs. sigmoid's slope of 0.25). Xavier initialization leverages this property by controlling the weight variance so that activation values fall near 0 (the linear region), thereby maintaining stable signal strength during propagation.
Of course, based on its underlying assumptions, Xavier initialization has notable limitations. On one hand, when inputs are far from 0, the non-linear characteristics of activation functions emerge. Xavier initialization can only try to keep activation values in the linear region but cannot completely avoid saturation. On the other hand, and more critically, Xavier initialization is not compatible with the ReLU activation function. ReLU's characteristics are fundamentally different from Sigmoid and tanh. ReLU retains only positive values and sets all negative values to zero, meaning about half of the activation values are "killed" and the signal strength is halved. Xavier's linearity assumption completely fails for ReLU. If Xavier initialization is used for a ReLU network, activation values decay layer by layer, and the gradients of deep layers are nearly zero. To address ReLU's unique characteristics, a new initialization method is needed -- this is precisely the problem that He initialization solves.
He Initialization
To address the incompatibility of Xavier initialization with ReLU, Chinese computer scientist Kaiming He proposed an initialization method specifically designed for ReLU in 2015. In his paper "Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification", he systematically analyzed the signal propagation characteristics of ReLU networks and proposed He initialization. This paper not only contributed to initialization theory but, more importantly, demonstrated for the first time the possibility of deep networks surpassing human performance on image classification tasks. Kaiming He's team achieved a Top-5 error rate of 3.57% on the ImageNet competition using deep residual networks (ResNet), lower than the human error rate of 5.1%. This milestone achievement proved the enormous potential of deep learning and established He initialization as a core method for ReLU networks.
The problem with Xavier initialization stems from ReLU killing half the signal in each layer; we need larger weight variance to compensate. Following a similar derivation to Xavier initialization, we consider signal propagation after ReLU activation and derive the weight variance needed to maintain signal stability. Let the input be the output of the previous layer's ReLU, with weights independently and identically distributed with zero mean. Forward propagation is divided into two steps: weighted summation () and ReLU activation (). The variance derivation for the first step remains unchanged (see (2)), giving:
After ReLU activation , for a zero-mean , the variance of the ReLU output is half of the original variance:
To maintain signal strength unchanged (), the product of the first two terms must equal 1 (), giving:
The 2 in the numerator is a compensation factor that counteracts ReLU's signal attenuation (multiplying by requires to compensate). He initialization requires a larger weight variance than Xavier to offset ReLU's "kill half the signal" effect. Based on this variance formula, He initialization also has two implementations:
- He Uniform Initialization: Sample from a uniform distribution. The boundary of the uniform distribution is , so that the variance satisfies .
- He Normal Initialization: Sample from a normal distribution. The standard deviation is , with most weights falling within .
He initialization's variance formula only considers , while Xavier considers the harmonic mean of . This is because He initialization places greater emphasis on forward propagation signal compensation. ReLU's sparsity problem mainly occurs during forward propagation. During backpropagation, gradients only pass through positive-valued neurons, and the signal is also halved in the reverse direction. However, He initialization prioritizes forward propagation signal stability and therefore only compensates for the forward direction. When , He initialization's variance is approximately twice that of Xavier.
Initialization Method Practice
Theoretical analysis tells us that Xavier initialization is suitable for Sigmoid/tanh, and He initialization is suitable for ReLU. In this section, let us verify this conclusion through code experiments.
The following experiment simulates a multi-layer neural network (similar to an MLP structure), comparing the performance of five initialization methods (zero initialization, small variance initialization, large variance initialization, Xavier initialization, He initialization) under three activation functions (Sigmoid, ReLU, tanh). The experiment measures three key indicators: the distribution of activation values per layer (verifying signal propagation), the gradient norm per layer (verifying gradient propagation), and the training loss curve (verifying convergence speed).
import numpy as np
import matplotlib.pyplot as plt
print("=" * 60)
print("Experiment: Impact of Different Initialization Methods on Training Stability")
print("=" * 60)
print()
# Define activation functions
def sigmoid(x):
return 1 / (1 + np.exp(-np.clip(x, -500, 500)))
def sigmoid_derivative(x):
s = sigmoid(x)
return s * (1 - s)
def relu(x):
return np.maximum(0, x)
def relu_derivative(x):
return (x > 0).astype(float)
def tanh(x):
return np.tanh(x)
def tanh_derivative(x):
return 1 - np.tanh(x)**2
# Define initialization methods
def zero_init(shape):
"""Zero initialization"""
return np.zeros(shape)
def random_init(shape, scale=0.01):
"""Random initialization (small variance)"""
return np.random.randn(*shape) * scale
def random_large_init(shape, scale=10):
"""Random initialization (large variance)"""
return np.random.randn(*shape) * scale
def xavier_uniform_init(shape):
"""Xavier uniform initialization"""
fan_in, fan_out = shape[0], shape[1]
limit = np.sqrt(6 / (fan_in + fan_out))
return np.random.uniform(-limit, limit, shape)
def xavier_normal_init(shape):
"""Xavier normal initialization"""
fan_in, fan_out = shape[0], shape[1]
std = np.sqrt(2 / (fan_in + fan_out))
return np.random.randn(*shape) * std
def he_normal_init(shape):
"""He normal initialization"""
fan_in = shape[0]
std = np.sqrt(2 / fan_in)
return np.random.randn(*shape) * std
def he_uniform_init(shape):
"""He uniform initialization"""
fan_in = shape[0]
limit = np.sqrt(6 / fan_in)
return np.random.uniform(-limit, limit, shape)
# Simple multi-layer network
class SimpleNetwork:
def __init__(self, layer_sizes, activation='relu', init_method='he_normal'):
self.layer_sizes = layer_sizes
self.num_layers = len(layer_sizes) - 1
# Select activation function
if activation == 'sigmoid':
self.activation = sigmoid
self.activation_derivative = sigmoid_derivative
elif activation == 'relu':
self.activation = relu
self.activation_derivative = relu_derivative
elif activation == 'tanh':
self.activation = tanh
self.activation_derivative = tanh_derivative
# Select initialization method
init_funcs = {
'zero': zero_init,
'random_small': lambda s: random_init(s, 0.01),
'random_large': lambda s: random_init(s, 10),
'xavier_uniform': xavier_uniform_init,
'xavier_normal': xavier_normal_init,
'he_normal': he_normal_init,
'he_uniform': he_uniform_init
}
self.init_func = init_funcs[init_method]
# Initialize weights and biases
self.weights = []
self.biases = []
for i in range(self.num_layers):
w = self.init_func((layer_sizes[i], layer_sizes[i+1]))
b = np.zeros((1, layer_sizes[i+1]))
self.weights.append(w)
self.biases.append(b)
# Record activations and gradients per layer
self.activations_history = []
self.gradients_history = []
def forward(self, X):
"""Forward propagation"""
self.activations = [X]
self.pre_activations = []
a = X
for i in range(self.num_layers):
z = a @ self.weights[i] + self.biases[i]
self.pre_activations.append(z)
a = self.activation(z)
self.activations.append(a)
return a
def backward(self, X, y, learning_rate=0.01):
"""Backward propagation"""
m = X.shape[0]
# Compute output layer error (simple MSE loss)
delta = (self.activations[-1] - y) * self.activation_derivative(self.pre_activations[-1])
# Store gradient norms
gradients = []
# Backward propagation
for i in range(self.num_layers - 1, -1, -1):
# Compute weight gradient
grad_w = self.activations[i].T @ delta / m
grad_b = np.mean(delta, axis=0, keepdims=True)
gradients.append(np.linalg.norm(grad_w))
# Update weights and biases
self.weights[i] -= learning_rate * grad_w
self.biases[i] -= learning_rate * grad_b
# Propagate error to the previous layer
if i > 0:
delta = (delta @ self.weights[i].T) * self.activation_derivative(self.pre_activations[i-1])
# Record gradient history (from first layer to last)
self.gradients_history.append(gradients[::-1])
self.activations_history.append([np.mean(np.abs(a)) for a in self.activations])
# Experiment 1: Activation value distribution for different initialization methods
print("Experiment 1: Activation Distribution for Different Initialization Methods")
print("-" * 40)
layer_sizes = [784, 512, 256, 128, 64, 10] # Similar to MLP structure
n_samples = 100
X = np.random.randn(n_samples, 784) * 0.5 # Simulate standardized input
init_methods = ['zero', 'random_small', 'random_large', 'xavier_normal', 'he_normal']
activation_names = ['sigmoid', 'relu', 'tanh']
results = {}
for activation in activation_names:
results[activation] = {}
for init_method in init_methods:
net = SimpleNetwork(layer_sizes, activation=activation, init_method=init_method)
output = net.forward(X)
# Record mean and variance of activation values per layer
activation_stats = []
for i, a in enumerate(net.activations):
mean_val = np.mean(np.abs(a))
std_val = np.std(a)
activation_stats.append((mean_val, std_val))
results[activation][init_method] = {
'activations': net.activations,
'pre_activations': net.pre_activations,
'stats': activation_stats
}
print(f"{activation} + {init_method}:")
for i, (mean_val, std_val) in enumerate(activation_stats):
print(f" {i}: mean={mean_val:.4f}, std={std_val:.4f}")
print()
# Visualize activation distribution
fig, axes = plt.subplots(3, 5, figsize=(20, 12))
for row, activation in enumerate(activation_names):
for col, init_method in enumerate(init_methods):
ax = axes[row, col]
stats = results[activation][init_method]['stats']
layer_means = [s[0] for s in stats]
layer_stds = [s[1] for s in stats]
layers = range(len(stats))
ax.bar(layers, layer_means, color='#3498db', alpha=0.7, label='Mean')
ax.errorbar(layers, layer_means, yerr=layer_stds, fmt='o', color='#e74c3c',
capsize=5, capthick=2, label='Std Dev')
ax.set_xlabel('Layer')
ax.set_ylabel('Activation Value')
ax.set_title(f'{activation} + {init_method}')
ax.legend(fontsize=8)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
plt.close()
print("\n" + "=" * 60)
print("Experiment 2: Gradient Propagation for Different Initialization Methods")
print("-" * 40)
# Experiment 2: Gradient propagation for different initialization methods
layer_sizes = [784, 512, 256, 128, 10]
n_samples = 100
X = np.random.randn(n_samples, 784) * 0.5
y = np.random.randn(n_samples, 10) * 0.1 # Simulate target output
gradient_results = {}
for activation in ['sigmoid', 'relu']:
gradient_results[activation] = {}
for init_method in init_methods:
if init_method == 'zero':
continue # Zero initialization yields zero gradients, skip
net = SimpleNetwork(layer_sizes, activation=activation, init_method=init_method)
# Train for 50 steps, record gradients
for step in range(50):
output = net.forward(X)
net.backward(X, y, learning_rate=0.001)
# Extract gradient norms per layer (take the last step)
final_gradients = net.gradients_history[-1]
gradient_results[activation][init_method] = {
'gradients': final_gradients,
'history': net.gradients_history
}
print(f"{activation} + {init_method}:")
for i, g in enumerate(final_gradients):
print(f" Layer {i} gradient norm: {g:.6f}")
print()
# Visualize gradient distribution
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
for idx, activation in enumerate(['sigmoid', 'relu']):
ax = axes[idx]
for init_method in init_methods:
if init_method == 'zero':
continue
gradients = gradient_results[activation][init_method]['gradients']
layers = range(len(gradients))
ax.plot(layers, gradients, 'o-', linewidth=2, markersize=8, label=init_method)
ax.set_xlabel('Layer')
ax.set_ylabel('Gradient Norm')
ax.set_title(f'Gradient Propagation for {activation} Activation')
ax.legend()
ax.grid(True, alpha=0.3)
ax.set_yscale('log')
plt.tight_layout()
plt.show()
plt.close()
print("\n" + "=" * 60)
print("Experiment 3: Impact of Initialization on Training Convergence")
print("-" * 40)
# Experiment 3: Impact of initialization on training convergence
layer_sizes = [784, 256, 128, 10]
n_samples = 500
n_epochs = 200
# Generate simple classification data
X_train = np.random.randn(n_samples, 784)
y_train = np.zeros((n_samples, 10))
y_train[:, 0] = 1 # All samples are class 0
convergence_results = {}
for activation in ['relu', 'sigmoid']:
convergence_results[activation] = {}
for init_method in ['random_small', 'xavier_normal', 'he_normal']:
if activation == 'relu' and init_method == 'xavier_normal':
continue # Xavier is not suitable for ReLU
if activation == 'sigmoid' and init_method == 'he_normal':
continue # He is not suitable for sigmoid
net = SimpleNetwork(layer_sizes, activation=activation, init_method=init_method)
losses = []
for epoch in range(n_epochs):
output = net.forward(X_train)
loss = np.mean((output - y_train)**2)
losses.append(loss)
net.backward(X_train, y_train, learning_rate=0.01)
convergence_results[activation][init_method] = {
'losses': losses,
'final_loss': losses[-1]
}
print(f"{activation} + {init_method}:")
print(f" Initial loss: {losses[0]:.4f}")
print(f" Final loss: {losses[-1]:.4f}")
print(f" Loss reduction: {losses[0] - losses[-1]:.4f}")
print()
# Visualize convergence curves
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
for idx, activation in enumerate(['relu', 'sigmoid']):
ax = axes[idx]
for init_method, data in convergence_results[activation].items():
ax.plot(data['losses'], linewidth=2, label=init_method)
ax.set_xlabel('Epoch')
ax.set_ylabel('Loss')
ax.set_title(f'Training Convergence for {activation} Activation')
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
plt.close()
Bias Initialization
Thus far, we have discussed weight initialization. However, a neuron's parameters include both weights and biases. How should biases be initialized? The answer is that biases are typically initialized to zero, for the following reasons:
- Biases do not participate in signal strength transmission: The weight matrix multiplied by the input determines how the signal flows; biases merely add a constant offset without changing the relative signal strength. Therefore, zero bias does not cause symmetry issues.
- Zero bias keeps the activation function in the linear region: Sigmoid and tanh are approximately linear when the input is near 0, which is precisely the prerequisite for Xavier initialization to work. Zero bias makes the activation function's input approximately equal to (zero mean), helping activation values fall in the linear region.
- Non-zero bias may push activation values out of the linear region: If the bias is initialized to a large positive value, Sigmoid activation values may directly saturate to 1, with gradients near zero. If the bias is initialized to a large negative value, activation values may directly saturate to 0, also with gradients near zero.
However, there are some special cases where non-zero bias initialization is needed, such as:
Positive bias for ReLU networks: The ReLU activation function sets negative values to zero. If the weight initialization makes the variance of the weighted sum moderate (as in He initialization), most activation values may fall near zero, with half positive and half negative. After the negative portion is zeroed out, the network's initial output may be too sparse. Initializing biases to a small positive value (e.g., 0.01) can ensure that most neurons have non-zero output initially, helping to avoid the dead neuron problem.
LSTM forget gate bias: LSTM (Long Short-Term Memory, covered in a later chapter) has a forget gate that controls how much of the previous time step's information is retained. When the forget gate output is close to 0, most historical information is forgotten; when the output is close to 1, most information is retained. If the forget gate bias is initialized to zero, the initial forget gate output may be close to 0.5 (the midpoint of Sigmoid), causing partial forgetting of historical information. Initializing the forget gate bias to 1 or larger makes the initial forget gate output close to 1, retaining more historical information and helping the network learn long-term dependencies in the early stages of training.
Summary
This chapter started from "why initialization is crucial," systematically analyzed the impact of weight initialization on deep network training, and introduced two classic methods: Xavier initialization and He initialization. The challenge of initialization lies in finding a balance point. Zero initialization cannot break symmetry, forcing all neurons to learn the same function and degrading the network to a single neuron. Random initialization breaks symmetry, but improper variance selection leads to two extremes: variance too small causes signal decay layer by layer and slow training; variance too large causes activation saturation and gradient vanishing. Good initialization must find a balance between "breaking symmetry" and "maintaining signal strength."
Initialization is the starting point of training, determining whether the network can get off to a good start. However, the end goal of training is whether it can converge to the optimum. The greatest difficulty encountered here is overfitting. We previously covered the use of L1 and L2 norm regularization to address overfitting in the linear models section. The next chapter will introduce Dropout regularization, which forces the network to learn more robust features by randomly dropping neurons, improving training stability from another perspective.
Exercises
Given a fully-connected layer with input dimension and output dimension , calculate the parameter ranges for Xavier uniform initialization and Xavier normal initialization respectively.
Reference Answer
Xavier Uniform Initialization:
Using the formula , substituting the values:
Therefore, weights are sampled from .
Xavier Normal Initialization:
Using the formula , substituting the values:
Therefore, weights are sampled from , with most weights falling within .
Comparison: The range of uniform initialization is approximately 1.73 times the standard deviation of normal initialization (), which is consistent with the relationship between the uniform distribution variance formula and the normal distribution variance .
Explain why Xavier initialization uses the harmonic mean of and , i.e., , instead of the arithmetic mean . Explain the advantage of the harmonic mean from the perspective of gradient stability.
Reference Answer
Forward propagation requires , while backpropagation requires . When , a compromise is needed.
Harmonic mean:
Arithmetic mean:
The difference: the harmonic mean is more sensitive to smaller values. Let , :
- Harmonic mean:
- Arithmetic mean:
The harmonic mean is approximately of the arithmetic mean, leaning toward the smaller (backpropagation requirement) rather than the larger (forward propagation requirement).
Gradient stability perspective: In the backpropagation gradient norm formula , when is large and is also large, the gradient norm grows exponentially, leading to gradient explosion. The harmonic mean leans toward the smaller variance, effectively suppressing the risk of gradient explosion during backpropagation and prioritizing gradient stability.
Consider a three-layer fully-connected network with dimensions using the ReLU activation function. If Xavier initialization is mistakenly used instead of He initialization, analyze how the signal changes during forward propagation and calculate the factor by which the signal variance changes after three layers.
Reference Answer
Problem of using Xavier initialization for ReLU:
Xavier initialization assumes the activation function is approximately linear, and its derived variance formula does not account for ReLU's signal attenuation. However, ReLU zeroes out approximately half of the activation values, halving the signal variance.
Signal variance change analysis:
Let the first layer weights use Xavier initialization, with , :
After forward propagation (weighted sum):
After ReLU activation: (signal attenuation)
Similar attenuation occurs in the second and third layers, with each layer's signal variance being approximately times the previous layer.
Cumulative effect after three layers:
Rough estimate:
The signal variance decays to approximately 23% of its initial value. The activation values in deep layers tend toward zero, and gradient propagation is hindered.
Correct approach: Use He initialization, where the factor of 2 in the variance formula compensates for ReLU's signal halving, maintaining stable signal strength.
