Corso
Le funzioni di attivazione decidono quali segnali passano attraverso una rete neurale e quali no. Scegliendo quella sbagliata, il modello impara troppo lentamente o non riesce a generalizzare. Per anni ReLU è stata la scelta predefinita ragionevole perché veloce e abbastanza buona per la maggior parte dei compiti.
GELU (Gaussian Error Linear Unit) ha cambiato le carte in tavola. Oggi è la funzione di attivazione alla base di alcuni dei modelli più capaci mai costruiti, tra cui BERT e GPT.
In questo articolo vedremo l'intuizione dietro GELU, la sua formula, come si confronta con altre funzioni di attivazione e dove usarla concretamente in pratica.
Se sei alle primissime armi con le funzioni di attivazione nel machine learning, leggi il nostro post Guida per principianti alla Rectified Linear Unit (ReLU).
Cos'è la funzione di attivazione GELU?
GELU, o Gaussian Error Linear Unit, è una funzione di attivazione che pesa gli input in base alla loro magnitudine con un approccio fluido e probabilistico.
La maggior parte delle funzioni di attivazione decide se far passare o bloccare il segnale. ReLU, per esempio, azzera tutto ciò che è negativo e lascia passare il resto invariato. GELU funziona diversamente. Invece di un taglio netto, scala gli input in modo continuo in base a quanto sono grandi o piccoli, il che significa che anche piccoli valori negativi possono contribuire all'output.
La differenza rispetto a ReLU è che GELU è liscia e continua ovunque. Non ci sono spigoli vivi a zero né transizioni brusche. Questa regolarità può contare durante l'addestramento perché fornisce all'ottimizzatore gradienti più puliti con cui lavorare.
Intuizione dietro GELU
Pensa a GELU come a un filtro che non tratta tutti gli input allo stesso modo.
ReLU è brutale: tutto ciò che è negativo viene azzerato, sempre. GELU, invece, si chiede: “quanto è probabile che questo valore di input sia utile?” I valori chiaramente grandi e positivi passano quasi invariati. I valori piccoli o negativi vengono ridimensionati, non tagliati del tutto.
Il risultato è una curva morbida che sopprime i segnali meno rilevanti senza scartarli completamente.
Immagina di esaminare una pila di candidature. Un filtro rigido eliminerebbe chiunque non abbia una laurea, senza eccezioni. Un filtro più intelligente prenderebbe comunque in considerazione candidati “al limite”, magari perché hanno esperienze rilevanti che compensano. GELU funziona come il filtro intelligente: non fa tagli netti, ma pesa ogni input in base alla sua magnitudine e decide quanta parte lasciar passare.
Questo ridimensionamento graduale e probabilistico è ciò che rende GELU diversa. Nessuna transizione brusca e nessun neurone morto: solo una decisione fluida di passare o sopprimere ogni valore di input.
Formula di GELU
La formula esatta di GELU si basa sulla funzione di distribuzione cumulativa (CDF) gaussiana, scritta come:

Funzione di distribuzione cumulativa gaussiana
dove x è il valore di input e Φ(x) è la probabilità che una variabile casuale estratta da una normale standard sia minore o uguale a x. In parole semplici, Φ(x) ti dice quanto è “normale” o atteso il valore di input — ed è quella probabilità che GELU usa per scalarlo.
Più alto è l'input, più Φ(x) si avvicina a 1, il che significa che l'input passa quasi invariato. Più basso è l'input, più Φ(x) si avvicina a 0, e quindi l'input viene soppresso.
L'approssimazione usata in pratica
Il problema con la formula esatta è che calcolare Φ(x) è costoso. Coinvolge la funzione errore, che non ha una forma chiusa semplice ed è lenta da calcolare su larga scala.
I framework di deep learning usano invece questa approssimazione:

Formula approssimata di GELU
Questa approssimazione usa tanh, che è veloce e ben supportata sull'hardware moderno. Il risultato è quasi identico alla formula esatta sull'intervallo di input che conta in pratica, motivo per cui framework come PyTorch e TensorFlow la usano di default.
Ovviamente non è necessario memorizzare nessuna delle due formule. Ma sapere che esiste un'approssimazione — e perché — aiuta a capire cosa succede davvero quando richiami GELU nel tuo codice.
GELU vs altre funzioni di attivazione
Ogni funzione di attivazione gestisce gli input in modo diverso, e queste differenze si riflettono su come il tuo modello si addestra.
Ecco come appare visivamente la differenza, prima di spiegarla a parole:

Grafico: GELU rispetto ad altre funzioni di attivazione
Sigmoid
Sigmoid comprime tutti gli input in un intervallo tra 0 e 1. È fluida, ma ha un problema noto: i gradienti che svaniscono. Per input molto grandi o molto piccoli, il gradiente tende a zero, e gli strati più profondi smettono di imparare. GELU non ha questo problema perché il suo gradiente resta significativo su un intervallo di input più ampio.
Tanh
Tanh è simile a Sigmoid ma centrata in zero, con output tra -1 e 1. Gestisce meglio gli input negativi rispetto a Sigmoid, ma soffre comunque di gradienti che svaniscono agli estremi. GELU produce una curva di output più morbida con un flusso di gradiente migliore nelle reti profonde.
ReLU
ReLU è veloce e semplice: gli input positivi passano invariati, quelli negativi vengono azzerati. Il taglio netto a zero causa il problema dei neuroni morenti: neuroni che ricevono nel tempo input sempre negativi smettono di aggiornarsi del tutto. GELU evita questo ridimensionando gli input negativi invece di tagliarli.
Leaky ReLU
Leaky ReLU risolve il problema dei neuroni morenti lasciando passare una piccola frazione di input negativi. È un passo avanti rispetto a ReLU, ma la transizione a zero resta brusca. GELU produce una curva complessivamente più morbida, che tende a funzionare meglio in architetture profonde dove la qualità del gradiente conta di più.
Riassumendo, ecco le differenze tra queste cinque funzioni di attivazione:

Tabella: GELU rispetto ad altre funzioni di attivazione
Perché GELU è usata nei transformer
I transformer sono semplicemente reti neurali profonde. E più la rete è profonda, più conta la qualità dei gradienti.
Modelli come BERT e GPT impilano dozzine di strati. A quella profondità, piccoli problemi nel flusso dei gradienti si amplificano. Se la tua funzione di attivazione produce gradienti instabili o quasi nulli in certe regioni, gli strati più iniziali della rete si aggiornano a malapena durante l'addestramento, e quindi imparano poco.
GELU evita questo mantenendo i gradienti regolari e non nulli su un intervallo di input più ampio. Non c'è un taglio come il confine a zero di ReLU, quindi l'ottimizzatore riceve segnali più puliti a ogni strato, non solo a quelli vicini all'output.
C'è un altro motivo per cui GELU si adatta bene alle architetture transformer.
I transformer elaborano gli input tramite meccanismi di attenzione che producono un'ampia gamma di valori di attivazione — sia positivi che negativi. Una funzione di attivazione liscia gestisce meglio questa gamma rispetto a una con transizioni brusche.
Quando fu pubblicato l'articolo originale su BERT, gli autori scelsero GELU al posto di ReLU e riportarono risultati migliori sui loro benchmark. GPT fece la stessa scelta. Da allora, GELU è diventata l'attivazione predefinita nella maggior parte delle architetture basate su transformer, non perché sia nuova, ma perché funziona meglio alla scala a cui operano questi modelli.
GELU in pratica
Usare GELU nei tuoi modelli è facile quanto usare qualsiasi altra funzione di attivazione. Sia PyTorch che TensorFlow la supportano nativamente.
PyTorch
In PyTorch puoi applicare GELU come modulo standalone o inline dentro la definizione del modello. Ecco un semplice blocco feedforward che usa GELU:
import torch
import torch.nn as nn
class FeedForwardBlock(nn.Module):
def __init__(self, input_dim, hidden_dim):
super().__init__()
self.fc1 = nn.Linear(input_dim, hidden_dim)
self.act = nn.GELU()
self.fc2 = nn.Linear(hidden_dim, input_dim)
def forward(self, x):
return self.fc2(self.act(self.fc1(x)))
block = FeedForwardBlock(input_dim=512, hidden_dim=2048)
x = torch.randn(8, 512)
output = block(x)
nn.GELU() è tra i due strati lineari, esattamente dove la trovi nel sottostrato feedforward di un transformer. L'attivazione viene eseguita dopo la prima proiezione e prima della seconda.
TensorFlow
In TensorFlow, GELU è disponibile tramite le API Keras:
import tensorflow as tf
from tensorflow import keras
model = keras.Sequential([
keras.layers.Dense(2048, input_shape=(512,)),
keras.layers.Activation("gelu"),
keras.layers.Dense(512)
])
x = tf.random.normal((8, 512))
output = model(x)
Puoi anche passarla direttamente come stringa a un livello Dense:
keras.layers.Dense(2048, activation="gelu")
Entrambi gli approcci producono lo stesso risultato.
Dove inserire GELU in una rete
GELU va nello stesso punto di qualsiasi altra funzione di attivazione: subito dopo una trasformazione lineare e prima del livello successivo. Nelle architetture transformer significa dentro il sottostrato feedforward, tra le due proiezioni dense. In altre reti profonde, la posizioni dopo il livello lineare o convoluzionale e lasci che scali l'output prima di passarla avanti.
Vantaggi di GELU
Se stai ancora leggendo, ormai conosci i principali punti di forza di GELU rispetto ad altre funzioni di attivazione. Ecco un breve riepilogo:
- Attivazione fluida: GELU produce una curva continua e derivabile senza transizioni brusche, che fornisce all'ottimizzatore informazioni più pulite a ogni passo.
- Miglior flusso del gradiente: GELU non azzera gli input negativi, quindi i gradienti possono ancora propagarsi attraverso neuroni che ricevono valori negativi. Questo riduce il rischio che i neuroni “muoiano” durante l'addestramento.
- Migliori prestazioni nei modelli profondi: In architetture profonde come i transformer, l'effetto cumulativo di gradienti più regolari tende a tradursi in risultati di addestramento migliori rispetto a funzioni di attivazione più semplici.
Limitazioni di GELU
GELU non è la scelta giusta in ogni situazione. Ecco alcune limitazioni di cui devi essere consapevole:
-
Più costosa da calcolare rispetto a ReLU: GELU coinvolge o la funzione errore o un'approssimazione basata su
tanh, entrambe più costose dell'operazione di soglia semplice di ReLU. In modelli grandi con molti strati, il costo può accumularsi. -
Meno intuitiva: Funzioni come ReLU sono facili da interpretare — i valori positivi passano, i negativi no. Il ridimensionamento probabilistico di GELU è più difficile da leggere.
-
Non sempre necessaria: Per reti poco profonde o compiti semplici, GELU non offre vantaggi significativi. ReLU o Leaky ReLU spesso rendono altrettanto bene a un costo computazionale inferiore.
In conclusione, se stai costruendo un transformer o un'altra architettura profonda, GELU è una scelta predefinita solida. Per tutto il resto, fai benchmark prima di adottarla.
Conclusione
GELU non è un upgrade universale, né una soluzione valida per tutto che sostituisce ReLU. È una scelta progettuale deliberata che vale la pena in contesti specifici — pensa a reti profonde e modelli transformer.
Se lavori con BERT, GPT o qualsiasi modello basato su transformer, stai già usando GELU, che te ne sia accorto o meno. Ora sai perché c'è.
Per tutto il resto, la scelta della funzione di attivazione è una questione di compromessi. Nessuna funzione vince sempre, e capire cosa fa ciascuna è il modo per decidere con sicurezza, non per abitudine.
Se le differenze tra le funzioni di attivazione ti confondono ancora, iscriviti al nostro Percorso Machine Learning Engineer per diventare pronto per la carriera nel machine learning e in MLOps.
FAQs
Cos'è la funzione di attivazione GELU?
GELU, o Gaussian Error Linear Unit, è una funzione di attivazione usata nelle reti neurali. A differenza di ReLU, GELU ridimensiona in modo fluido gli input in base alla loro magnitudine usando un approccio probabilistico. Questo la rende più adatta alle architetture profonde in cui la qualità del gradiente è importante.
In cosa GELU è diversa da ReLU?
ReLU azzera tutti gli input negativi con un taglio netto a zero, il che può far smettere di imparare ai neuroni — un problema noto come neuroni morenti. GELU evita questo riducendo gradualmente gli input negativi invece di tagliarli. Il risultato è un flusso di gradiente più regolare e prestazioni migliori nelle reti profonde.
Quando dovrei usare GELU al posto di altre funzioni di attivazione?
GELU funziona al meglio nelle architetture profonde, in particolare nei modelli basati su transformer come BERT e GPT. Per reti poco profonde o compiti più semplici, il sovraccarico computazionale raramente giustifica il passaggio da ReLU. Parti da ReLU come benchmark e poi puoi sempre testare altre opzioni.
Qual è la differenza tra la formula esatta di GELU e l'approssimazione?
La formula esatta di GELU usa la funzione di distribuzione cumulativa gaussiana, che richiede di calcolare la funzione errore — un'operazione lenta su larga scala. L'approssimazione la sostituisce con una tanh, un'espressione più veloce e ben supportata sull'hardware moderno. In pratica, le due producono risultati quasi identici, motivo per cui la maggior parte dei framework usa l'approssimazione di default.
GELU funziona sia in PyTorch che in TensorFlow?
Sì, entrambi i framework supportano GELU. In PyTorch puoi usare nn.GELU() come modulo all'interno della definizione del modello. In TensorFlow puoi passare "gelu" come stringa all'argomento activation di qualsiasi livello, oppure usare keras.layers.Activation("gelu").


