Activation Function Visualizer

Plot 16 activation functions and their derivatives, read f(x) and f′(x) at any point, then backpropagate through a 24-layer network in your browser: with sigmoid, the gradient that reaches the first layer is 14 to 16 orders of magnitude smaller than at the output; with ReLU it stays within about one.

4
0.01
0.25
1.00
1.00

Hover over the graph, or tap and drag sideways on a phone, to read f(x) and f′(x) at any x. Solid lines are the functions, dashed lines their derivatives. Up to 8 functions at once; each keeps its colour while it stays on.

One function in detail


Slope at 0, f′(0)—
Largest slope, max f′—
Lowest value, min f—
Flat tails, |f′| < 0.01—

All 16 activation functions at a glance

Formulas, output ranges and derivatives. Peak slopes and minimums are at the default parameters and were checked numerically against the functions this page plots.

Functionf(x) and its derivative f′(x)Output rangePeak f′Zero-centredSaturatesWhere it is used
Sigmoidσ(x) = 1 / (1 + e^(−x))
σ′(x) = σ(x)·(1 − σ(x))
(0, 1)0.25
(x = 0)
NoBoth sidesBinary-classification outputs; LSTM and GRU gates
Tanhtanh(x) = (eˣ − e^(−x)) / (eˣ + e^(−x))
tanh′(x) = 1 − tanh²(x)
(−1, 1)1
(x = 0)
YesBoth sidesLSTM and GRU state updates; classic RNNs
ReLUReLU(x) = max(0, x)
ReLU′(x) = 0 (x < 0), 1 (x > 0)
[0, ∞)1
(x > 0)
NoLeft side: gradient exactly 0AlexNet, VGG, ResNet; the default in CNNs and MLPs
Leaky ReLUf(x) = x (x ≥ 0), αx (x < 0); α = 0.01
f′(x) = 1 (x > 0), α (x < 0)
(−∞, ∞)1
(x > 0)
NoNoGAN discriminators (DCGAN uses α = 0.2)
PReLUf(x) = x (x ≥ 0), a·x (x < 0)
f′(x) = 1 (x > 0), a (x < 0); ∂f/∂a = min(0, x)
(−∞, ∞)1
(x > 0)
NoNoThe slope a is learned (PyTorch starts it at 0.25); introduced for ImageNet CNNs by He et al. (2015), the paper that also gave He initialisation
ELUf(x) = x (x > 0), α(eˣ − 1) (x ≤ 0); α = 1
f′(x) = 1 (x > 0), αeˣ (x ≤ 0)
(−α, ∞)1
(x > 0)
Partly: negative outputs pull the mean towards 0Left side, smoothly towards −αProposed by Clevert et al. (2015) to speed up training of deep networks
SELUf(x) = λx (x > 0), λα(eˣ − 1) (x ≤ 0); λ ≈ 1.0507, α ≈ 1.6733
f′(x) = λ (x > 0), λαeˣ (x ≤ 0)
(−1.7581, ∞)1.7581
(x → 0⁻)
Yes, by design (with LeCun-normal init)Left side, towards −λα ≈ −1.7581Self-normalising networks (Klambauer et al., 2017)
GELUGELU(x) = x·Φ(x) = ½x(1 + erf(x/√2))
GELU′(x) = Φ(x) + x·φ(x)
[−0.1700, ∞)1.1289
(x = √2)
No (dips to −0.1700)Left side, towards 0Feed-forward layers of BERT, GPT-2 and ViT
GELU (tanh approx.)f(x) = ½x(1 + tanh(√(2/π)·(x + 0.044715x³)))
f′(x) = ½(1 + t) + ½x(1 − t²)·√(2/π)·(1 + 0.134145x²); t = tanh(√(2/π)·(x + 0.044715x³))
[−0.1700, ∞)1.1290
(x ≈ 1.42)
No (dips to −0.1700)Left side, towards 0GPT-2's original code; approximate='tanh' in PyTorch
SiLU / Swishf(x) = x·σ(βx); β = 1: SiLU
f′(x) = σ(βx) + βx·σ(βx)·(1 − σ(βx))
[−0.2785, ∞)
(β = 1)
1.0998
(x ≈ 2.40, β = 1)
No (dips to −0.2785)Left side, towards 0EfficientNet; SwiGLU feed-forward blocks in LLaMA-family LLMs
MishMish(x) = x·tanh(softplus(x))
Mish′(x) = tanh(s) + x·sech²(s)·σ(x); s = softplus(x)
[−0.3088, ∞)1.0885
(x ≈ 1.49)
No (dips to −0.3088)Left side, towards 0The YOLOv4 backbone (Misra, 2019)
Softplussoftplus(x) = ln(1 + eˣ)
softplus′(x) = σ(x)
(0, ∞)→ 1
(x → ∞)
NoLeft side, towards 0Keeping an output positive, e.g. a predicted variance or scale
Softsignsoftsign(x) = x / (1 + |x|)
softsign′(x) = 1 / (1 + |x|)²
(−1, 1)1
(x = 0)
YesBoth sides, but only polynomiallyStudied as a tanh alternative (Glorot & Bengio, 2010); rare today
Hard sigmoidf(x) = ReLU6(x + 3) / 6 = min(1, max(0, x/6 + ½))
f′(x) = 1/6 (−3 < x < 3), 0 (|x| > 3)
[0, 1]1/6
(−3 < x < 3)
NoBoth sides, exactly (gradient 0 for |x| > 3)MobileNetV3 squeeze-and-excite blocks
Hard swishf(x) = x·ReLU6(x + 3) / 6
f′(x) = 0 (x < −3), (2x + 3)/6 (−3 ≤ x ≤ 3), 1 (x > 3)
[−0.375, ∞)1.5
(x = 3)
No (dips to −0.375)Left side, exactly (gradient 0 for x < −3)MobileNetV3 (Howard et al., 2019)
Binary stepf(x) = 1 (x ≥ 0), 0 (x < 0)
f′(x) = 0 (x ≠ 0)
{0, 1}0NoEverywhere: no gradient to pass backRosenblatt's perceptron; not trainable by backpropagation

