FFN Activation Functions › Activation Function Comparison
Language AI HandbookAll chapters FFN Activation Functions › Activation Function ComparisonOne section · Sections in this chapter6 / 15 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
With all three activations implemented, let's visualize them together to understand their relationships and differences:

The three functions converge for large positive inputs, approaching the identity function. They also converge for large negative inputs, approaching zero. The critical differences are in the transition region around zero, where:
- ReLU has a sharp corner with discontinuous derivative
- GELU has a smooth transition with a slight negative dip (minimum at )
- SiLU has a smooth transition with a deeper negative dip (minimum at )
Let's also compare the derivatives, which directly affect gradient flow during training:

The derivative plots show that both smooth activations can mildly amplify gradients for certain positive inputs. GELU's derivative peaks at approximately near , while SiLU's derivative peaks at approximately near . Let's examine SiLU's broader amplification region in more detail:

Quantitative Comparison
Let's compute specific properties that affect neural network behavior:
def analyze_activation(name, func, x_range):
"""Compute key properties of an activation function."""
y = func(x_range)
# Find minimum value and location
min_idx = np.argmin(y)
min_val = y[min_idx]
min_x = x_range[min_idx]
# Sparsity: fraction of outputs that are zero or near-zero
sparsity = (np.abs(y) < 0.01).mean()
# Linearity for positive inputs (correlation with y=x)
pos_mask = x_range > 0.5
correlation = np.corrcoef(x_range[pos_mask], y[pos_mask])[0, 1]
return {
"name": name,
"min_value": min_val,
"min_location": min_x,
"sparsity": sparsity,
"linearity": correlation,
}
x_analysis = np.linspace(-5, 5, 10000)
activations = [
("ReLU", relu),
("GELU", gelu_exact),
("SiLU", silu),
]
results = [
analyze_activation(name, func, x_analysis) for name, func in activations
]Activation function properties: Function Min Value Min Location Sparsity Linearity ----------------------------------------------------------------- ReLU 0.0000 -5.00 50.1% 1.000000 GELU -0.1700 -0.75 23.6% 0.999769 SiLU -0.2785 -1.28 0.4% 0.999823
Key observations from this analysis:
-
Minimum value: ReLU never goes negative (by definition). GELU's dip is mild (-0.17), while SiLU dips deeper (-0.28). These negative values can help with regularization but also introduce potential instabilities.
-
Sparsity: All three create some degree of sparsity (outputs near zero), but ReLU is the most sparse for normally distributed inputs. This sparsity can aid interpretability and efficiency.
-
Linearity: All three are highly linear for positive inputs (correlation > 0.999 with ), which helps preserve signal magnitude through deep networks.
The sparsity difference between ReLU and the smooth activations is worth dwelling on. For a standard normal input distribution, ReLU produces exactly 50% sparsity by zeroing all negative values. GELU and SiLU produce much less sparsity because they only attenuate negative inputs, not zero them. This means GELU and SiLU FFN layers operate with denser intermediate representations, which requires slightly more memory bandwidth during training and inference.