FFN Activation Functions › Implementation: Configurable Activation Module

Michael BrenndoerferUpdated June 14, 20252 min read
Language AI HandbookAll chapters
Part 15 of 67Transformer Blocks
Chapter 108FFN Activation Functions › Implementation: Configurable Activation Module
Reading section 11 of 15 · Implementation: Configurable Activation Module · 2 minSection 11 of 15 · 2 min

Book contents

Section 11 of 15 · 2 min read

FFN Activation Functions › Implementation: Configurable Activation ModuleOne section · Sections in this chapter11 / 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

Let's create a configurable activation function module that supports all three options, following patterns used in modern transformer libraries:

In[26]:
Code
class Activation:
    """
    Configurable activation function for FFN layers.

    Supports ReLU, GELU (exact and approximate), and SiLU.
    """

    ACTIVATIONS = {
        "relu": lambda x: np.maximum(0, x),
        "gelu": lambda x: x * 0.5 * (1 + erf(x / np.sqrt(2))),
        "gelu_approximate": lambda x: (
            0.5 * x * (1 + np.tanh(np.sqrt(2 / np.pi) * (x + 0.044715 * x**3)))
        ),
        "silu": lambda x: x * (1 / (1 + np.exp(-np.clip(x, -500, 500)))),
    }

    def __init__(self, activation_type="gelu"):
        """
        Initialize the activation function.

        Args:
            activation_type: One of "relu", "gelu", "gelu_approximate", "silu"
        """
        if activation_type not in self.ACTIVATIONS:
            raise ValueError(
                f"Unknown activation: {activation_type}. "
                f"Choose from {list(self.ACTIVATIONS.keys())}"
            )

        self.activation_type = activation_type
        self._func = self.ACTIVATIONS[activation_type]

    def __call__(self, x):
        """Apply the activation function."""
        return self._func(x)

    def __repr__(self):
        return f"Activation({self.activation_type})"


# Test the module
test_input = np.array([-2, -1, 0, 1, 2])
Out[27]:
Console
Activation module test:

Input: [-2 -1  0  1  2]

Activation(relu)               → [0 0 0 1 2]
Activation(gelu)               → [-0.046 -0.159  0.     0.841  1.954]
Activation(gelu_approximate)   → [-0.045 -0.159  0.     0.841  1.955]
Activation(silu)               → [-0.238 -0.269  0.     0.731  1.762]

In practice, PyTorch makes this even simpler. You can specify the activation using torch.nn.functional.gelu, torch.nn.functional.silu, or torch.nn.ReLU(). Hugging Face's Transformers library defines an ACT2FN dictionary that maps string names like "gelu", "silu", and "relu" to their corresponding functions, allowing model architectures to be configured via a single string parameter in the model config. This pattern lets you swap activations without changing the model code, which is convenient for ablation experiments.