CS6910 · Deep Learning · IIT Madras

Pre-training, activation functions, initialization and batch norm

Until 2006, deep networks trained with backpropagation rarely converged, and greedy layerwise pre-training was the first fix that worked. This lecture asks why it worked, then follows the levers it pointed to: activation functions that keep gradients alive, weight scales that keep activations spread out from layer to layer, and batch normalization, which enforces that spread directly.

Lecture 7 Instructor Prof. Mitesh M. Khapra About 120 min of video 6 modules

At a glance

  • Training is a game of gradients. Whatever the optimizer, each weight moves by its gradient, and the gradient of a weight is proportional to the input it multiplies, \(h_{i-1}\). Backpropagation was popular from 1986, yet until 2006 deep networks trained with it rarely converged.
  • Hinton and Salakhutdinov (2006) revived the field with greedy layerwise unsupervised pre-training: train each hidden layer, one at a time, to reconstruct its own input, then add the output layer and fine-tune everything on the supervised loss. Later studies found evidence that it helps optimization when capacity is small, acts as a regularizer, and makes results robust to the random initialization.
  • Those studies pointed at four levers: optimizers, regularizers, activation functions and initialization. Sigmoid saturates, is not zero-centred and is costly; tanh fixes only the centring; ReLU is cheap and does not saturate for \(x > 0\), but its units can die. Leaky and parametric ReLU, ELU and maxout keep a gradient flowing, and GELU \(= x\Phi(x)\), Swish \(= x\sigma(\beta x)\) and SiLU \(= x\sigma(x)\) are smooth newer choices.
  • Equal initial weights never break symmetry. Weights that are too small shrink activations toward 0, and weights that are too large saturate them; either way gradients vanish. Since each layer multiplies the variance by \(n\operatorname{Var}(w)\), choose \(n\operatorname{Var}(w) = 1\) (randn/sqrt(fan_in)), and twice that for ReLU.
  • Batch normalization standardizes every pre-activation over the mini-batch, then applies a learnable scale \(\gamma\) and shift \(\beta\). It is differentiable and makes training less sensitive to initialization, but it fails for very small batches, where layer normalization (statistics across the units of one sample) takes over.

The lecture starts by recalling how networks are trained. For a single sigmoid neuron \(f(x) = \sigma(wx)\) with the squared-error loss of Lecture 3, gradient descent repeats

\[ w_{t+1} = w_t - \eta\,\nabla w_t, \qquad \nabla w_t = \frac{\partial \mathcal{L}(w)}{\partial w_t} = (f(x) - y)\, f(x)\,\big(1 - f(x)\big)\, x \]

A wider network, with inputs \(x_1, x_2, x_3\) feeding one sigmoid neuron, changes nothing. Each weight gets its own copy of the rule, \(w_i \leftarrow w_i - \eta\,\nabla w_i\), with \(\nabla w_i = (f(x) - y)\,f(x)(1 - f(x))\,x_i\).

A deeper, thin network chains sigmoid neurons: \(a_i = w_i h_{i-1}\) and \(h_i = \sigma(a_i)\), starting from \(h_0 = x\). The chain rule gives

\[ \frac{\partial \mathcal{L}(w)}{\partial w_1} = \frac{\partial \mathcal{L}(w)}{\partial y}\cdot\frac{\partial y}{\partial a_3}\cdot\frac{\partial a_3}{\partial h_2}\cdot\frac{\partial h_2}{\partial a_2}\cdot\frac{\partial a_2}{\partial h_1}\cdot\frac{\partial h_1}{\partial a_1}\cdot\frac{\partial a_1}{\partial w_1}, \qquad \frac{\partial a_1}{\partial w_1} = h_0 \]

In general \(\nabla w_i = \frac{\partial \mathcal{L}(w)}{\partial y} \cdots h_{i-1}\). The gradient of a weight is proportional to the input \(h_{i-1}\) it multiplies, and the lecture uses this fact again and again. A network that is both deep and wide applies the same chain rule along every path from the weight to the output and adds the paths up, as in backpropagation (Lecture 4).