Gradient through depth: backpropagation in your browser

This builds a real multilayer perceptron — 2 inputs, L hidden layers of the chosen width, one sigmoid output — feeds it 700 two-moons points, and runs one forward and one backward pass with binary cross-entropy. Nothing is trained: these are the gradients at initialisation, the same measurement as the article’s first depth experiment. Each point is the mean |∂loss/∂W| of one weight matrix; layer 1 sits next to the input.

24
seed 1
Layer-1 gradient—
Output-layer gradient—
Orders of magnitude lost—
Change per layer towards the input (log₁₀)—

For comparison, the article measured the same quantity with numpy (width 32, its own random seed, layer-1 gradient of separate networks of depth 1 and 24): sigmoid 1.14e-2 → 2.05e-17, ReLU 2.87e-2 → 4.60e-3, GELU 2.93e-2 → 2.16e-3, tanh 4.64e-2 → 1.59e-2. This panel draws its own random weights, so its numbers are its own; the sizes are what to compare.

Can one ReLU imitate a sigmoid?

The article’s first check: fit scale·ReLU(x + shift) + offset to the sigmoid by least squares inside a window, then look at the same line outside it. The fit is exact least squares — for each shift the scale and offset are solved in closed form, and the shift is searched over the window.

8
scale, shift, offset—
R² inside the window—
Max error on [−30, 30]—
Fitted line at x = 30 (sigmoid: 1.00)—

What this activation function visualizer shows

Tick up to eight functions in the list under the graph. Solid lines are the functions themselves, dashed lines in the same colour are their derivatives, and the Show menu switches between both, f(x) only and f′(x) only. Move the pointer over the graph (on a phone, drag sideways) and the table underneath gives f(x) and f′(x) for every plotted function at that x. x range and the + and − buttons zoom; Same scale on both axes makes a slope of 1 look like 45°, which is the honest way to compare ReLU with a sigmoid; and Shade where |f′| < 0.01 marks the flat tails of the function chosen in One function in detail.

