La función de activación GELU en redes neuronales
Índice de contenidos
La función GELU (Gaussian Error Linear Unit) multiplica cada valor de entrada por la probabilidad de que la normal estándar sea menor que ese valor. El resultado es una curva suave, con derivada continua, que pesa las entradas por su magnitud y se ha convertido en la activación por defecto de BERT y GPT.
La función GELU (Gaussian Error Linear Unit) es la activación que usan por defecto BERT, GPT y la mayoría de transformers modernos. En lugar de cortar en seco los valores negativos como hace la ReLU, GELU los atenúa de forma gradual: multiplica cada número por la probabilidad de que una variable normal estándar caiga por debajo de él. El resultado es una curva suave que mejora el entrenamiento en modelos muy profundos. La misma explicación está disponible en inglés.
Puntos clave
- La función GELU se define como
GELU(x) = x · Φ(x), dondeΦ(x)es la función de distribución acumulada de la normal estándar. - A diferencia de la ReLU, GELU es suave y tiene derivada continua en todo su dominio, lo que ayuda a que el descenso de gradiente sea más estable.
- Fue propuesta por Dan Hendrycks y Kevin Gimpel en 2016 y es la activación por defecto en BERT (2018) y en la familia GPT.
- Pesa cada entrada por su magnitud en vez de decidir solo por el signo, así que valores negativos pequeños conservan una parte de su información.
- En la práctica se calcula con una aproximación basada en la tangente hiperbólica que evita evaluar la integral gaussiana en cada paso.
¿Qué es GELU?
GELU es una función de activación, es decir, la operación no lineal que se aplica al resultado z = Wx + b de cada neurona antes de pasarlo a la capa siguiente. Sin esa no linealidad, apilar capas no serviría de nada: una pila de transformaciones lineales sigue siendo lineal. Si quieres situar esta pieza dentro del conjunto, el mapa de las matemáticas de las redes neuronales explica dónde encaja cada función.
La idea de GELU es tratar la activación como una decisión probabilística. En lugar de multiplicar la entrada por 0 o por 1 según su signo (lo que hace la función ReLU), la multiplica por un número entre 0 y 1: la probabilidad Φ(x) de que una muestra de la normal estándar sea menor que x. Cuanto mayor es x, más cerca está esa probabilidad de 1 y más pasa la entrada; cuanto más negativo, más se acerca a 0 y más se atenúa. Como escriben Hendrycks y Gimpel, «la no linealidad GELU pondera las entradas por su valor, en lugar de filtrarlas por su signo como hacen las ReLU».
Fórmula y derivada
La definición exacta usa la función de distribución acumulada $\Phi$ de la normal estándar:
$$\mathrm{GELU}(x) = x \cdot \Phi(x) = x \cdot \tfrac{1}{2}\left[1 + \operatorname{erf}!\left(\tfrac{x}{\sqrt{2}}\right)\right]$$
Aquí $\operatorname{erf}$ es la función de error, de donde viene la palabra «Error» en el nombre. Para ver el comportamiento con números concretos: $\mathrm{GELU}(-2) \approx -0{,}0455$, $\mathrm{GELU}(0) = 0$ y $\mathrm{GELU}(2) \approx 1{,}9545$. Fíjate en que la salida en $x = -2$ no es cero, como sí lo sería con la ReLU, sino un valor pequeño y negativo.
La derivada de GELU es continua en todo su dominio, incluido el origen. Esto elimina el «codo» que la ReLU tiene en cero, donde su derivada salta de golpe de 0 a 1.
Como la curva es suave, su derivada existe en todos los puntos, incluido el origen. Esa derivada es $\Phi(x) + x \cdot \varphi(x)$, donde $\varphi(x)$ es la densidad de la normal estándar.
Ver la derivación de la derivada
Aplicando la regla del producto a $x \cdot \Phi(x)$: el primer término deriva $x$ y deja $\Phi(x)$; el segundo deja $x$ y deriva $\Phi(x)$, cuya derivada es la densidad $\varphi(x)$. Resultado: $\dfrac{d}{dx}\,\mathrm{GELU}(x) = \Phi(x) + x\,\varphi(x)$.
Que el gradiente cambie de manera continua evita el «codo» que la ReLU tiene en cero, donde la derivada salta de 0 a 1. Para repasar por qué el gradiente es el motor del aprendizaje, revisa cómo funciona [la derivada como tasa de cambio](/derivadas-la-tasa-de-cambio/).
## Por qué la usan los transformers (BERT, GPT)
Cuando el equipo de Google publicó BERT en 2018 eligió GELU en lugar de ReLU, y a partir de ahí casi toda la familia de grandes modelos de lenguaje la adoptó, incluidos los GPT. La razón práctica es empírica: en las pruebas de los autores, GELU igualaba o superaba a ReLU y ELU en tareas de visión, lenguaje y voz.
Hay dos motivos que lo explican. Primero, la suavidad del gradiente ayuda a entrenar redes con muchas capas, y un transformer grande apila decenas de bloques; recuerda que un modelo como GPT-3 ajusta 175.000 millones de parámetros. Segundo, al conservar algo de señal en los valores negativos pequeños, GELU no «mata» neuronas de forma tan tajante como la ReLU, que puede dejar unidades permanentemente a cero. Esa diferencia se nota sobre todo en las primeras fases del entrenamiento.
## GELU frente a ReLU y Swish
Las tres funciones se parecen para valores grandes de `x`, donde todas dejan pasar la entrada casi intacta. Las diferencias están cerca de cero:
– **ReLU** (`max(0, x)`) es la más rápida de calcular, pero su derivada es discontinua en cero y anula por completo los negativos.
– **GELU** (`x · Φ(x)`) es suave y deja pasar una fracción de los negativos según su magnitud, con un pequeño tramo en el que la salida baja por debajo de cero.
– **Swish** o SiLU (`x · sigmoide(x)`) tiene una forma casi idéntica a GELU; de hecho, `x · sigmoide(1,702·x)` es una aproximación clásica de GELU.
En modelos de lenguaje grandes, GELU y Swish suelen rendir de forma muy parecida, y la elección depende más del ecosistema y de la costumbre que de una ventaja clara de una sobre otra.
## Implementación
En la práctica no se evalúa la integral gaussiana en cada paso, sino una aproximación con tangente hiperbólica que introdujeron los propios autores:
`GELU(x) ≈ 0,5 · x · [1 + tanh(√(2/π) · (x + 0,044715 · x³))]`
Esa constante `0,044715` ajusta la curva para que se pegue a la versión exacta. En un framework moderno no necesitas escribirla a mano: PyTorch la ofrece como una capa lista para usar.
import torch
import torch.nn as nn
gelu = nn.GELU() # exacta por defecto; approximate='tanh' para la variante
x = torch.tensor([-2.0, 0.0, 2.0])
print(gelu(x)) # tensor([-0.0455, 0.0000, 1.9545])
La salida coincide con los valores que calculamos a mano, una buena forma de comprobar que has entendido la fórmula.
## Preguntas frecuentes
### ¿En qué se diferencia GELU de ReLU?
La ReLU pone a cero cualquier entrada negativa y deja pasar las positivas sin cambios, con un cambio brusco en el origen. GELU, en cambio, es suave: multiplica cada valor por la probabilidad `Φ(x)`, de modo que los negativos pequeños conservan parte de su señal y la derivada es continua en todos los puntos.
### ¿Por qué GELU se llama «Gaussian Error Linear Unit»?
Porque combina tres ideas: es «gaussiana» al usar la distribución normal, aparece la función de «error» `erf` en su definición exacta y se comporta como una unidad casi «lineal» para valores grandes de `x`. El nombre resume su fórmula `x · Φ(x)`.
### ¿GELU es más lenta que ReLU?
Sí, algo más, porque calcular `Φ(x)` o su aproximación con tangente hiperbólica cuesta más que un simple `max(0, x)`. En modelos grandes esa diferencia es pequeña frente al coste total, y suele compensar por la estabilidad que aporta al entrenamiento.
## Conclusión
GELU sustituye la decisión abrupta de la ReLU por una transición suave gobernada por la distribución normal, y esa suavidad es la que la ha convertido en la activación estándar de los transformers. Entender su fórmula `x · Φ(x)` te da una base sólida para leer la arquitectura de BERT o GPT y para elegir con criterio entre activaciones. El siguiente paso natural es ver cómo la salida final se convierte en probabilidades con [la función softmax](/funcion-softmax-activacion-para-la-clasificacion/).
Fuentes: [1] [Gaussian Error Linear Units, Hendrycks y Gimpel (arXiv, 2016)](https://arxiv.org/abs/1606.08415), [2] [Activation function (Wikipedia)](https://en.wikipedia.org/wiki/Activation_function), [3] [torch.nn.GELU (documentación de PyTorch)](https://pytorch.org/docs/stable/generated/torch.nn.GELU.html), [4] [tf.nn.gelu (documentación de TensorFlow)](https://www.tensorflow.org/api_docs/python/tf/nn/gelu).