forward x = h₀ w₁ σ h₁ = σ(a₁) a₁ = w₁h₀ w₂ σ h₂ = σ(a₂) a₂ = w₂h₁ w₃ σ y = σ(a₃) a₃ = w₃h₂ ℒ(w) backward ∇w₁ = h₀ × σ′(a₁) × w₂ × σ′(a₂) × w₃ × σ′(a₃) × ∂ℒ/∂y Each factor sits under the step it comes from. The last one, h₀, is the input that w₁ multiplies.
One factor per step. In the thin network, the gradient for \(w_1\) multiplies the local derivative of every step between \(w_1\) and the loss. Two kinds of factor matter later: the activation derivatives \(\sigma'(a_i)\), which vanish when a unit saturates, and the input \(h_0\) at the end, which makes every weight's gradient proportional to its own input.

Things to remember: training is a game of gradients, played with any gradient-based method from Lecture 5. A gradient measures a parameter's responsibility for the loss, and it is proportional to the input to that parameter.

Why deep networks were hard to train before 2006

Backpropagation is old. It existed before 1986, when Rumelhart and colleagues made it popular for neural networks, and it is still how every network in this course is trained. In principle it trains a network of any depth by chaining gradients. In practice, networks as deep as four or five layers were not trained successfully with it: even after a large number of epochs, training did not converge reliably. Until 2006 it was very hard to train deep networks.

Three things have changed since the 1990s. There is far more data, which a network with many parameters needs. Compute is much faster. And several ideas fell into place that make deep networks trainable at all, which is what this lecture is about. The turning point was a 2006 paper by Hinton and Salakhutdinov, "Reducing the dimensionality of data with neural networks" (Science), which revived the field through unsupervised pre-training.

The 2006 paper introduced the idea with restricted Boltzmann machines (RBMs). The lecture explains it with autoencoders instead. Autoencoders are not otherwise part of this offering of the course, so only the part that is needed is introduced here.

Take a deep network from \(\mathbf{x} \in \mathbb{R}^n\) to an output \(y\), and look only at its first two layers, the input \(\mathbf{x}\) and the first hidden layer \(\mathbf{h}_1\). Cut the network after \(\mathbf{h}_1\) and attach a new output layer whose job is to reproduce the input, \(\hat{\mathbf{x}}\), from \(\mathbf{h}_1\). Train these weights to make the reconstruction good on all \(m\) training inputs:

\[ \min \; \frac{1}{m}\sum_{i=1}^{m}\sum_{j=1}^{n} \big(\hat{x}_{ij} - x_{ij}\big)^2 \]

This objective is unsupervised. It uses only the inputs and never the label \(y\).

Why is a good reconstruction useful? Suppose \(\mathbf{x}\) has 1024 dimensions and \(\mathbf{h}_1\) only 256, and the network rebuilds \(\mathbf{x}\) from \(\mathbf{h}_1\) with zero error. Then \(\mathbf{h}_1\) holds everything that matters in \(\mathbf{x}\). That is plausible because real inputs are redundant: weight, height and BMI (BMI follows from the other two), weight in kilograms and in pounds, salary and income tax. Squeezing the input through a smaller layer and rebuilding it is exactly what an autoencoder does, and under certain conditions it is equivalent to principal component analysis. The weights of layer 1 now compute an abstract representation \(\mathbf{h}_1\) of the input, and learning them only required training a network with one hidden layer. Shallow networks were never the problem.

Now repeat one level up. Fix the weights of layer 1 and compute \(\mathbf{h}_1\) for every training input. Treat these as the new data, add \(\mathbf{h}_2\), and train it to reconstruct \(\mathbf{h}_1\) with the same objective:

\[ \min \; \frac{1}{m}\sum_{i=1}^{m}\sum_{j} \big(\hat{h}_{1_{ij}} - h_{1_{ij}}\big)^2 \]

\(\mathbf{h}_2\) is then an abstract representation of \(\mathbf{h}_1\), and so a deeper abstraction of \(\mathbf{x}\). Continue in the same way up to the last hidden layer, the one just before the output layer.

Finally, return to the original problem. Keep the pre-trained weights, add the output layer with random weights, and train the whole network on the task's supervised objective, \(\min \frac{1}{m}\sum_i \big(y_i - f(\mathbf{x}_i)\big)^2\), with full backpropagation. Every weight is updated, but the hidden layers start from their pre-trained values instead of random ones.

  1. Greedy layerwise pre-training, then fine-tuning
  2. Set \(\mathbf{h}_0 = \mathbf{x}\) for every training input.
  3. For each hidden layer \(k = 1, \dots, L\): keep layers \(1, \dots, k-1\) fixed, and train the weights into \(\mathbf{h}_k\), together with a temporary output layer, to reconstruct \(\mathbf{h}_{k-1}\) from \(\mathbf{h}_k\) with the squared error. Then compute \(\mathbf{h}_k\) for every input.
  4. Remove the temporary reconstruction layers and add the real output layer with random weights.
  5. Fine-tune all the weights on the supervised loss with backpropagation, starting from the pre-trained values.
1 · Pre-train layer 1 reconstruct x from h₁ x h₁ x̂ min Σ ‖x̂ − x‖² over the m inputs no labels y used 2 · Pre-train layer 2 layer 1 fixed; reconstruct h₁ from h₂ x h₁ h₂ ĥ₁ min Σ ‖ĥ₁ − h₁‖² over the m inputs grey: frozen weights 3 · Fine-tune everything add the output layer; supervised loss x h₁ h₂ y new min Σ (y − f(x))² over the m inputs all weights updated by backprop Accent: weights being trained · dashed nodes: temporary reconstruction layer, used only in that step
Pre-train one layer at a time, then fine-tune. Each pre-training step trains a shallow network on an unsupervised reconstruction task, so it never meets the difficulty of training a deep network. Only the last step uses the labels, and it starts from the weights the earlier steps found.

In effect, the weights of the network have been initialized with a greedy unsupervised objective and then fine-tuned with the supervised one. It is greedy because each layer is trained to do well on its own, without regard to the layers above it. With this procedure, networks that had been hard to train could be trained effectively (deep for the time, though shallow by today's standards). Unsupervised pre-training still exists, today mostly in the context of Transformers, with different objectives but a similar idea.

Why does pre-training work better? Two explanations were put forward, and studies in 2009 (Erhan et al.; Larochelle et al.) looked at both. Does pre-training lead to better optimization, or to better regularization?

The questions are different. Optimization concerns the training data only: can the training loss be driven down? Regularization concerns generalization, doing better on test data the model was not trained on. So the first question asks whether, without pre-training, the error could not even be brought to zero on the training set.

\[ \text{minimize}\;\; \mathcal{L}(\theta) = \frac{1}{m}\sum_{i=1}^{m} \big(y_i - f(\mathbf{x}_i)\big)^2 \]

The error surface of a deep network's supervised objective is highly non-convex, with many hills, plateaus and valleys. Even so, deep networks have large capacity. By the universal approximation theorem (Lecture 3), a large enough network can make the error as small as we like. So it should still be easy to land in one of the many zero-error regions.

Larochelle et al. tested this by increasing the capacity of the last layer: many neurons in the layer before the output means many weights in the last layer. With a large-capacity last layer, \(\mathcal{L}(\theta)\) went to 0 even without pre-training. When capacity was small, pre-training helped, so in that case it was helping the optimization itself.

These were empirical experiments, small in scale compared with deep learning today. Their value was the direction they suggested: if optimization is a bottleneck, it is worth looking for better optimization methods as well.

Regularization constrains the weights to certain regions of the parameter space. L1 regularization pushes most weights to 0 (the diamond-shaped region), L2 regularization keeps most weights from taking large values (the circle), and early stopping has a similar effect (Lecture 6).

Pre-training does the same. It constrains the weights to regions where the characteristics of the data are captured well, as measured by the unsupervised objective

\[ \Omega(\theta) = \frac{1}{m}\sum_{i=1}^{m}\sum_{j=1}^{n} \big(x_{ij} - \hat{x}_{ij}\big)^2 \]

Supervised training of \(\mathcal{L}(\theta)\) then starts inside that region, so where the weights end up depends on where pre-training put them. The unsupervised objective works like an additional constraint on the optimization problem: learning is not greedy with respect to the supervised objective alone, and the solution also satisfies the unsupervised one.

Compare the regularized loss of Lecture 6, \(\mathcal{L}(\theta) + \Omega(\theta)\), which minimizes both terms together. Pre-training minimizes the two terms one after the other: first \(\Omega(\theta)\), then \(\mathcal{L}(\theta)\) starting from where \(\Omega\) left the weights. Seen this way, it acts as a regularizer.

Other experiments (Erhan et al., 2009) showed that pre-training makes training more robust to random initialization. Initialize a network at random, train it, and record its final error. Repeat this many times (around 100) with different random initializations and summarize the errors in a box plot. For shallow networks the spread is small. For deep networks without pre-training it is large: the result depends heavily on the particular initialization. With pre-training inserted between the random initialization and the supervised training, the spread stays small even for deep networks.

One accepted hypothesis is therefore that pre-training leads to better weight initializations, from which the layers capture the internal characteristics of the data.

What has happened since 2006–2009

None of these studies gave a conclusive answer, and that was not what mattered. Each lens (optimization, regularization, initialization) suggested a research direction, and deep learning has advanced along all of them:

DirectionWhat it led toWhere
Better optimization algorithmsMomentum, NAG, AdaGrad, RMSProp, Adam and its variantsLecture 5
Better regularization methodsL2, early stopping and others adopted in deep learning; dropout, made for itLecture 6
Better activation functionsReLU and its variants, maxout, GELU, Swish, SiLUModule 7.3
Better weight initializationScaling by the fan-in, the factor of 2 for ReLU, and batch normalizationModules 7.4–7.5

Non-linearity is what makes depth useful

Before comparing activation functions, the lecture asks what makes deep networks powerful. Take a thin deep network and replace every sigmoid by the identity, so that \(h_i = a_i\). Then

\[ y = w_4\,\big(w_3\,\big(w_2\,(w_1 x)\big)\big) = (w_4 w_3 w_2 w_1)\,x \]

which is a single linear transformation of \(x\), however many layers there are. (With vectors and matrices the product \(W_4W_3W_2W_1\) is still a single matrix.) Such a network can only learn linear decision boundaries. If one class of points surrounds the other, no line or hyperplane separates them without a large error, and a deep linear network cannot learn the boundary. A deep non-linear network can, as the universal approximation theorem says (Lecture 3).

The power of deep networks comes from the non-linearities, and the non-linearities come from the activation functions. That is why it pays to ask which non-linear functions train well. Much of the material that follows is based on Andrej Karpathy's lecture notes.

\[ \sigma(x) = \frac{1}{1 + e^{-x}}, \qquad \frac{\partial \sigma(x)}{\partial x} = \sigma(x)\,\big(1 - \sigma(x)\big) \]

The sigmoid compresses every input into the range \([0, 1]\). Training is about gradients, so look at its derivative. In a deep sigmoid network, the chain rule for \(\nabla w_2\) passes through the later layers and meets factors such as

\[ \frac{\partial h_3}{\partial a_3} = \frac{\partial \sigma(a_3)}{\partial a_3} = \sigma(a_3)\,\big(1 - \sigma(a_3)\big), \qquad a_3 = w_3 h_2, \quad h_3 = \sigma(a_3) \]

Problem 1: saturated neurons make the gradient vanish

A sigmoid neuron is saturated when its output sits at an extreme, \(\sigma(x) = 0\) or \(\sigma(x) = 1\). There the derivative \(\sigma(1 - \sigma)\) is 0, as the formula or the flat ends of the curve show. Any gradient that has to pass through a saturated neuron vanishes, so the weights before it stop learning. A neuron saturated at 1 is one whose weights contributed strongly to the output, yet that signal never gets back to them.

Why would a neuron saturate? Its output is \(\sigma\big(\sum_{i=1}^{n} w_i x_i\big)\). Inputs are usually standardized, so they are small. If the weights are initialized to large values, the sum is large and the neuron saturates almost at once; large negative weights saturate it at 0. Small weights do not settle the matter either. With a thousand inputs, a sum of a thousand small terms easily reaches 2 or 3, and already \(\sigma(2.5) \approx 0.92\) with \(\sigma'(2.5) \approx 0.07\), against a peak of \(0.25\) at \(x = 0\). The weights must be initialized carefully, which is the topic of Module 7.4.

Problem 2: the outputs are not zero-centred

The sigmoid's outputs lie in \([0, 1]\), centred around 0.5 instead of 0. Take a sigmoid neuron with pre-activation \(a_3 = w_1 h_{21} + w_2 h_{22}\), where \(h_{21}, h_{22}\) come from sigmoid neurons in the previous layer, \(h_3 = \sigma(a_3)\), and output \(y\). Its two weight gradients are

\[ \nabla w_1 = \underbrace{\frac{\partial \mathcal{L}(w)}{\partial y}\,\frac{\partial y}{\partial h_3}\,\frac{\partial h_3}{\partial a_3}}_{\text{common to both}}\; h_{21}, \qquad \nabla w_2 = \underbrace{\frac{\partial \mathcal{L}(w)}{\partial y}\,\frac{\partial y}{\partial h_3}\,\frac{\partial h_3}{\partial a_3}}_{\text{common to both}}\; h_{22} \]

\(h_{21}\) and \(h_{22}\) are sigmoid outputs, so both are positive. The sign of each gradient is therefore the sign of the common factor. If it is positive, both gradients are positive; if it is negative, both are negative. The argument is the same for \(n\) inputs, so all the gradients of the weights feeding a neuron share one sign.

That restricts the directions in which the weights can move. In the plane of \((\nabla w_1, \nabla w_2)\), only the quadrant where both are positive and the quadrant where both are negative can occur. If the optimum requires increasing \(w_1\) while decreasing \(w_2\), no single step can head straight for it, and gradient descent has to zigzag, taking more steps to converge. It is like driving from A to B when certain kinds of turns are forbidden.

Possible gradient directions ∇w₁ ∇w₂ both +ve allowed both −ve allowed not possible not possible Reaching w* takes a zigzag w₁ w₂ initial w w* (optimum) dashed: direct move, impossible · accent: allowed steps
Why non-zero-centred inputs slow learning. With positive inputs, the gradient for all the weights into a neuron lies in the first or third quadrant, and so does the update \(-\eta\nabla w\). An optimum to the lower right of the start can only be reached by alternating steps that raise both weights and steps that lower both (an illustrative path, after the lecture's toy example).

Problem 3: cost

Finally, sigmoids are computationally expensive, because every evaluation needs \(\exp(x)\).

tanh: zero-centred, still saturating

\[ \tanh(x) = \frac{e^{x} - e^{-x}}{e^{x} + e^{-x}}, \qquad \frac{\partial \tanh(x)}{\partial x} = 1 - \tanh^2(x) \]

tanh compresses its inputs into \([-1, 1]\) and is zero-centred, so the next layer's inputs can be positive or negative and the gradients of a neuron's weights no longer have to share one sign. That removes the restriction on update directions. The other two problems remain. At saturation, \(\tanh(x) = \pm 1\), the derivative \(1 - \tanh^2(x)\) is 0, so gradients still vanish there; the flat ends of the curve show the same thing. It is also still expensive to compute. tanh is not new; it has been in use since the 1990s.

Standard identity, not on the slides: \(\tanh(x) = 2\sigma(2x) - 1\). tanh is a sigmoid stretched to \([-1, 1]\) and recentred at 0, which is why it keeps the sigmoid's flat ends.

ReLU: cheap and non-saturating, but units can die

\[ f(x) = \max(0, x) \]

The rectified linear unit passes a positive pre-activation through unchanged and clamps a negative one to 0. It looks almost linear, so the lecture first asks whether it is non-linear at all. It is, since a linear function would behave the same way on both sides of 0 and ReLU does not. Combining two ReLUs shows what it can do:

\[ f(x) = \max(0, x) - \max(0, x - 6) = \begin{cases} 0 & x \le 0 \\ x & 0 \lt x \lt 6 \\ 6 & x \ge 6 \end{cases} \]

This is a piecewise-linear approximation of a scaled sigmoid, and is called ReLU6, where 6 is its maximum value. Adjusting the pieces brings it even closer to a step.

ReLU has three advantages:

  • It does not saturate in the positive region, since nothing clamps that side. It still has zero gradient for negative inputs, so roughly half of the saturation problem is solved.
  • It is computationally efficient: one comparison and no exponential.
  • In practice it converges much faster than sigmoid or tanh, as Krizhevsky, Sutskever and Hinton found for deep convolutional networks in 2012 (Lecture 8). It has since been used in feedforward, recurrent and Transformer networks too.

The caveat: dead neurons

The derivative of ReLU is 1 for \(x > 0\) and 0 for \(x \lt 0\). Take a ReLU unit \(h_1\) with \(a_1 = w_1x_1 + w_2x_2 + b\), feeding the output through \(w_3\). Suppose that at some point a large gradient updates the bias \(b\) to a large negative value. Then \(w_1x_1 + w_2x_2 + b \lt 0\) for every input, and the unit outputs 0: it is a dead neuron. During backpropagation \(\partial h_1/\partial a_1 = 0\) as well, so

\[ \nabla w_1 = \frac{\partial \mathcal{L}(\theta)}{\partial y}\,\frac{\partial y}{\partial a_2}\,\frac{\partial a_2}{\partial h_1}\,\underbrace{\frac{\partial h_1}{\partial a_1}}_{=\,0}\,\frac{\partial a_1}{\partial w_1} = 0 \]

and likewise \(\nabla w_2 = \nabla b = 0\). None of \(w_1\), \(w_2\), \(b\) changes, so on the next input \(b\) is still very negative and the unit is dead again. Once dead, it stays dead for the rest of training.

A ReLU unit whose bias went very negative x₁ x₂ 1 w₁ w₂ b ≪ 0 ReLU a₁ = w₁x₁ + w₂x₂ + b h₁ = 0 for every input w₃ y gradient ∂h₁/∂a₁ = 0 stops it here so ∇w₁ = ∇w₂ = ∇b = 0: nothing changes, and the unit is dead on the next input too ReLU and its derivative −4 −2 0 2 1 2 highlighted: a₁ for every input both 0 here solid: max(0, a) · dashed: its derivative
A dead ReLU unit. Once a very negative bias puts the pre-activation below 0 for every input, both the output and the local derivative are 0. Every gradient that would reach \(w_1\), \(w_2\) or \(b\) passes through that zero factor, so nothing can move the unit out of the flat region.

In practice a large fraction of ReLU units can die if the learning rate is set too high; the lecture mentions more than half. A high learning rate turns one large gradient into a large jump in \(b\). Two remedies are advised:

  • Initialize the bias to a positive value, such as 0.01.
  • Use a variant of ReLU that lets some gradient through for negative inputs.

Leaky ReLU, parametric ReLU and ELU

Leaky ReLU

\[ f(x) = \max(0.1x,\, x), \qquad f'(x) = \begin{cases} 1 & x > 0 \\ 0.1 & x \lt 0 \end{cases} \]

Leaky ReLU lets a little through on the negative side. It does not saturate, and its units do not die, because the \(0.1x\) term always passes a small gradient. It is as cheap to compute as ReLU, and since its outputs can now be negative, they are close to zero-centred.

Parametric ReLU

\[ f(x) = \max(\alpha x,\, x) \]

Why fix the slope at 0.1? Parametric ReLU makes \(\alpha\) a parameter of the model, learnt along with everything else. Start with, say, \(\alpha = 0.1\), compute \(\partial\mathcal{L}/\partial\alpha\) during backpropagation, and update \(\alpha \leftarrow \alpha - \eta\,\partial\mathcal{L}/\partial\alpha\) (or with any other update rule). For \(\alpha \lt 1\) the local derivative is \(\partial f/\partial\alpha = x\) when \(x \lt 0\) and 0 otherwise. The slope can then adjust as training goes on.

Exponential linear unit (ELU)

\[ f(x) = \begin{cases} x & x > 0 \\ \alpha\,(e^{x} - 1) & x \le 0 \end{cases}, \qquad f'(x) = \begin{cases} 1 & x > 0 \\ \alpha\,e^{x} & x \le 0 \end{cases} \]

ELU keeps the linear positive side and decays exponentially toward \(-\alpha\) on the negative side. It has all the benefits of ReLU, a small gradient \(\alpha e^{x}\) always flows for negative inputs, and its outputs are close to zero-centred. The price is the exponential, which makes it more expensive.

The slide writes the negative branch as \(ae^x - 1\). The usual ELU is \(\alpha(e^{x} - 1)\), which is 0 at \(x = 0\) and so joins the positive branch without a jump.

Each of these variants was proposed in some setting and found better than ReLU there, some with a theoretical argument. In practice none became very popular. The default ReLU usually works, or one of the newer functions below, GELU and Swish.

Maxout is motivated by comparing dropout with model averaging (Lecture 6). In bagging, \(k\) training sets are built from the original one by sampling with replacement, each of the same size as the original, so each contains duplicates. One model is trained on each set. A model sees its duplicated samples again and again and so overfits to its own bucket of data. At inference the \(k\) predictions are combined, for example by an arithmetic or geometric mean, a max, or a vote.

Dropout imitates model averaging inside one network whose sub-networks share weights. There are exponentially many sub-networks and each is sampled rarely, so none of them gets the chance a bagged model has to specialize on particular samples. Simply raising the learning rate would make bigger updates whenever a sample is seen, but the parameters are shared, so it would disturb the other sub-networks too. Dropout's averaging at inference, scaling each unit by the probability \(p\) that it was on, also treats every unit as equally responsive to every input.

Maxout tries to close this gap. Suppose two ReLU units in a layer are both active on an input, with \(0 \lt a_{21} \lt a_{22}\). The second responds more strongly and is more sensitive to this input, so let it be the one that learns from it. Output the larger of the two:

\[ h_{21} = \max(a_{21}, a_{22}) = a_{22}, \qquad \frac{\partial h_{21}}{\partial a_{21}} = 0, \qquad \frac{\partial h_{21}}{\partial a_{22}} = 1 \]

The gradient now flows only to the stronger unit, which specializes on inputs like this one while the weaker unit is left alone. Different pieces come to specialize on different inputs, much as bagged models specialize on their buckets. Under dropout, every unit that survives the mask gets gradient, whether it responded strongly or weakly. Under maxout, only the strongest piece in each maxout unit stays active, and the weaker pieces are effectively dropped as well.

Maxout neuron \[ h = \max\big(\mathbf{w}_1^\top\mathbf{x} + b_1,\; \mathbf{w}_2^\top\mathbf{x} + b_2,\; \dots,\; \mathbf{w}_k^\top\mathbf{x} + b_k\big) \]

The maximum of \(k\) affine functions of the same input. On any given input only the winning piece receives gradient.

One maxout unit, three pieces x w₁ᵀx + b₁ = 0.8 w₂ᵀx + b₂ = 1.9 w₃ᵀx + b₃ = −0.4 max h = 1.9 0 1 0 Backward: ∂h/∂(piece) is 1 for the winner, 0 for the rest, so the other pieces are dropped for this input. max(0.5x, −0.5x) −2 2 1 0.5|x|: a V shape max(0.5x, −0.5x, x, −x − 0.2) −2 2 1 x² a convex bowl, roughly x² dashed: the affine pieces · accent: their maximum
Maxout, inside and out. Left: one maxout unit with three affine pieces (illustrative values); the max passes on the largest, and only that piece's weights are updated. Right: the lecture's two examples, drawn to scale on \(-2 \le x \le 2\). Two pieces give a V; four pieces give a convex bowl, a rough piecewise-linear stand-in for \(x^2\) (dotted).

Maxout generalizes ReLU and its variants. ReLU is a maxout unit with two pieces, \(\max(0\cdot x + 0,\; 1\cdot x + 0)\). Leaky ReLU is \(\max(0.1x,\, x)\) and parametric ReLU is \(\max(\alpha x,\, x)\). More pieces give more non-linearity: \(\max(0.5x, -0.5x) = 0.5|x|\) is a V shape, and the four pieces \(\max(0.5x,\, -0.5x,\, x,\, -x - 0.2)\) give a bowl that the lecture uses to approximate \(x^2\).

  • No saturation and no death. The gradient always flows through the winning piece.
  • Cost. \(k\) affine pieces per neuron mean \(k\) times as many parameters.
  • Power. Two maxout neurons with a sufficient number of affine pieces act as a universal approximator.

Standard detail (Goodfellow et al., 2013): the universal-approximation construction takes the difference of the two maxout units. Each unit is a convex piecewise-linear function, and any continuous function can be approximated by a difference of two such functions.

Despite all this, maxout never became very popular; its special cases, ReLU and the variants, are used far more. It is still worth knowing for the link to dropout, the way it generalizes ReLU, and the fact that two such units can approximate any function.

The Gaussian error linear unit starts from a similarity. The hard threshold and ReLU both decide their output by the sign of the input:

\[ \text{threshold: } f(x) = \begin{cases} 1 & x > 0 \\ 0 & x \le 0 \end{cases} \qquad\qquad \text{ReLU: } f(x) = \begin{cases} 1\cdot x & x > 0 \\ 0\cdot x & x \le 0 \end{cases} \]

Written this way, ReLU multiplies its input by 1 or by 0. Dropout (Lecture 6) also multiplies a unit's value by 1 or 0, with one difference: it chooses at random, \(\mu(x) = 1\cdot x\) with probability \(p\) and \(0\cdot x\) with probability \(1 - p\) (a slight abuse of notation). GELU combines the two properties in one activation: a random 0/1 multiplier whose probability depends on the input.

\[ f(x) = m\cdot x, \qquad m \sim \text{Bernoulli}\big(\Phi(x)\big) \]

Here \(x\) is the neuron's pre-activation. \(\Phi(x)\) is a probability, so it must satisfy \(0 \le \Phi(x) \le 1\). The logistic function would do, but the more natural choice is the cumulative distribution function of the standard normal distribution, \(\Phi(x) = P(X \le x)\) for \(X \sim \mathcal{N}(0, 1)\). It is also S-shaped, close to 0 for very negative \(x\) and close to 1 for very positive \(x\). A large positive pre-activation is then almost always kept, and a large negative one almost always zeroed.

The activation used is the expected value of this random unit:

\[ \mathbb{E}[f(x)] = \mathbb{E}[m\cdot x] = \Phi(x)\cdot 1\cdot x + \big(1 - \Phi(x)\big)\cdot 0\cdot x = x\,\Phi(x) = x\,P(X \le x) \]
GELU and its approximations \[ \operatorname{GELU}(x) = x\,\Phi(x) \;\approx\; 0.5\,x\left(1 + \tanh\!\Big[\sqrt{2/\pi}\,\big(x + 0.044715\,x^3\big)\Big]\right) \;\approx\; x\,\sigma(1.702\,x) \]

\(\Phi\) is usually computed with the error function, \(\Phi(x) = \tfrac12\big[1 + \operatorname{erf}(x/\sqrt2)\big]\); the two approximations avoid it.

A quick check, with numbers computed for these notes: \(\Phi(1) \approx 0.841\), so \(\operatorname{GELU}(1) \approx 0.841\) and \(\operatorname{GELU}(-1) = -\Phi(-1) \approx -0.159\). The sigmoid approximation gives 0.846 and \(-0.154\). On its own, \(x\sigma(1.702x)\) looks like an arbitrary formula; the derivation shows it weights the input by the probability that a standard normal value falls below it. GELU is the most common activation in Transformer-based architectures such as BERT and GPT (Lecture 14).

SELU, searched activations, Swish and SiLU

SELU: self-normalizing

It helps if each layer's output activations have zero mean and unit variance. That can be done explicitly with normalization techniques (batch normalization, Module 7.5). The scaled exponential linear unit instead builds it into the activation function, which is called self-normalizing:

\[ f(x) = \lambda \begin{cases} x & x > 0 \\ \alpha e^{x} - \alpha & x \le 0 \end{cases}, \qquad \lambda \approx 1.0507, \quad \alpha \approx 1.6733 \]

ReLU is clearly not zero-centred: it can take large values on the positive side and only 0 on the negative side. ELU has some negative values, so it is somewhat more balanced, and so is GELU. Scaling ELU by a suitable \(\lambda\), with a matching \(\alpha\), balances the two sides and gives near zero-centring.

The slide labels both constants \(\lambda\); the second one, 1.673263, is \(\alpha\). On the negative side SELU flattens at \(-\lambda\alpha \approx -1.76\).

Searching for activation functions

Rather than keep inventing activation functions by hand, one can search for them automatically. Assume a search space of scalar functions, each composed of two kinds of operation:

  • Unary operations take one input: \(|x|\), \(-x\), \(\exp(-x)\), \(\sqrt{x}\), and so on.
  • Binary operations take two: \(\max(x_1, x_2)\), \(x_1\cdot\sigma(x_2)\), and so on.

The sigmoid, tanh, ReLU, leaky ReLU and \(x\sigma(1.702x)\) all live in this space. Restrict the space, try combinations, and keep those that most improve the accuracy of existing models. The search itself uses reinforcement learning, which is beyond this course. Several good functions came out of it, one of them resembling the ELU and GELU family. The best had the form

Swish \[ f(x) = x\,\sigma(\beta x) \]

\(\beta\) can be a constant, as in the GELU approximation with \(\beta = 1.702\), or a learnable parameter.

SiLU

The family now has three names. \(x\sigma(1.702x)\) is (approximately) GELU, \(x\sigma(\beta x)\) is Swish, and the case \(\beta = 1\),

\[ \operatorname{SiLU}(x) = x\,\sigma(x) \]

is the sigmoid-weighted linear unit: a linear unit \(x\), weighted by a sigmoid. It was first proposed in reinforcement learning.

Not in the lecture: the two extremes of Swish make the family easy to picture. With \(\beta = 0\) it is the straight line \(x/2\). As \(\beta\) grows, \(\sigma(\beta x)\) approaches a step and \(x\sigma(\beta x)\) approaches ReLU. Both are easy to see in the explorer below.

Comparing them, and which to use

The explorer plots each function the lecture covers together with its derivative. Move the probe to the flat ends of the sigmoid and tanh, to the negative side of ReLU and its variants, and compare GELU with its sigmoid approximation.

2.50
–
f(x)–
f′(x)–
Output range–
Activation explorer. Solid: \(f(x)\); dashed: \(f'(x)\), on the same axes at equal scale. The parameter slider sets the leak \(\alpha\) (with \(\alpha = 0\) leaky ReLU becomes ReLU), ELU's \(\alpha\), the number of the lecture's maxout pieces \(0.5x, -0.5x, x, -x - 0.2\) (dotted lines), or Swish's \(\beta\) (\(\beta = 1\) is SiLU, \(\beta = 1.702\) the GELU approximation). For GELU, the extra dashed curve is \(x\sigma(1.702x)\). The derivatives of GELU and Swish were worked out for these notes.
Activationf(x)f′(x)What the lecture says
Sigmoid\(\frac{1}{1 + e^{-x}}\)\(\sigma(x)(1 - \sigma(x)) \le 0.25\)Saturates at both ends; not zero-centred; exp is costly
tanh\(\tanh x\)\(1 - \tanh^2 x\)Zero-centred; still saturates; still costly
ReLU\(\max(0, x)\)1 for \(x > 0\), 0 for \(x \lt 0\)No saturation for \(x > 0\); cheap; converges much faster; units can die
Leaky ReLU\(\max(0.1x, x)\)1, or 0.1No saturation; never dies; cheap; close to zero-centred
Parametric ReLU\(\max(\alpha x, x)\)1, or \(\alpha\)The slope \(\alpha\) is learnt by backpropagation
ELU\(x\), or \(\alpha(e^x - 1)\)1, or \(\alpha e^x\)ReLU's benefits; gradient for \(x \lt 0\); close to zero-centred; exp is costly
SELU\(\lambda\,\)ELU, \(\alpha \approx 1.6733\)\(\lambda\), or \(\lambda\alpha e^x\)Self-normalizing; \(\lambda \approx 1.0507\) balances the two sides
Maxout\(\max_j\big(\mathbf{w}_j^\top\mathbf{x} + b_j\big)\)1 for the winning piece, 0 for the restNo saturation, no death; generalizes ReLU; \(k\) times the parameters
GELU\(x\Phi(x) \approx x\sigma(1.702x)\)\(\Phi(x) + x\,\varphi(x)\)Expected value of a random 0/1 gate; standard in BERT and GPT
Swish / SiLU\(x\sigma(\beta x)\); SiLU: \(\beta = 1\)\(\sigma(\beta x)\big[1 + \beta x\,(1 - \sigma(\beta x))\big]\)Found by automatic search; \(\beta\) fixed or learnt

\(\varphi\) is the standard normal density. The GELU and Swish derivatives come from the product rule and are not on the slides.

Which one should you use? A plot from Papers with Code on the slides shows how the use of these functions has changed over time. ReLU has stayed popular for more than a decade. GELU became popular with Transformers, the setting where it is now the usual choice. Sigmoid and tanh, despite their drawbacks, are still used where their ranges are needed: the sigmoid wherever a value must lie between 0 and 1, as in some attention functions, and tanh in LSTMs and RNNs.

Things to remember: sigmoids are bad as hidden activations. ReLU is more or less the standard unit for convolutional networks, and Leaky ReLU, maxout and ELU are worth exploring. tanh and sigmoid are still used in LSTMs and RNNs (Lecture 12). GELU is the most common choice in Transformer models such as BERT and GPT (Lecture 14).

Equal initial weights: the symmetry problem

The module videos end with the activation functions. Modules 7.4 and 7.5 are written from the slides alone.

For learning to happen, gradients must flow from the output layer back to the input layer. Saturated neurons block that flow, because a weight's gradient carries the factor \(\sigma(x)(1 - \sigma(x))\):

\[ \nabla w = \big(f(x) - y\big)\,\sigma(x)\,\big(1 - \sigma(x)\big)\cdot \text{input} \]

The way to keep neurons out of saturation is to initialize the parameters carefully. The right initialization depends on the number of inputs to a layer, \(\text{fan}_\text{in}\), the number of outputs, \(\text{fan}_\text{out}\), the type of activation function and the type of architecture.

Start with the simplest choice, all weights 0. In a network with inputs \(x_1, x_2\), three sigmoid units in layer 1 and one unit in layer 2,

\[ a_{11} = w_{11}x_1 + w_{12}x_2 = 0, \qquad a_{12} = w_{21}x_1 + w_{22}x_2 = 0 \qquad\Rightarrow\qquad h_{11} = h_{12} \]

so every unit in layer 1 gets the same activation (here \(\sigma(0) = 0.5\)). Backpropagation then gives

\[ \nabla w_{11} = \frac{\partial \mathcal{L}(w)}{\partial y}\cdot\frac{\partial y}{\partial h_{11}}\cdot\frac{\partial h_{11}}{\partial a_{11}}\cdot x_1, \qquad \nabla w_{21} = \frac{\partial \mathcal{L}(w)}{\partial y}\cdot\frac{\partial y}{\partial h_{12}}\cdot\frac{\partial h_{12}}{\partial a_{12}}\cdot x_1 \]

Since \(h_{11} = h_{12}\) and \(a_{11} = a_{12}\), and the two units' outgoing weights are equal as well, every factor matches and \(\nabla w_{11} = \nabla w_{21}\). Both weights get the same update and remain equal. The same is true for \(w_{12}\) and \(w_{22}\), and for all the weights in layer 2 (work through the maths to convince yourself). The symmetry never breaks during training: the units of a layer stay copies of one another and the layer behaves like a single unit. This is the symmetry breaking problem. It happens whenever all the weights in a network are initialized to the same value, 0 or any other.

Every weight starts at 0 x₁ x₂ 0.5 0.5 0.5 h₁₁ h₁₂ h₁₃ σ h₂₁ y all weights 0, so every hidden unit outputs σ(0) = 0.5 Forward a₁₁ = a₁₂ = a₁₃ = 0 ⇒ h₁₁ = h₁₂ = h₁₃ Backward ∇w₁₁ = ∂ℒ/∂y · ∂y/∂h₁₁ · ∂h₁₁/∂a₁₁ · x₁ ∇w₂₁ = ∂ℒ/∂y · ∂y/∂h₁₂ · ∂h₁₂/∂a₁₂ · x₁ every factor matches ⇒ ∇w₁₁ = ∇w₂₁ After the update w₁₁ = w₂₁ still: the units stay copies
Equal weights stay equal. With every weight at 0, all three hidden units compute the same value for every input, receive the same gradient and make the same update. Nothing in training can ever make them differ, so the initial weights must be different from each other, which in practice means random.

Random, but how large? Too small and too large

So the weights must be random. The slides test different scales with a forward pass through a synthetic network:

  • Input: 1000 points, each in \(\mathbb{R}^{500}\), drawn from a unit Gaussian.
  • The network has 5 layers of 500 neurons each.
  • Run only forward propagation and look at each layer's activations under different weight initializations.
num_layers = 5
D = np.random.randn(1000, 500)
for i in range(num_layers):
    x = D if i == 0 else h_cache[i-1]
    W = 0.01*np.random.randn(500, 500)
    a = np.dot(x, W)
    h = sigmoid(a)          # the slides also try tanh

Small random weights: W = 0.01*np.random.randn(500,500)

The slides look at the activations layer by layer, with sigmoid and with tanh. With tanh, they shrink toward 0 as the depth grows. With sigmoid, they bunch ever more tightly around \(\sigma(0) = 0.5\). The explorer at the end of this module reproduces both. Now think about backpropagation. A weight's gradient is proportional to the activation passing through it, so if all the activations of a layer are very close to 0, the gradients of the weights connecting that layer to the next are all close to 0 as well. This is the vanishing gradient problem.

The slides then check real data. Data: MNIST, \(\mathbf{x} \in \mathbb{R}^{784}\). Model: a feedforward network with three hidden layers, \(\mathbf{h}_1, \mathbf{h}_2, \mathbf{h}_3 \in \mathbb{R}^{500}\), and tanh activations. Loss: cross-entropy. Optimizer: mini-batch gradient descent with \(\eta = 0.5\) and batch size 256. With W = 0.01*np.random.randn(500,500), the loss stays almost constant for the first 35 iterations.

Large random weights: W = np.random.randn(500,500)

Now most activations saturate, at 0 or 1 for the sigmoid and at \(\pm 1\) for tanh. At saturation the local gradients are close to 0, so the gradients vanish again. The video makes the same point from the other direction M4 · 11:18: with a thousand inputs, even modest weights give sums large enough to saturate a sigmoid. The slides rerun the MNIST experiment with this initialization as well.

A principled scale: keep \(n\operatorname{Var}(w) = 1\)

Look at the first pre-activation of layer 1, \(s_{11} = \sum_{i=1}^{n} w_{1i}x_i\), and treat the weights and inputs as independent random variables. For independent \(w\) and \(x\),

\[ \operatorname{Var}(wx) = (\mathbb{E}[w])^2\operatorname{Var}(x) + (\mathbb{E}[x])^2\operatorname{Var}(w) + \operatorname{Var}(x)\operatorname{Var}(w) \]

so

\[ \begin{aligned} \operatorname{Var}(s_{11}) &= \operatorname{Var}\Big(\sum_{i=1}^{n} w_{1i}x_i\Big) = \sum_{i=1}^{n}\operatorname{Var}(w_{1i}x_i) \\ &= \sum_{i=1}^{n}\Big[(\mathbb{E}[w_{1i}])^2\operatorname{Var}(x_i) + (\mathbb{E}[x_i])^2\operatorname{Var}(w_{1i}) + \operatorname{Var}(x_i)\operatorname{Var}(w_{1i})\Big] \\ &= \sum_{i=1}^{n}\operatorname{Var}(x_i)\operatorname{Var}(w_{1i}) \qquad \text{[zero-mean inputs and weights]} \\ &= n\operatorname{Var}(w)\operatorname{Var}(x) \qquad \text{[}\operatorname{Var}(x_i) = \operatorname{Var}(x),\ \operatorname{Var}(w_{1i}) = \operatorname{Var}(w)\ \forall i\text{]} \end{aligned} \]

The same holds for every unit of the layer: \(\operatorname{Var}(s_{1i}) = n\operatorname{Var}(w)\operatorname{Var}(x)\). If \(n\operatorname{Var}(w) \gg 1\), the pre-activations have a large variance and the units saturate. If \(n\operatorname{Var}(w) \to 0\), the variance is small and the activations collapse.

Add one more layer. The same procedure, with the \(s_{1i}\) as the inputs, gives

\[ \operatorname{Var}(s_{21}) = \sum_{i=1}^{n}\operatorname{Var}(s_{1i})\operatorname{Var}(w_{2i}) = n\operatorname{Var}(s_{1i})\operatorname{Var}(w_2) \;\propto\; [n\operatorname{Var}(w_2)]\,[n\operatorname{Var}(w_1)]\operatorname{Var}(x) \;\propto\; [n\operatorname{Var}(w)]^2\operatorname{Var}(x) \]

assuming that the weights in all layers have the same variance. (Passing the \(s_{1i}\) straight to the next layer treats the activation as roughly linear, which is how tanh behaves near 0.)

Variance after k layers \[ \operatorname{Var}(s_{ki}) = [n\operatorname{Var}(w)]^{k}\operatorname{Var}(x) \qquad\Rightarrow\qquad \text{choose } n\operatorname{Var}(w) = 1 \]

To make it so, draw \(z\) from a unit Gaussian and scale it by \(1/\sqrt{n}\). Using \(\operatorname{Var}(az) = a^2\operatorname{Var}(z)\): \(n\operatorname{Var}\big(z/\sqrt{n}\big) = n\cdot\tfrac{1}{n}\operatorname{Var}(z) = 1\).

W = np.random.randn(fan_in, fan_out) / np.sqrt(fan_in)

The slides rerun the synthetic network with this initialization, for tanh and for sigmoid, and the MNIST experiment with W = np.random.randn(500,500)/sqrt(fan_in). In the explorer below, the activations now keep a usable spread through all the layers. With \(n = 500\), the three initializations so far compare as follows (numbers worked out for these notes):

InitializationVar(w)n·Var(w)Variance factor after 5 layers
0.01*randn10⁻⁴0.050.05⁵ ≈ 3.1 × 10⁻⁷
randn1500500⁵ ≈ 3.1 × 10¹³
randn/sqrt(fan_in)1/50011

Standard name: scaling by \(1/\sqrt{\text{fan}_\text{in}}\) is often called LeCun or Xavier initialization. The Xavier rule of Glorot and Bengio (2010) balances the forward and backward passes with \(\operatorname{Var}(w) = 2/(\text{fan}_\text{in} + \text{fan}_\text{out})\), which equals \(1/n\) when the two are equal.

ReLU needs a factor of 2

The \(1/\sqrt{\text{fan}_\text{in}}\) rule does not work for ReLU neurons. He et al. argue that a factor of 2 is needed. Intuitively, the output of a ReLU is restricted to the positive half of the space: it zeroes roughly half of what passes through it, so the variance reaching the next layer is roughly halved at every layer. The slides show this on a deeper ReLU network, with \(\mathbf{h}_1 \in \mathbb{R}^{100}\) and \(\mathbf{h}_2, \dots, \mathbf{h}_7 \in \mathbb{R}^{50}\), at the layers \(\mathbf{h}_1\), \(\mathbf{h}_4\) and \(\mathbf{h}_7\). Accounting for the factor of 2 gives better performance:

W = np.random.randn(fan_in, fan_out) / np.sqrt(fan_in/2)

Not in the lecture, the short reason for the 2: if \(s\) is symmetric about 0, then \(h = \max(0, s)\) has \(\mathbb{E}[h^2] = \tfrac12\operatorname{Var}(s)\). With zero-mean weights, the next pre-activation has variance \(n\operatorname{Var}(w)\,\mathbb{E}[h^2] = \tfrac12\,n\operatorname{Var}(w)\operatorname{Var}(s)\), which stays constant only if \(n\operatorname{Var}(w) = 2\), that is \(\operatorname{Var}(w) = 2/\text{fan}_\text{in}\).

Activation
W =
5
n·Var(w)–
Std, layer 1–
Std, last layer–
Std change per layer–
Saturated, last layer–
Synthetic forward pass, with data generated for these notes from a seeded random generator: 100 inputs in \(\mathbb{R}^{500}\) from a unit Gaussian, pushed through layers of 500 units without biases (the slides use 1000 inputs). Each panel is the histogram of one layer's activations, scaled to its own tallest bar. Every option reuses the same random matrices, so only the weight scale changes. For ReLU, exact zeros (about half the units) are left out of the histogram and a highlighted bar at the right edge collects values of 3 or more. Batch norm standardizes each unit's pre-activation over the 100 inputs before the activation (\(\gamma = 1\), \(\beta = 0\)).

Batch normalization: standardize every pre-activation

Batch normalization is a method that allows us to be less careful about initialization.

Consider a deep network and focus on learning the weights between two of its layers, say from \(\mathbf{h}_3\) to \(\mathbf{h}_4\). Training uses mini-batches. If the distribution of \(\mathbf{h}_3\) keeps changing from one mini-batch to the next, these weights keep chasing a moving target, and learning them is hard. It would help if the pre-activations at each layer were unit Gaussians. Batch normalization ensures this explicitly by standardizing each pre-activation, for sample \(i\) and unit \(k\):

\[ \hat{s}_{ik} = \frac{s_{ik} - \mathbb{E}[s_{ik}]}{\sqrt{\operatorname{Var}(s_{ik})}} \]

The mean and variance are computed from the mini-batch. This explicitly keeps the distribution of the inputs to each layer from changing across batches.

Standard name: Ioffe and Szegedy (2015), who introduced batch normalization, called this changing distribution internal covariate shift.

The network now has a BN step before each non-linearity: linear, BN, tanh, linear, BN, tanh, and so on. Is that legal? Yes. Like the tanh layer, the batch normalization layer is differentiable, so backpropagation passes through it.

A learnable scale and shift, and the batch statistics

Is a unit Gaussian necessarily the best input for the tanh layer? Perhaps not, so let the network learn what is best for it. After the standardization, BN adds one more step:

\[ y^{(k)} = \gamma^{(k)}\,\hat{s}_{ik} + \beta^{(k)} \]

\(\gamma^{(k)}\) and \(\beta^{(k)}\) are additional parameters of the network, learnt with all the others. If the network learns \(\gamma^{(k)} = \sqrt{\operatorname{Var}(x^{(k)})}\) and \(\beta^{(k)} = \mathbb{E}[x^{(k)}]\), it recovers the original \(s_{ik}\). By adjusting these two parameters, the network can undo the normalization whenever that is more favourable.

How are the statistics computed? Three indices are involved: the layer \(l\), the neuron \(i\) within that layer, and the training sample \(j\) within the mini-batch; picture them as the three axes of a cube. Associate with layer \(l\) an accumulator that stores the activations for the batch inputs, and let \(x_i^j\) be the activation of the \(i\)-th neuron for the \(j\)-th of the \(m\) training samples. Each neuron is normalized with its own statistics, taken over the batch:

  1. Batch normalization of neuron i in layer l, for one mini-batch of m samples
  2. Mean over the batch: \(\mu_i = \frac{1}{m}\sum_{j=1}^{m} x_i^j\).
  3. Variance over the batch: \(\sigma_i^2 = \frac{1}{m}\sum_{j=1}^{m}\big(x_i^j - \mu_i\big)^2\).
  4. Standardize each sample's activation: \(\hat{x}_i = \dfrac{x_i - \mu_i}{\sqrt{\sigma_i^2 + \epsilon}}\), where \(\epsilon\) is a small constant that avoids division by zero.
  5. Scale and shift: \(\hat{y}_i = \gamma\,\hat{x}_i + \beta\), with \(\gamma\) and \(\beta\) learnt.

The slides then compare a 7-layer network on MNIST with and without batch normalization, using sigmoid activations and w = 0.1*np.random.randn(), and plot the activation distributions at \(\mathbf{h}_1\), \(\mathbf{h}_4\) and \(\mathbf{h}_7\) (blue without BN, red with). To run a comparison of the same kind, tick Batch norm in the explorer of Module 7.4. With BN on, every weight scale gives the same spread at every layer, because standardizing the pre-activations cancels the scale of the weights.

The limits of batch norm, and layer normalization

Batch normalization has limitations:

  • The mean and variance are estimates, and their accuracy depends on the batch size \(m\). For data such as images and videos, memory limits often force small batches, and a small \(m\) gives a large estimation error.
  • A batch size of 1 cannot be used at all. Then \(\mu_i = x_i\) and \(\sigma_i = 0\), so normalization makes no sense: every standardized value is 0.
  • Naive use of BN was also found empirically to degrade performance on NLP tasks. A systematic study confirmed this and proposed a modified BN called PowerNorm.

Alternatives such as group normalization and instance normalization were proposed for particular domains. The simplest one is layer normalization: take the average across the outputs of the \(H\) hidden units of the layer, one sample at a time.

\[ \mu_l = \frac{1}{H}\sum_{i=1}^{H} x_i, \qquad \sigma_l = \sqrt{\frac{1}{H}\sum_{i=1}^{H}\big(x_i - \mu_l\big)^2}, \qquad \hat{x}_i = \frac{x_i - \mu_l}{\sqrt{\sigma_l^2 + \epsilon}}\;\;\forall i, \qquad \hat{y}_i = \gamma\,\hat{x}_i + \beta \]

The statistics no longer involve the other samples in the batch, so layer normalization works even with a batch size of 1, as needed, for example, in RNNs.

Batch norm one neuron, statistics over the m samples neuron i → 1 2 3 … … H 1 2 3 … m sample j μᵢ, σᵢ² from this column needs a batch: with m = 1, σᵢ = 0 Layer norm one sample, statistics over the H units neuron i → 1 2 3 … … H 1 2 3 … m sample j μₗ, σₗ from this row works for any batch size, even 1 Rows: samples j of the mini-batch · columns: neurons i of layer l · each cell is one activation xᵢʲ
Same activations, different statistics. Batch norm normalizes each neuron with the mean and variance of its column, over the samples in the mini-batch. Layer norm normalizes each sample with the mean and spread of its row, over the units of the layer. Only the second can work with a single sample.

Not in this lecture: layer normalization is the "norm" in the Transformer's add-and-norm steps (Lecture 14).

Key terms

Greedy layerwise pre-training
Training one hidden layer at a time, each to reconstruct its own input, before fine-tuning the whole network.
Autoencoder objective
Rebuild the input from a hidden layer with small squared error, so that layer keeps the input's important information.
Fine-tuning
Training the whole pre-trained network on the supervised loss, starting from the pre-trained weights.
Saturated neuron
A sigmoid or tanh unit at an end of its range, where its derivative, and every gradient through it, is about 0.
Zero-centred output
Outputs spread around 0. The sigmoid's are all positive, which forces a neuron's weight gradients to share one sign.
Dead ReLU
A ReLU unit whose pre-activation is negative for every input: it outputs 0, gets zero gradient, and never recovers.
Leaky and parametric ReLU
\(\max(\alpha x, x)\), with \(\alpha = 0.1\) fixed or \(\alpha\) learnt, so a gradient always flows.
ELU and SELU
\(x\) for \(x > 0\) and \(\alpha(e^x - 1)\) below; SELU scales this by \(\lambda \approx 1.0507\), with \(\alpha \approx 1.6733\), to self-normalize.
Maxout
The maximum of \(k\) affine functions of the input; only the winning piece receives gradient.
GELU
\(x\Phi(x)\), the expected value of \(m\cdot x\) with \(m \sim \text{Bernoulli}(\Phi(x))\); about \(x\sigma(1.702x)\).
Swish and SiLU
\(x\sigma(\beta x)\), found by automatic search; SiLU is the case \(\beta = 1\).
Symmetry breaking problem
Equal initial weights give equal activations and equal gradients, so the units of a layer stay identical forever.
Fan-in scaling
\(\operatorname{Var}(w) = 1/\text{fan}_\text{in}\) keeps \(n\operatorname{Var}(w) = 1\) and the variance steady across layers; ReLU needs \(2/\text{fan}_\text{in}\).
Batch and layer normalization
Standardize pre-activations, then apply a learnt \(\gamma\) and \(\beta\). BN takes statistics per unit over the batch; LN per sample over the layer's units.

Test yourself

Q1A deep network uses the identity as its activation: \(y = w_4(w_3(w_2(w_1x)))\). Why can it learn nothing that a single linear layer cannot?

The composition is \((w_4w_3w_2w_1)\,x\), one linear map with weight \(w_4w_3w_2w_1\); with matrices, \(W_4W_3W_2W_1\) is still one matrix. Its decision boundaries stay linear, so for example one class surrounding another can never be separated. Non-linear activations are what stop the layers from collapsing into one.

Q2Compute \(\sigma'(0)\) and \(\sigma'(4)\). If a gradient passes through five sigmoid units in a chain, how large can the product of their local derivatives be?

\(\sigma(0) = 0.5\), so \(\sigma'(0) = 0.5 \times 0.5 = 0.25\), the largest value it can take. \(\sigma(4) \approx 0.982\), so \(\sigma'(4) \approx 0.982 \times 0.018 \approx 0.018\), about 7% of the peak. Through five units the product is at most \(0.25^5 \approx 0.001\), and far less if any unit is near saturation (the weights in the chain multiply in as well).

Q3A sigmoid unit receives \(h_{21} = 0.3\) and \(h_{22} = 0.8\) from sigmoid units, and the common factor \(\frac{\partial\mathcal{L}}{\partial y}\frac{\partial y}{\partial h_3}\frac{\partial h_3}{\partial a_3}\) is \(-0.5\). Find \(\nabla w_1\) and \(\nabla w_2\). Can this step increase \(w_1\) and decrease \(w_2\)?

\(\nabla w_1 = -0.5 \times 0.3 = -0.15\) and \(\nabla w_2 = -0.5 \times 0.8 = -0.40\). Both are negative, so the update \(-\eta\nabla w\) increases both weights. No step can move them in opposite directions, because the inputs are positive and the common factor fixes the sign of both gradients.

Q4A ReLU unit has \(a = w_1x_1 + w_2x_2 + b\) with inputs in \([0, 1]\), \(w_1 = 0.5\), \(w_2 = -0.3\) and \(b = -2\). Is it alive? What changes with leaky ReLU?

The largest possible pre-activation is \(0.5 \times 1 - 0.3 \times 0 - 2 = -1.5 \lt 0\), so \(a \lt 0\) for every input and the unit is dead. Its local derivative is 0, so \(\nabla w_1 = \nabla w_2 = \nabla b = 0\) and it never recovers. With leaky ReLU (slope 0.1), \(\partial h/\partial a = 0.1\) for \(a \lt 0\), so \(\nabla b = 0.1\,\delta\) and \(\nabla w_1 = 0.1\,\delta\,x_1\), where \(\delta\) is the gradient arriving at \(h\). The bias can still move back up.

Q5Write ReLU and leaky ReLU as maxout units. What does \(\max(0.5x, -0.5x)\) compute, and how many parameters does a maxout unit with \(k\) pieces over \(d\) inputs have?

ReLU is \(\max(0\cdot x + 0,\ 1\cdot x + 0)\) and leaky ReLU is \(\max(0.1x,\ x)\). \(\max(0.5x, -0.5x) = 0.5|x|\), a V shape. Each piece has a weight vector of length \(d\) and a bias, so the unit has \(k(d + 1)\) parameters, \(k\) times those of an ordinary unit.

Q6Derive GELU from \(f(x) = m\cdot x\) with \(m \sim \text{Bernoulli}(\Phi(x))\), then evaluate it at \(x = 1\) and \(x = -1\) using \(\Phi(1) \approx 0.841\).

The expected value is \(\Phi(x)\cdot x + (1 - \Phi(x))\cdot 0\), which is \(x\Phi(x)\). So \(\operatorname{GELU}(1) \approx 0.841\), and since \(\Phi(-1) = 1 - \Phi(1) \approx 0.159\), \(\operatorname{GELU}(-1) \approx -0.159\). Unlike ReLU, a small negative input gives a small negative output instead of exactly 0.

Q7A layer has \(\text{fan}_\text{in} = 250\). What weight standard deviation do the \(1/\sqrt{\text{fan}_\text{in}}\) rule and the ReLU rule give? With 0.01*randn instead, by what factor does the variance shrink over 4 such layers?

\(1/\sqrt{\text{fan}_\text{in}}\): \(\operatorname{Var}(w) = 1/250 = 0.004\), standard deviation \(\approx 0.063\). ReLU rule: \(\operatorname{Var}(w) = 2/250 = 0.008\), standard deviation \(\approx 0.089\). With 0.01*randn, \(n\operatorname{Var}(w) = 250 \times 10^{-4} = 0.025\) per layer, so over 4 layers the variance is multiplied by \(0.025^4 \approx 3.9 \times 10^{-7}\).

Q8Why can batch normalization not be used with a batch size of 1, and what does layer normalization compute instead?

With \(m = 1\), \(\mu_i = x_i\) and \(\sigma_i = 0\), so \(\hat{x}_i = 0/\sqrt{\epsilon} = 0\) for every unit and the layer passes on only \(\beta\). Layer normalization takes the mean and variance across the \(H\) units of the same sample, so it needs no batch at all.