That panel prints the formula and its derivative, measures the slope at 0, the largest slope, the lowest value and where the flat tails begin, and copies both formulas as LaTeX. The table below it is the list view: all 16 functions with formula, derivative, output range, peak slope, whether they are zero-centred, where they saturate, and a well-known place each one is used. Every peak and minimum in that table was recomputed from the plotted functions by this page’s verification script.

The functions, grouped by shape

Squashing functions: sigmoid, tanh, softsign, hard sigmoid

These map every input into a bounded interval. The sigmoid σ(x) = 1/(1 + e⁻ˣ) has derivative σ(x)(1 − σ(x)), which is never larger than 0.25, reached at x = 0. Tanh is the same curve stretched to (−1, 1) — tanh(x) = 2σ(2x) − 1 — so its peak slope is 1. Both go flat quickly: |f′| drops below 0.01 for |x| ≥ 2.99 with tanh and |x| ≥ 4.58 with the sigmoid. Softsign, x/(1 + |x|), has the same range as tanh but approaches ±1 only like 1/|x|, so its slope stays above 0.01 until |x| = 9. The hard sigmoid used in MobileNetV3 replaces the curve with three straight pieces and has slope exactly 1/6 between −3 and 3 and exactly 0 outside.

Rectifiers: ReLU, Leaky ReLU, PReLU, ELU, SELU

ReLU, max(0, x), has slope exactly 1 for positive inputs and exactly 0 for negative ones; at the kink the derivative is undefined, and this page uses 0 there, as PyTorch does. Leaky ReLU and PReLU keep a small slope α (or a learned a) on the left so a unit can never stop receiving gradient. ELU bends smoothly towards −α instead, and is only smooth at 0 when α = 1. SELU scales ELU with λ ≈ 1.0507 and α ≈ 1.6733, constants chosen so that a standard-normal input keeps mean 0 and variance 1: integrating numerically, this page gets E[f(z)²] = 1.000000000 and a mean below 10⁻¹⁴.

Smooth gates: GELU, SiLU/Swish, Mish, softplus, hard swish

These multiply x by a soft switch. GELU is x·Φ(x), with Φ the normal distribution function; it dips to −0.1700 at x = −0.752, and its slope peaks at 1.1289 at x = √2 — above 1, which ReLU never is. The tanh approximation used in GPT-2’s original code differs from the exact erf form by at most 4.73 × 10⁻⁴ (at x = ±2.70), and its slope by at most 8.68 × 10⁻⁴ (at x = ±2.02), measured on [−10, 10]. Swish is x·σ(βx) and β = 1 is SiLU. Press Swish β sweep to watch β run from 0.1 to 10: as β → 0 it becomes the straight line x/2, and its largest distance from ReLU is 0.2785/β, so it closes in on ReLU as β grows. Mish, x·tanh(softplus(x)), has slope 0.6 at 0 (exactly tanh(ln 2)) and a minimum of −0.3088. Softplus is the smooth ReLU whose derivative is the sigmoid itself.

The binary step

Rosenblatt’s perceptron used a step. Its derivative is 0 wherever it exists, so backpropagation has nothing to pass back — in the depth panel every layer of a step network below the output layer gets a gradient of exactly 0. That is the whole reason smooth or piecewise-linear functions replaced it.

Why the derivative decides what a deep network can learn

Backpropagation multiplies one factor per layer on the way back to the input: the transposed weight matrix, then the activation’s derivative at that layer’s inputs. If the derivative is at most 0.25, then with weights scaled so that the matrices roughly preserve size — Xavier initialisation does that for a square layer — the gradient shrinks by about a factor of four per layer, every layer.

The Japanese write-up behind this page measured exactly that. It trained width-32 MLPs on two-moons (1000 points, noise 0.25, 700 for training and 300 for testing) with Adam at learning rate 0.01, giving each function its own best initialisation: He for ReLU and GELU, Xavier for tanh and sigmoid. At initialisation the first-layer gradient of the sigmoid network fell from 1.14 × 10⁻² at depth 1 to 2.05 × 10⁻¹⁷ at depth 24 — the “15 orders of magnitude” in its title (log₁₀ of the ratio is 14.7). ReLU, GELU and tanh stayed between 10⁻² and 10⁻³. After training, the sigmoid network still reached 0.803 test accuracy at depth 12 and then fell to 0.490 at depth 16 and 24, which is exactly 147/300: it predicted class 1 for every test point. ReLU and GELU stayed between 0.89 and 0.95 at every depth; tanh dropped to 0.80 at depth 24.

