A la lliçó anterior el perceptró decidia amb una funció esglaó: tot o res, 0 o 1. Aquest interruptor brusc té dos problemes seriosos: no expressa matisos ("com de sospitosa és aquesta comanda?") i, sobretot, no es pot derivar, cosa que —com veurem a la propera lliçó— fa impossible entrenar capes ocultes. En aquesta lliçó entendràs primer per què una xarxa necessita funcions d'activació no lineals (sense elles, apilar cent capes equival a tenir-ne una de sola), i després recorrerem el catàleg d'activacions que faràs servir durant tot el curs: sigmoide, tanh, ReLU i les seves variants, i softmax. Tancarem amb una guia pràctica de quina fer servir en cada situació, amb els projectes de TecnoMarket com a exemples, i les implementarem i visualitzarem amb numpy i matplotlib.
Contingut
- Per què la no linealitat és imprescindible
- Catàleg de funcions d'activació
- Taula comparativa
- Quina activació fer servir a cada capa segons el problema
- Implementació en numpy i visualització amb matplotlib
Per què la no linealitat és imprescindible
Imagina que traiem l'activació (o fem servir l'"activació identitat" $f(z) = z$, que és lineal) a la xarxa 2-2-1 que va resoldre XOR. Cada capa faria només una operació lineal: multiplicar per una matriu i sumar un biaix. Vegem què passa en encadenar-ne dues:
$$h = W_1^T x + b_1 \qquad \hat{y} = W_2^T h + b_2$$
Substituint la primera dins la segona:
$$\hat{y} = W_2^T (W_1^T x + b_1) + b_2 = \underbrace{(W_2^T W_1^T)}{W'} x + \underbrace{(W_2^T b_1 + b_2)}{b'} = W' x + b'$$
El resultat és una altra operació lineal, amb una matriu $W'$ i un biaix $b'$ combinats. Tant és quantes capes apilis: la composició de funcions lineals és lineal. Una xarxa de 100 capes sense activacions no lineals és matemàticament idèntica a un perceptró sense esglaó, és a dir, a una simple regressió lineal — i per tant torna a estavellar-se contra XOR i contra qualsevol problema del món real.
Ho pots comprovar empíricament en numpy:
import numpy as np
rng = np.random.default_rng(42)
W1, b1 = rng.normal(size=(3, 4)), rng.normal(size=4)
W2, b2 = rng.normal(size=(4, 2)), rng.normal(size=2)
x = rng.normal(size=3)
# Xarxa de 2 capes SENSE activació
y_xarxa = (x @ W1 + b1) @ W2 + b2
# Una sola capa equivalent, "col·lapsada"
W_eq = W1 @ W2
b_eq = b1 @ W2 + b2
y_eq = x @ W_eq + b_eq
print(np.allclose(y_xarxa, y_eq)) # -> True: eren la mateixa funcióLa funció d'activació és la peça que trenca aquesta trampa: en aplicar una funció no lineal $f$ després de cada capa ($h = f(W^T x + b)$), la composició deixa de col·lapsar i cada capa nova afegeix capacitat real. És el que permet la jerarquia de representacions que vam veure a la primera lliçó del curs: vores → formes → objectes.
Catàleg de funcions d'activació
Per a cada funció indiquem fórmula, forma de la gràfica, rang de sortida i ús típic. Totes reben la suma ponderada $z = w \cdot x + b$ de la lliçó anterior.
Esglaó (step)
$$f(z) = \begin{cases} 1 & z \geq 0 \ 0 & z < 0 \end{cases}$$
- Gràfica: una línia horitzontal a 0 que salta bruscament a 1 en creuar l'origen.
- Rang: {0, 1} (només dos valors).
- Ús avui: cap a la pràctica; interès històric (perceptró). La seva derivada és 0 a tot arreu (i infinita al salt), de manera que no transmet informació de "quant corregir".
Sigmoide (logística)
$$\sigma(z) = \frac{1}{1 + e^{-z}}$$
- Gràfica: una "S" suau: a prop de 0 per a $z$ molt negatius, a prop d'1 per a $z$ molt positius, i val exactament 0.5 a $z=0$. És la versió "suavitzada" de l'esglaó.
- Rang: (0, 1).
- Interpretació: la seva sortida es pot llegir com a probabilitat. Per al filtre antifrau de TecnoMarket, en lloc d'un sec "frau sí/no", la sigmoide retorna "probabilitat de frau 0.87", cosa que permet polítiques graduals (bloquejar si > 0.9, revisar manualment si 0.5–0.9).
- Problema: als extrems la corba és gairebé plana (es satura): el pendent és pràcticament zero, i això dificulta l'aprenentatge en xarxes profundes. És l'origen del vanishing gradient que esmentarem al final i desenvoluparem a la propera lliçó.
- Ús actual: capa de sortida en classificació binària. Ja gairebé mai en capes ocultes.
Tangent hiperbòlica (tanh)
$$\tanh(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}}$$
- Gràfica: la mateixa "S" que la sigmoide, però estirada verticalment: passa per l'origen (tanh(0) = 0).
- Rang: (−1, 1).
- Avantatge sobre la sigmoide: la seva sortida està centrada en zero, cosa que sol facilitar l'entrenament de la capa següent (les entrades no són totes positives).
- Problema: es satura igual que la sigmoide als extrems.
- Ús actual: capes ocultes en algunes arquitectures recurrents (la retrobaràs dins de les LSTM al mòdul 4).
ReLU (Rectified Linear Unit)
$$\text{ReLU}(z) = \max(0, z)$$
- Gràfica: plana a 0 per a $z$ negatiu, i una recta de pendent 1 per a $z$ positiu. Un "colze" a l'origen.
- Rang: [0, +∞).
- Per què domina: és baratíssima de calcular (una comparació), no es satura per a valors positius (el pendent continua sent 1 per gran que sigui $z$) i a la pràctica fa que les xarxes profundes entrenin molt més ràpid. És l'activació per defecte en capes ocultes des de l'era AlexNet (2012, lliçó d'història).
- Encara que sembli "gairebé lineal", no ho és: el colze a 0 basta per trencar el col·lapse lineal de l'apartat 1.
- Problema: les neurones mortes (dying ReLU): si una neurona acaba amb $z$ sempre negatiu per a totes les dades, la seva sortida és sempre 0, el seu pendent és sempre 0, i ja no torna a aprendre mai més.
Variants de ReLU: Leaky ReLU i ELU
Leaky ReLU — arregla les neurones mortes deixant passar un petit pendent a la zona negativa:
$$f(z) = \begin{cases} z & z \geq 0 \ \alpha z & z < 0 \end{cases} \qquad (\alpha \approx 0.01)$$
Gràfica: com ReLU, però la part esquerra no és plana sinó una recta gairebé horitzontal amb pendent $\alpha$. Rang: (−∞, +∞).
ELU (Exponential Linear Unit) — suavitza la zona negativa amb una exponencial:
$$f(z) = \begin{cases} z & z \geq 0 \ \alpha(e^z - 1) & z < 0 \end{cases} \qquad (\alpha \approx 1)$$
Gràfica: idèntica a ReLU a la dreta; a l'esquerra baixa suaument i s'aplana a $-\alpha$. Rang: (−α, +∞). Sortida mitjana més propera a zero que ReLU i sense colze brusc, a canvi de calcular una exponencial.
Softmax (per a sortida multiclasse)
A diferència de les anteriors, softmax no actua neurona a neurona sinó sobre tot el vector de sortides $z = (z_1, \dots, z_K)$ de l'última capa:
$$\text{softmax}(z)i = \frac{e^{z_i}}{\sum{j=1}^{K} e^{z_j}}$$
- Rang: cada component a (0, 1) i totes sumen exactament 1: una distribució de probabilitat sobre les $K$ classes.
- Intuïció: exponenciar amplifica les diferències (el $z_i$ més gran s'endú gairebé tota la probabilitat) i dividir per la suma normalitza.
- Ús: capa de sortida en classificació multiclasse. Quan el classificador de fotos de TecnoMarket miri una imatge i hagi de triar entre {portàtil, cafetera, aspiradora, monitor}, softmax retornarà una cosa com (0.85, 0.02, 0.03, 0.10): un 85 % de confiança en "portàtil".
Taula comparativa
| Funció | Fórmula | Rang | Es satura? | Cost | Ús principal avui |
|---|---|---|---|---|---|
| Esglaó | $z \geq 0 \Rightarrow 1$ | {0, 1} | — (no derivable) | Mínim | Històric (perceptró) |
| Sigmoide | $1/(1+e^{-z})$ | (0, 1) | Sí, tots dos extrems | Mitjà (exp) | Sortida binària |
| Tanh | $\frac{e^z - e^{-z}}{e^z + e^{-z}}$ | (−1, 1) | Sí, tots dos extrems | Mitjà (exp) | Ocultes en RNN/LSTM |
| ReLU | $\max(0, z)$ | [0, +∞) | No (costat positiu) | Mínim | Ocultes, per defecte |
| Leaky ReLU | $\max(\alpha z, z)$ | (−∞, +∞) | No | Mínim | Ocultes si hi ha neurones mortes |
| ELU | $z$ o $\alpha(e^z-1)$ | (−α, +∞) | Només costat negatiu | Mitjà (exp) | Ocultes, alternativa a ReLU |
| Softmax | $e^{z_i}/\sum e^{z_j}$ | (0,1), suma 1 | — | Mitjà | Sortida multiclasse |
Quina activació fer servir a cada capa segons el problema
L'elecció segueix dues regles diferents segons la capa:
Capes ocultes: comença sempre per ReLU. Si detectes moltes neurones mortes, prova Leaky ReLU o ELU. Reserva tanh per a arquitectures recurrents (mòdul 4). Evita la sigmoide en capes ocultes.
Capa de sortida: la decideix el tipus de problema, perquè la sortida ha de tenir la forma de la resposta que busques:
| Tipus de problema | Exemple TecnoMarket | Neurones de sortida | Activació de sortida |
|---|---|---|---|
| Regressió (nombre real) | Predir unitats venudes d'una cafetera la setmana vinent | 1 | Cap (lineal/identitat) |
| Classificació binària | És fraudulenta aquesta comanda? / És positiva aquesta ressenya? | 1 | Sigmoide |
| Classificació multiclasse (una sola classe correcta) | Aquesta foto és un portàtil, una cafetera, una aspiradora o un monitor? | K (una per classe) | Softmax |
| Multietiqueta (diverses classes alhora) | Etiquetar una ressenya amb diversos temes: "enviament", "preu", "qualitat" | K | Sigmoide a cada neurona |
Fixa't en la diferència entre les dues últimes files: softmax obliga que les probabilitats competeixin (sumen 1: una foto és una sola cosa); les sigmoides independents permeten que diverses etiquetes siguin certes alhora. A la lliçó d'optimització i funció de pèrdua veuràs que cadascuna d'aquestes sortides s'aparella amb una funció de pèrdua concreta.
Implementació en numpy i visualització amb matplotlib
Totes caben en poques línies. Guarda aquest codi a la teva carpeta tecnomarket-dl/ (per exemple com a activacions.py), perquè el reutilitzarem a la propera lliçó:
import numpy as np
import matplotlib.pyplot as plt
def esglao(z): return (z >= 0).astype(float)
def sigmoide(z): return 1 / (1 + np.exp(-z))
def tanh(z): return np.tanh(z) # numpy ja la porta
def relu(z): return np.maximum(0, z)
def leaky_relu(z, alpha=0.01):
return np.where(z >= 0, z, alpha * z)
def elu(z, alpha=1.0):
return np.where(z >= 0, z, alpha * (np.exp(z) - 1))
def softmax(z):
z = z - np.max(z) # truc d'estabilitat numèrica
e = np.exp(z)
return e / e.sum()Dos detalls importants:
np.where(condicio, a, b)tria element a element: on la condició és certa prena, on no,b. És la forma vectoritzada del "si z ≥ 0 llavors... si no...".- A
softmaxrestem el màxim abans d'exponenciar. No canvia el resultat matemàtic (numerador i denominador queden dividits per la mateixa constant $e^{z_{max}}$), però evita quenp.exp(1000)desbordi a infinit. Sense aquest truc, softmax falla amb entrades grans.
Ara dibuixem totes les corbes per fixar la intuïció visual:
z = np.linspace(-5, 5, 200) # 200 punts entre -5 i 5
funcions = [
("Esglao", esglao), ("Sigmoide", sigmoide), ("Tanh", tanh),
("ReLU", relu), ("Leaky ReLU", leaky_relu), ("ELU", elu),
]
fig, eixos = plt.subplots(2, 3, figsize=(12, 6))
for eix, (nom, f) in zip(eixos.flat, funcions):
eix.plot(z, f(z), linewidth=2)
eix.set_title(nom)
eix.axhline(0, color="gray", linewidth=0.5) # eix horitzontal de referència
eix.axvline(0, color="gray", linewidth=0.5) # eix vertical de referència
eix.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()En executar-ho veuràs en una sola figura les sis formes descrites al catàleg: el salt de l'esglaó, les dues "S" (una entre 0 i 1, l'altra entre −1 i 1), el colze de ReLU i les seves dues variants amb la zona negativa "rescatada". I una prova ràpida de softmax amb les puntuacions del classificador de fotos:
puntuacions = np.array([3.1, -0.5, 0.2, 1.4]) # portàtil, cafetera, aspiradora, monitor
probs = softmax(puntuacions)
print(np.round(probs, 3)) # -> [0.792 0.022 0.044 0.143]
print(probs.sum()) # -> 1.0La classe amb més puntuació (portàtil) concentra la probabilitat, però les altres no queden a zero: el model expressa la seva incertesa.
Un apunt final que connecta amb la propera lliçó: hem dit diverses vegades que sigmoide i tanh "se saturen" i que això dificulta l'aprenentatge. La raó exacta és que a les zones planes el seu pendent (derivada) és gairebé zero, i l'algorisme d'entrenament —backpropagation— multiplica pendents en cadena: molts nombres gairebé-zero multiplicats donen un zero pràctic, i les primeres capes deixen d'aprendre. És el famós vanishing gradient; el veurem sorgir de manera natural a la propera lliçó i les tècniques per combatre'l en profunditat al mòdul 5.
Errors Comuns i Consells
- Posar activació a la sortida d'una regressió. Si prediu unitats venudes i poses sigmoide a la sortida, la teva xarxa només podrà predir entre 0 i 1. Per a regressió, l'última capa va sense activació (o
activation="linear"a Keras, que és el mateix). - Fer servir softmax amb una sola neurona de sortida. Softmax sobre un vector d'un element retorna sempre 1.0, sigui quina sigui l'entrada. Per a binària: 1 neurona + sigmoide, o 2 neurones + softmax, però no ho barregis.
- Calcular softmax sense restar el màxim. Funciona amb nombres petits i explota amb grans (
np.exp(1000) = inf, iinf/inf = nan). Fes servir sempre la versió estable. - Sigmoide en moltes capes ocultes. És la recepta clàssica del vanishing gradient. En ocultes, ReLU per defecte.
- Ignorar les neurones mortes. Si després d'entrenar observes que moltes unitats ReLU treuen 0 per a tots els exemples, baixa el learning rate o canvia a Leaky ReLU/ELU.
- Triar l'activació de sortida sense pensar en la pèrdua. Van en parella (sigmoide ↔ entropia creuada binària, softmax ↔ entropia creuada categòrica). L'aparellament exacte el cobrim a la lliçó d'optimització.
Exercicis
- Derivades visuals. La derivada de la sigmoide és $\sigma'(z) = \sigma(z)(1 - \sigma(z))$. Implementa-la i dibuixa-la juntament amb la sigmoide a la mateixa gràfica per a $z \in [-6, 6]$. Quin és el seu valor màxim i on s'assoleix? Quant val aproximadament a $z = 5$? Relaciona el que veus amb el vanishing gradient.
- Classificador de sortida correcte. Per a cada projecte de TecnoMarket, indica quantes neurones de sortida faries servir i amb quina activació: (a) decidir si una ressenya és positiva o negativa; (b) classificar una foto entre 12 categories de producte; (c) predir l'import mitjà de compra d'un client el mes vinent; (d) marcar una ressenya amb les etiquetes que hi apliquin de {enviament, preu, qualitat, atenció}.
- XOR amb sigmoide. Reescriu l'MLP 2-2-1 que va resoldre XOR a la lliçó anterior substituint l'esglaó per la sigmoide (mantén els mateixos pesos:
W1=[[1,1],[1,1]],b1=[-0.5,-1.5],W2=[[1],[-2]],b2=[-0.5]). Multiplica abans tots els pesos i biaixos per 10. Calcula la sortida per a les quatre entrades i comprova que, arrodonint, continua sent XOR. Per què cal multiplicar per 10?
Solucions
Exercici 1.
def sigmoide_derivada(z):
s = sigmoide(z)
return s * (1 - s)
z = np.linspace(-6, 6, 200)
plt.plot(z, sigmoide(z), label="sigmoide")
plt.plot(z, sigmoide_derivada(z), label="derivada")
plt.legend(); plt.grid(True); plt.show()El màxim de la derivada és 0.25 i s'assoleix a $z = 0$. A $z = 5$ val aproximadament 0.0066: gairebé zero. Com que la derivada mai no supera 0.25, en encadenar diverses capes sigmoides els pendents es multipliquen (0.25 × 0.25 × ... → 0 ràpidament): aquesta és la llavor del vanishing gradient.
Exercici 2. (a) 1 neurona amb sigmoide (binària). (b) 12 neurones amb softmax (multiclasse excloent). (c) 1 neurona sense activació (regressió; l'import no està acotat a (0,1)). (d) 4 neurones, cadascuna amb la seva pròpia sigmoide (multietiqueta: una ressenya pot parlar de l'enviament i del preu alhora, així que les probabilitats no han de competir).
Exercici 3. Amb els pesos ×10 (b1=[-5,-15], etc.), les sumes ponderades queden lluny de zero i la sigmoide es comporta gairebé com l'esglaó: per a (0,0) la sortida és ≈0.007 → 0; per a (0,1) i (1,0), ≈0.98 → 1; per a (1,1), ≈0.01 → 0. Arrodonint, XOR. Cal multiplicar per 10 perquè amb els pesos originals les sumes cauen a la zona central i suau de la sigmoide (on la sortida ronda 0.3–0.6 en lloc d'acostar-se a 0 o a 1) i l'arrodoniment ja no reprodueix el comportament de l'esglaó. Moralitat: la sigmoide és un esglaó "estovat", i la magnitud dels pesos controla com s'hi assembla.
Conclusió
Ja saps per què les funcions d'activació no són un ornament sinó la condició perquè la profunditat serveixi d'alguna cosa: sense no linealitat, qualsevol pila de capes col·lapsa en una sola transformació lineal. Tens el catàleg complet —esglaó (història), sigmoide i tanh (les "S" que se saturen), ReLU i variants (l'estàndard en ocultes), softmax (la sortida multiclasse)— i les dues regles pràctiques: ReLU per defecte en capes ocultes, i a la sortida el que dicti el problema (res per a regressió, sigmoide per a binària, softmax per a multiclasse).
A més, totes les activacions modernes comparteixen una propietat que a l'esglaó li mancava: tenen derivada útil, un pendent que diu cap a on i quant corregir. Aquest pendent és just el que necessita l'algorisme que fa dues lliçons que ajornem: a la propera lliçó obrirem per fi la caixa de backpropagation i veurem com una xarxa completa —la nostra vella coneguda 3-4-2-1 inclosa— aprèn els seus pesos capa a capa.
Curs de Deep Learning
Mòdul 1: Introducció al Deep Learning
- Què és el Deep Learning?
- Història i evolució del Deep Learning
- Aplicacions del Deep Learning
- Conceptes bàsics de xarxes neuronals
- Preparació de l'entorn de treball
Mòdul 2: Fonaments de Xarxes Neuronals
- Perceptró i Perceptró Multicapa
- Funció d'activació
- Propagació cap endavant i cap enrere
- Optimització i funció de pèrdua
- La teva primera xarxa neuronal completa
Mòdul 3: Xarxes Neuronals Convolucionals (CNN)
- Introducció a les CNN
- Capes convolucionals i de pooling
- Arquitectures populars de CNN
- Aplicacions de CNN en reconeixement d'imatges
Mòdul 4: Xarxes Neuronals Recurrents (RNN)
- Introducció a les RNN
- LSTM i GRU
- Aplicacions de RNN en processament del llenguatge natural
- Seqüències i sèries temporals
Mòdul 5: Tècniques Avançades en Deep Learning
- Xarxes Generatives Adversàries (GAN)
- Autoencoders
- Transfer Learning
- Regularització i tècniques de millora
- Mecanismes d'atenció i Transformers
Mòdul 6: Eines i Frameworks
- Introducció a TensorFlow
- Introducció a PyTorch
- Comparació de frameworks
- Entorns de desenvolupament i recursos addicionals
- Desar, carregar i desplegar models
Mòdul 7: Projectes Pràctics
- Classificació d'imatges amb CNN
- Generació de text amb RNN
- Detecció d'anomalies amb Autoencoders
- Creació d'una GAN per a generació d'imatges
- Fine-tuning d'un model preentrenat
