Activation Functions

July 6, 2025

Math for Training
TypeNameFormulaCommon usage
Non-gatedReLUReLU(x)=max⁡(0,x)\mathrm{ReLU}(x) = \max(0, x)Older Transformer FFNs
Non-gatedGELUGELU(x)=x Φ(x)\mathrm{GELU}(x) = x\,\Phi(x)BERT, GPT-2, GPT-3-style models
Non-gatedSiLU / SwishSiLU(x)=x σ(x)\mathrm{SiLU}(x) = x\,\sigma(x)Used directly in some modern networks
Non-gatedSquared ReLUReLU2(x)=max⁡(0,x)2\mathrm{ReLU}^2(x) = \max(0, x)^2Used in some newer architectures
GatedGLUσ(xWg)⊙(xWu)\sigma(xW_g) \odot (xW_u)Original gated linear unit
GatedReGLUReLU(xWg)⊙(xWu)\mathrm{ReLU}(xW_g) \odot (xW_u)GLU variant
GatedGEGLUGELU(xWg)⊙(xWu)\mathrm{GELU}(xW_g) \odot (xW_u)T5-family / some encoder-decoder models
GatedSwiGLUSiLU(xWg)⊙(xWu)\mathrm{SiLU}(xW_g) \odot (xW_u)Very common in modern LLMs: Llama, Mistral, Qwen, etc.

Non-gated FFN

FFN(x)=f(xW1)W2\mathrm{FFN}(x) = f(xW_1)W_2

Example with GELU:

FFN(x)=GELU(xW1)W2\mathrm{FFN}(x) = \mathrm{GELU}(xW_1)W_2

Gated FFN

FFN(x)=[f(xWg)⊙(xWu)]Wd\mathrm{FFN}(x) = \left[f(xW_g) \odot (xW_u)\right] W_d

For SwiGLU specifically:

FFN(x)=[SiLU(xWg)⊙(xWu)]Wd\mathrm{FFN}(x) = \left[\mathrm{SiLU}(xW_g) \odot (xW_u)\right] W_d

A useful modern-LLM summary is:

Older GPT/BERT→GELU\text{Older GPT/BERT} \rightarrow \text{GELU}

Modern decoder LLMs→SwiGLU\text{Modern decoder LLMs} \rightarrow \text{SwiGLU}

And the key naming pattern is:

ReLU→ReGLU\mathrm{ReLU} \rightarrow \mathrm{ReGLU}

GELU→GEGLU\mathrm{GELU} \rightarrow \mathrm{GEGLU}

SiLU/Swish→SwiGLU\mathrm{SiLU/Swish} \rightarrow \mathrm{SwiGLU}


NameFormulaCommon usage
Sigmoidσ(x)=11+e−x\sigma(x) = \dfrac{1}{1 + e^{-x}}Gates, not usually standalone FFN activation
Tanhtanh⁡(x)=ex−e−xex+e−x\tanh(x) = \dfrac{e^x - e^{-x}}{e^x + e^{-x}}Rare in modern transformer FFNs
Leaky ReLUmax⁡(x,αx)\max(x, \alpha x)Rare in LLMs
Squared ReLUReLU2(x)=max⁡(0,x)2\mathrm{ReLU}^2(x) = \max(0, x)^2Some newer architectures
Mishxtanh⁡(ln⁡(1+ex))x \tanh(\ln(1 + e^x))Rare

Activation Functions Visualization

(source: colab)


Details of each activation

GELU

The exact GELU definition is:

GELU(x)=x Φ(x)\mathrm{GELU}(x) = x\,\Phi(x)

where Φ(x)\Phi(x) is the standard normal CDF:

Φ(x)=12π∫−∞xe−t2/2 dt\Phi(x) = \frac{1}{\sqrt{2\pi}} \int_{-\infty}^{x} e^{-t^2/2}\, dt

So equivalently:

GELU(x)=x2(1+erf ⁣(x2))\mathrm{GELU}(x) = \frac{x}{2}\left(1 + \mathrm{erf}\!\left(\frac{x}{\sqrt{2}}\right)\right)

because

Φ(x)=12(1+erf ⁣(x2))\Phi(x) = \frac{1}{2}\left(1 + \mathrm{erf}\!\left(\frac{x}{\sqrt{2}}\right)\right)

The commonly used approximation is:

GELU(x)≈x2[1+tanh⁡ ⁣(2π (x+0.044715 x3))]\mathrm{GELU}(x) \approx \frac{x}{2}\left[1 + \tanh\!\left(\sqrt{\frac{2}{\pi}}\,\left(x + 0.044715\,x^3\right)\right)\right]

Intuition:

GELU(x)=xדprobability that a standard Gaussian is≤x”\mathrm{GELU}(x) = x \times \text{“probability that a standard Gaussian is} \le x\text{”}

Standard Normal Cumulative Distribution Function

Φ(x)=P(Z≤x), Z∼N(0,1)\Phi(x) = P(Z \le x),\ Z \sim N(0, 1) — as x→−∞x \to -\infty, Φ(x)→0\Phi(x) \to 0; as x→+∞x \to +\infty, Φ(x)→1\Phi(x) \to 1; and Φ(0)=0.5\Phi(0) = 0.5.

SiLU

SiLU stands for Sigmoid Linear Unit.

Its mathematical definition is:

SiLU(x)=x σ(x)\mathrm{SiLU}(x) = x\,\sigma(x)

where sigmoid is

σ(x)=11+e−x\sigma(x) = \frac{1}{1 + e^{-x}}

So equivalently:

SiLU(x)=x1+e−x\mathrm{SiLU}(x) = \frac{x}{1 + e^{-x}}

Gated Activation

Typically inside the Transformer FFN/MLP sublayer, not in the attention operation.

For a modern decoder block, the rough structure is:

x→Attention→FFN / MLPx \rightarrow \text{Attention} \rightarrow \text{FFN / MLP}

Inside the FFN, a gated activation like SwiGLU is applied here:

x→  Wg, Wu  {xWg→ SiLU xWu→ ⊙ h→  Wd  outputx \xrightarrow{\;W_g,\,W_u\;} \begin{cases} xW_g \xrightarrow{\ \mathrm{SiLU}\ } \\ xW_u \end{cases} \xrightarrow{\ \odot\ } h \xrightarrow{\;W_d\;} \text{output}

So for SwiGLU:

FFN(x)=[SiLU(xWg)⊙(xWu)]Wd\mathrm{FFN}(x) = \left[\mathrm{SiLU}(xW_g) \odot (xW_u)\right] W_d

The gated activation is specifically this part:

SiLU(xWg)⊙(xWu)\mathrm{SiLU}(xW_g) \odot (xW_u)

It sits between the input/up projections and the down projection.

In code:

gate = gate_proj(x)
up   = up_proj(x)

hidden = F.silu(gate) * up   # gated activation happens here

out = down_proj(hidden)