The Gradient through depth panel recomputes the first half of that experiment in your browser: the same architecture, the same loss, the same metric (the mean absolute value of each weight matrix’s gradient), on 700 two-moons points generated with the same recipe. It does not train, so it cannot reproduce the accuracy numbers, and it draws its own random weights, so its numbers are its own. With the default ReLU vs sigmoid, 24 layers (seed 1) the sigmoid line falls from 7.00 × 10⁻³ at the output layer to 3.22 × 10⁻¹⁷ at layer 1: 14.3 orders of magnitude, or −0.637 orders per layer. ReLU with He goes from 2.21 × 10⁻² to 3.08 × 10⁻³, 0.9 orders in total. Across 20 random seeds the sigmoid loses 14.3 to 15.9 orders and shrinks by a factor of 0.224 to 0.238 per layer — just under the 0.25 ceiling set by σ′ — while ReLU’s total stays between −0.3 and 1.3 orders.

Switch the plot to Layer-1 gradient vs depth, or press The article’s four, and the panel builds a separate network for each depth from 1 to 24, as the article did. Over 20 seeds the median sigmoid values are 1.51 × 10⁻², 3.32 × 10⁻³, 2.04 × 10⁻⁴, 4.63 × 10⁻⁷, 1.30 × 10⁻⁹, 4.48 × 10⁻¹² and 2.94 × 10⁻¹⁷ at depths 1, 2, 4, 8, 12, 16 and 24, against the article’s 1.14 × 10⁻², 3.07 × 10⁻³, 2.14 × 10⁻⁴, 5.54 × 10⁻⁷, 2.40 × 10⁻⁹, 2.34 × 10⁻¹² and 2.05 × 10⁻¹⁷; the median drop from depth 1 to 24 is 14.7 orders, the same as the article’s.

Initialisation is the other half

A flat line in the per-layer view is not the whole story. ReLU with the wrong init compares He and Xavier at 48 layers. Both lines are flat, but with Xavier the whole profile sits about seven orders lower: 7.84 × 10⁻¹⁰ at layer 1 against 1.14 × 10⁻² with He (seed 1). The problem is in the forward pass: ReLU discards half of its input, and only He’s factor of 2 makes up for it. Measured directly, the output of the 48th layer has a root-mean-square of 8 × 10⁻¹⁰ to 6 × 10⁻⁹ with Xavier and 0.04 to 0.28 with He, over five seeds.

Smooth modern functions shows the same effect where it is less expected. With He initialisation at 48 layers, the median layer-1 gradient over 20 seeds is 3.4 × 10⁻⁷ for GELU, 2.2 × 10⁻⁸ for SiLU and 7.4 × 10⁻⁵ for Mish, against 4.2 × 10⁻² for SELU with LeCun initialisation, whose forward signal stays at a root-mean-square of 0.88 to 1.2. He’s factor of 2 was derived for ReLU; deep plain stacks of other functions need their own scaling (or the normalisation layers that real architectures add).

Can one ReLU imitate a sigmoid?

The article’s first check fitted scale·ReLU(x + shift) + offset to the sigmoid on [−8, 8] and got scale 0.1009, shift 4.5522, offset 0.0029 and R² = 0.922 — a respectable fit. The same line evaluated on [−30, 30] misses by up to 2.49, and at x = 30 it is at 3.49 while the sigmoid is at 1.0000. The last panel on this page solves the same least-squares problem exactly and reproduces all six numbers. Move the window to see the trade-off: at ±4 the fit inside is better (R² = 0.976) and the miss on [−30, 30] is worse (4.41); at ±16 R² drops to 0.863 and the miss shrinks to 1.07. A good fit inside a window says nothing about what happens outside it, and a saturating function and a non-saturating one part ways exactly there.

Limits

What will you try next?

Share this tool

Part of Shake AI Lab — interactive experiments in mathematics and machine learning. · More tools · 日本語の解説記事