The ReLU function explained

Learn how the ReLU function works

Contents
  1. Definition
  2. The Derivative
  3. Why It Replaced the Sigmoid
  4. One Kink at a Time
  5. Why Depth Matters
  6. The Dying ReLU Problem
  7. Variants
  8. Initialization
  9. In Code
  10. Common Mistakes

A neural network is a stack of linear maps, and a stack of linear maps is still one linear map: W_2(W_1 x) = (W_2 W_1)x. Depth buys nothing until something bends between the layers. The bend that made deep networks trainable is the simplest one you could write down.

Definition #

The rectified linear unit, or ReLU, keeps positive numbers and turns everything else into zero:

\mathrm{ReLU}(x) = \max(0, x) = \begin{cases} x & \text{if } x > 0 \\ 0 & \text{if } x \le 0 \end{cases}
−4−3−2−101234−101234the kink
Two straight lines that meet at the origin. All the nonlinearity of ReLU sits in that one point.

The Derivative #

\mathrm{ReLU}'(x) = \begin{cases} 1 & \text{if } x > 0 \\ 0 & \text{if } x < 0 \end{cases}

At x = 0 the slope from the left is 0 and the slope from the right is 1, so no derivative exists there. This does not stop training: libraries pick a value, usually 0, and carry on.

Why It Replaced the Sigmoid #

Backpropagation is the chain rule, so the gradient that reaches the first layer holds one factor of the activation's slope for every layer. In a chain of n layers with activation f, where a_k is the input to the activation in layer k:

\frac{\partial L}{\partial w_1} \propto \prod_{k=1}^{n} f'(a_k) \prod_{k=2}^{n} w_k

The sigmoid \sigma(x) = 1 / (1 + e^{-x}) has the slope \sigma'(x) = \sigma(x)(1 - \sigma(x)), which is never above \frac{1}{4}. Across ten layers, those factors multiply to at most

\left(\frac{1}{4}\right)^{10} \approx 10^{-6}

and that is the best case, with every unit sitting exactly at x = 0. At x = 5 the slope is already 0.0066. The function \tanh does better at the centre, where its slope is 1, but it flattens in the same way.

  • \mathrm{ReLU}'(x)
  • \tanh'(x)
  • \sigma'(x)
−6−4−2024600.51
The slope of each function. The other two fade on both sides, while ReLU stays at exactly 1 for every positive input.

A ReLU that is switched on has a slope of exactly 1, so it passes the gradient through unchanged, however deep the network is. The function is old: Fukushima used it in 1969,[1] and around 2010 it was brought into deep networks.[2][3] The AlexNet paper made the case in 2012: a four-layer convolutional network with ReLU reached 25% training error on CIFAR-10 about six times sooner than the same network with \tanh.[4]

One Kink at a Time #

If every piece is a straight line, how does a network learn a curve? By adding kinks. Three ReLUs already make a bump:

\mathrm{bump}(x) = \mathrm{ReLU}(x) - 2\,\mathrm{ReLU}(x - 1) + \mathrm{ReLU}(x - 2)

Each term switches on at its own point and changes the slope there, which goes from 0 to 1, then to -1, then back to 0.

  • Sum
  • \mathrm{ReLU}(x)
  • -2\,\mathrm{ReLU}(x - 1)
  • \mathrm{ReLU}(x - 2)
−101234−3−2−10123
Three lines that grow without limit add up to a bump that is zero outside [0, 2].

The coefficient of each ReLU is the change in slope at its kink. So any broken line through the points t_0 < t_1 < \dots < t_n, with slope m_i on the piece that ends at t_i, can be written on [t_0, t_n] as

f(x) = f(t_0) + m_1 \mathrm{ReLU}(x - t_0) + \sum_{i=1}^{n-1} (m_{i+1} - m_i)\,\mathrm{ReLU}(x - t_i)

That sum is exactly a network with one hidden layer. With enough kinks it can follow any continuous function on an interval as closely as you like. Six units already trace a sine wave with a maximum error of 0.134, and twelve bring that down to 0.033: double the kinks and the error falls to a quarter.

  • Six ReLU units
  • \sin x
0123456−1−0.500.51
One hidden layer with six units, following a sine wave with six straight pieces.

Why Depth Matters #

A new unit adds one kink. A new layer multiplies them, because each layer folds the output of the one before. Take this tent on [0, 1], made of two units:

t(x) = 2\,\mathrm{ReLU}(x) - 4\,\mathrm{ReLU}\left(x - \tfrac{1}{2}\right)

Feed it into itself, and every layer doubles the number of teeth.

  • Four layers
  • One layer
00.20.40.60.8100.20.40.60.81
The same tent applied four times gives eight teeth from only eight units.

Ten such layers use 20 units and produce 512 teeth with 1,023 kinks. One hidden layer would need at least 1,023 units to draw the same shape.[5] This does not mean that every deep network reaches that count, only that depth can buy complexity far more cheaply than width can.

The Dying ReLU Problem #

The flat side has a price. Take a unit \mathrm{ReLU}(wx + b) with inputs in [-1, 1], w = 1 and b = -10. Then wx + b \le -9 for every input, so the output is always 0 and so is the gradient. Neither w nor b will ever change again, and the unit is dead.

A single large update can push a unit there, which is why a learning rate that is too high can quietly remove part of a network. To check for it, measure the share of units that output zero for a whole batch.

Variants #

Leaky ReLU gives the left side a small slope, so that no unit is ever fully off. The usual choice is \alpha = 0.01.[6]

\mathrm{LeakyReLU}(x) = \max(\alpha x, x)

GELU replaces the kink with a smooth curve, where \Phi is the standard normal distribution function. It dips to about -0.17 near x = -0.75.[7]

\mathrm{GELU}(x) = x\,\Phi(x)
  • ReLU
  • Leaky ReLU, \alpha = 0.1
  • GELU
−3−2−101230123
ReLU and two of its variants. The slope of the leaky line is exaggerated here so that it can be seen.

In language models the choice has moved over time. The original Transformer used plain ReLU in its feed-forward layers, \max(0, xW_1 + b_1)W_2 + b_2,[8] and BERT moved to GELU.[9]

Initialization #

For an input that is symmetric around zero, ReLU discards half of the signal: \mathbb{E}[\mathrm{ReLU}(z)^2] = \frac{1}{2}\mathbb{E}[z^2]. Without a correction, the variance would halve at every layer, so ReLU networks draw their weights with twice the usual variance, where n is the number of inputs to the layer.[10]

\mathrm{Var}(w) = \frac{2}{n}

In Code #

import numpy as np

def relu(x):
    return np.maximum(0, x)

def bump(x):
    return relu(x) - 2 * relu(x - 1) + relu(x - 2)

print(bump(np.array([-1.0, 0.5, 1.0, 1.5, 3.0])))
# [0.  0.5 1.  0.5 0. ]

Common Mistakes #

  1. Putting a ReLU on the output of a regression whose target can be negative. It cannot produce a negative number.
  2. Using an initialization designed for \tanh, which lets the signal shrink layer by layer.
  3. Blaming the data when a network stops improving, without checking how many units have died.
  4. Worrying about the kink at zero. An input that lands exactly on it is rare, and the choice of slope there rarely matters.

  1. K. Fukushima, Visual feature extraction by a multilayered network of analog threshold elements, IEEE Transactions on Systems Science and Cybernetics, 1969. ↩︎

  2. V. Nair and G. Hinton, Rectified linear units improve restricted Boltzmann machines, ICML 2010. ↩︎

  3. X. Glorot, A. Bordes and Y. Bengio, Deep sparse rectifier neural networks, AISTATS 2011. ↩︎

  4. A. Krizhevsky, I. Sutskever and G. Hinton, ImageNet classification with deep convolutional neural networks, NeurIPS 2012. ↩︎

  5. M. Telgarsky, Benefits of depth in neural networks, COLT 2016. ↩︎

  6. A. Maas, A. Hannun and A. Ng, Rectifier nonlinearities improve neural network acoustic models, ICML 2013. ↩︎

  7. D. Hendrycks and K. Gimpel, Gaussian error linear units (GELUs), 2016. ↩︎

  8. A. Vaswani et al., Attention is all you need, NeurIPS 2017. ↩︎

  9. J. Devlin et al., BERT: pre-training of deep bidirectional transformers for language understanding, 2018. ↩︎

  10. K. He, X. Zhang, S. Ren and J. Sun, Delving deep into rectifiers, ICCV 2015. ↩︎

Comments

Loading comments…