A la lliçó anterior vam entrenar una xarxa completa amb les eines més bàsiques possibles: vam mesurar l'error amb el quadrat de la diferència i vam corregir amb descens del gradient pur sobre totes les dades alhora. Va funcionar, però totes dues eleccions eren provisionals. Aquesta lliçó les examina a fons, perquè són dues de les decisions de disseny més importants de qualsevol projecte: la funció de pèrdua defineix què vol dir "equivocar-se" (i ha de casar amb el tipus de problema i amb l'activació de sortida que vas triar a 02-02), i l'optimitzador defineix com es fa servir el gradient per corregir (i determina si el teu entrenament triga minuts o hores, o si directament no convergeix). Veurem les pèrdues estàndard amb fórmules i intuïció, les tres variants del descens del gradient, les patologies del learning rate, i els optimitzadors moderns —momentum, RMSprop i Adam— que faràs servir a la pràctica. Tanquem veient com tot això es declara a Keras amb una sola línia: compile().
Contingut
- Què és exactament una funció de pèrdua
- Pèrdues per a regressió: MSE i MAE
- Pèrdues per a classificació: entropia creuada binària i categòrica
- Taula de decisió: quina pèrdua per a quin problema
- Descens del gradient: batch, estocàstic i mini-batch
- El learning rate i les seves patologies
- Optimitzadors moderns: momentum, RMSprop i Adam
- Tot junt a Keras: compile()
Què és exactament una funció de pèrdua
La funció de pèrdua (loss) pren la predicció $\hat{y}$ i l'etiqueta real $y$ i retorna un sol nombre: com de malament ho ha fet la xarxa en aquest exemple (o, fent la mitjana, en un batch). Tot l'aprenentatge descrit a la lliçó de backpropagation comença derivant aquest nombre; per això la pèrdua ha de ser derivable i ha de penalitzar de manera sensata els errors del problema concret.
No és un detall tècnic: la pèrdua és el contracte que dones a la xarxa. Si el contracte està mal triat, la xarxa optimitzarà diligentment la cosa equivocada. La bona notícia és que per als tres tipus de problema estàndard (regressió, classificació binària, classificació multiclasse) hi ha respostes canòniques.
Pèrdues per a regressió: MSE i MAE
Per predir nombres continus —la demanda setmanal de cafeteres de TecnoMarket— les dues pèrdues bàsiques comparen predicció i realitat sobre els $m$ exemples:
Error quadràtic mitjà (MSE, Mean Squared Error):
$$\text{MSE} = \frac{1}{m}\sum_{i=1}^{m} (\hat{y}_i - y_i)^2$$
Error absolut mitjà (MAE, Mean Absolute Error):
$$\text{MAE} = \frac{1}{m}\sum_{i=1}^{m} |\hat{y}_i - y_i|$$
La diferència és en com tracten els errors grans. En elevar al quadrat, l'MSE castiga desproporcionadament les errades grosses: equivocar-se en 10 unitats pesa 100 vegades més que equivocar-se en 1 (no 10 vegades més). L'MAE tracta cada unitat d'error per igual.
Conseqüència pràctica amb TecnoMarket: suposa que la demanda real d'una setmana atípica (Black Friday) va ser de 500 unitats i el teu històric normal ronda les 50. Amb MSE, aquest únic punt extrem domina la pèrdua total i la xarxa deformarà les seves prediccions normals per no fallar tant allà; amb MAE, el punt pesa el que toca. Regla pràctica:
- MSE per defecte: gradients suaus, entrenament estable, i penalitzar fort els errors grans sol ser el que es vol.
- MAE quan les teves dades tenen valors atípics (outliers) que no vols que segrestin l'entrenament.
import numpy as np
y_real = np.array([48, 52, 45, 500]) # demanda real; l'ultima setmana va ser Black Friday
y_pred = np.array([50, 50, 50, 60]) # prediccio d'un model "normal"
mse = np.mean((y_pred - y_real) ** 2) # -> 48405.25 (l'outlier ho domina tot)
mae = np.mean(np.abs(y_pred - y_real)) # -> 112.25 (mes representatiu del dia a dia)Pèrdues per a classificació: entropia creuada binària i categòrica
Per classificar podríem fer servir MSE ("la probabilitat predita menys l'etiqueta, al quadrat", com vam fer provisionalment a la lliçó anterior), però existeix una pèrdua molt més ben adaptada a sortides que són probabilitats: l'entropia creuada (cross-entropy).
Entropia creuada binària (BCE) — per a sortida sigmoide amb etiquetes 0/1:
$$\text{BCE} = -\frac{1}{m}\sum_{i=1}^{m} \Big[ y_i \log \hat{y}_i + (1-y_i)\log(1-\hat{y}_i) \Big]$$
La fórmula espanta menys del que sembla, perquè per a cada exemple només sobreviu un dels dos sumands:
- Si $y = 1$ (era frau), la pèrdua és $-\log \hat{y}$: val gairebé 0 si la xarxa va dir $\hat{y} \approx 1$ (encert segur) i tendeix a infinit si va dir $\hat{y} \approx 0$ (error amb total confiança).
- Si $y = 0$, simètricament, la pèrdua és $-\log(1-\hat{y})$.
Aquesta és la intuïció clau: l'entropia creuada castiga brutalment la confiança equivocada. Dir "2 % de probabilitat de frau" en una comanda que era frau costa $-\log(0.02) \approx 3.9$; dir "40 %" només costa $0.92$. Amb MSE la diferència seria molt més tèbia (0.96 davant de 0.36), i a més MSE + sigmoide produeix gradients diminuts just quan la xarxa està més equivocada (per la saturació que vam veure a 02-02); la parella sigmoide + BCE cancel·la aquest problema i aprèn ràpid precisament en els errors greus.
Entropia creuada categòrica (CCE) — per a sortida softmax amb $K$ classes:
$$\text{CCE} = -\frac{1}{m}\sum_{i=1}^{m} \log \hat{y}_{i,c_i}$$
on $\hat{y}_{i,c_i}$ és la probabilitat que la xarxa va assignar a la classe correcta de l'exemple $i$. Lectura directa: la pèrdua només mira quanta probabilitat vas donar a la resposta bona. Si el classificador de fotos de TecnoMarket veu una cafetera i el seu softmax assigna (portàtil 0.05, cafetera 0.90, aspiradora 0.03, monitor 0.02), la pèrdua és $-\log(0.90) = 0.105$: bé. Si va assignar cafetera 0.10, la pèrdua és $-\log(0.10) = 2.30$: càstig seriós.
A Keras veuràs dues variants de la CCE segons el format de les etiquetes: categorical_crossentropy si són one-hot ([0,1,0,0]) i sparse_categorical_crossentropy si són enters (1). Són la mateixa matemàtica amb codificacions d'entrada diferents; la variant sparse ens estalviarà un pas de conversió a la propera lliçó.
Taula de decisió: quina pèrdua per a quin problema
Aquesta taula completa la d'activacions de sortida de 02-02 — cada fila és la parella activació + pèrdua que va junta:
| Problema | Exemple TecnoMarket | Activació de sortida | Pèrdua | Nom a Keras |
|---|---|---|---|---|
| Regressió | Predir la demanda setmanal d'un producte | Cap (lineal) | MSE (o MAE amb outliers) | "mse" / "mae" |
| Classificació binària | Comanda fraudulenta? Ressenya positiva? | Sigmoide (1 neurona) | Entropia creuada binària | "binary_crossentropy" |
| Multiclasse (etiquetes one-hot) | Foto → 1 de 12 categories de producte | Softmax (K neurones) | Entropia creuada categòrica | "categorical_crossentropy" |
| Multiclasse (etiquetes enteres) | Igual, amb etiquetes 0..11 | Softmax (K neurones) | CCE dispersa | "sparse_categorical_crossentropy" |
| Multietiqueta | Ressenya → temes {enviament, preu, qualitat} | Sigmoide (K neurones) | BCE sobre cada sortida | "binary_crossentropy" |
Descens del gradient: batch, estocàstic i mini-batch
A la lliçó anterior vam calcular el gradient fent servir les 400 comandes alhora a cada actualització. Aquesta és una de tres estratègies possibles, que es diferencien en quants exemples miren abans de cada correcció:
| Variant | Exemples per actualització | Avantatges | Inconvenients |
|---|---|---|---|
| Batch (per lots complet) | Tots ($m$) | Gradient exacte, trajectòria suau | Lentíssim i prohibitiu en memòria amb datasets grans; 1 sola actualització per època |
| Estocàstic (SGD pur) | 1 | Actualitzacions barates i freqüents; el soroll ajuda a escapar de mals racons | Trajectòria molt erràtica; desaprofita la vectorització de la GPU |
| Mini-batch | Un lot de 32–256 | Equilibri: gradient raonable, aprofita la GPU, moltes actualitzacions per època | Cal triar la mida del batch |
La intuïció amb TecnoMarket: per ajustar la política antifrau podries esperar a analitzar totes les comandes de l'any (batch: decisió molt informada, un cop l'any), reaccionar després de cada comanda individual (estocàstic: rapidíssim però histèric, una sola comanda estranya et fa fer tombs), o revisar cada matí el lot de comandes del dia anterior (mini-batch: freqüent i estable). L'estàndard absolut en deep learning és mini-batch, i és el que el paràmetre batch_size de Keras controla — el mateix "batch" del vocabulari de 01-04. Nota terminològica: a la pràctica, quan algú diu "SGD" gairebé sempre es refereix a mini-batch SGD.
Amb mini-batches, una època ja no és una actualització sinó moltes: amb 60 000 exemples i batch_size=32, cada època són 1 875 actualitzacions de pesos.
El learning rate i les seves patologies
El learning rate $\eta$ multiplica el gradient a cada actualització: $w \leftarrow w - \eta \nabla L$. Ja el coneixes des de la regla del perceptró i l'aixeta de la dutxa; ara, els seus modes de fallada. Imagina la pèrdua com una vall i tu baixant a cegues fent passos de longitud $\eta$:
- $\eta$ massa gran: saltes d'un vessant a l'oposat. La pèrdua oscil·la o fins i tot divergeix (creix fins a
nan, com vas veure a l'exercici 3 de la lliçó anterior). - $\eta$ una mica gran: baixes ràpid al principi però després rebotes al voltant del fons sense afinar: la pèrdua s'estanca en un valor mediocre i sorollós.
- $\eta$ massa petit: cada pas és mil·limètric. La pèrdua baixa de manera bonica i monòtona… i després d'hores encara és lluny del fons. A més et pots quedar encallat al primer replà que trobis.
- $\eta$ adequat: descens ràpid al principi que es va assentant. A la pràctica es troba provant potències de 10 (0.1, 0.01, 0.001…) i mirant la corba de pèrdua.
Un truc clàssic és reduir $\eta$ durant l'entrenament (passos grans al principi, fins al final). Els optimitzadors moderns de l'apartat següent automatitzen en gran part aquesta gestió.
Optimitzadors moderns: momentum, RMSprop i Adam
El descens del gradient pur (SGD) fa servir a cada pas només el gradient actual. Els optimitzadors moderns li afegeixen memòria per navegar millor la vall de la pèrdua.
Momentum: la bola que roda
$$v \leftarrow \beta v - \eta \nabla L \qquad w \leftarrow w + v$$
En lloc de fer passos independents, mantenim una velocitat $v$ que acumula els gradients recents ($\beta \approx 0.9$: cada pas conserva el 90 % de l'impuls anterior). Intuïció: una bola pesant rodant vessant avall. Dos beneficis: en direccions on el gradient apunta consistentment igual, la bola accelera; en direccions on el gradient canvia de signe a cada pas (les oscil·lacions de vessant a vessant), els impulsos oposats es cancel·len i la trajectòria se suavitza. A més, l'impuls ajuda a travessar petits replans i sots.
RMSprop: un learning rate a mida de cada paràmetre
$$s \leftarrow \beta s + (1-\beta)(\nabla L)^2 \qquad w \leftarrow w - \frac{\eta}{\sqrt{s} + \epsilon} \nabla L$$
RMSprop porta, per a cada paràmetre per separat, una mitjana mòbil $s$ del quadrat dels seus gradients recents, i divideix el pas per la seva arrel. Efecte: els paràmetres amb gradients històricament enormes fan passos moderats (se'ls frena) i els de gradients minúsculs fan passos relativament més grans (se'ls anima). És a dir: deixa d'haver-hi un únic $\eta$ per a 29 (o 29 milions de) paràmetres amb escales diferents — cadascun rep un pas adaptat.
Adam: momentum + RMSprop
Adam (Adaptive Moment Estimation) combina totes dues idees: manté la mitjana mòbil del gradient (com momentum) i la mitjana mòbil del seu quadrat (com RMSprop), amb una petita correcció d'arrencada, i les fa servir juntes. Els seus hiperparàmetres per defecte (learning_rate=0.001, $\beta_1=0.9$, $\beta_2=0.999$) funcionen bé en una enorme varietat de problemes, i per això Adam és l'optimitzador per defecte amb què començar qualsevol projecte.
| Optimitzador | Idea afegida | Memòria que guarda | Quan fer-lo servir |
|---|---|---|---|
| SGD | Cap (base) | Res | Docència; producció amb ajust expert |
| SGD + momentum | Inèrcia / velocitat | 1 valor per paràmetre | Clàssic en visió, molt bon resultat final ben ajustat |
| RMSprop | Pas adaptat per paràmetre | 1 valor per paràmetre | Històric en xarxes recurrents (mòdul 4) |
| Adam | Momentum + adaptació | 2 valors per paràmetre | Per defecte: robust gairebé sense ajust |
Matís honest: Adam convergeix ràpid "sense tocar res", però un SGD+momentum finament ajustat de vegades assoleix solucions lleugerament millors en visió. Per a aquest curs: comença sempre amb Adam; considera alternatives només quan tinguis un motiu.
Tot junt a Keras: compile()
Tot l'anterior es declara a Keras en una sola crida, el pas compile() que converteix una arquitectura en un model entrenable. Encara no construirem el model complet (això és la propera lliçó), només llegirem aquesta línia amb ulls nous:
from tensorflow import keras
# Deteccio de frau (binaria): sigmoide a la sortida + BCE + Adam
model.compile(
optimizer="adam", # l'optimitzador de l'apartat 7
loss="binary_crossentropy", # la perdua de la taula de decisio
metrics=["accuracy"], # metriques NOMES per observar, no s'optimitzen
)
# Variant amb hiperparametres explicits:
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=0.001),
loss="binary_crossentropy",
metrics=["accuracy"],
)
# Dos altres projectes de TecnoMarket, mateixa estructura:
# - Classificador de fotos (12 classes, etiquetes enteres):
# optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"]
# - Prediccio de demanda (regressio):
# optimizer="adam", loss="mse", metrics=["mae"]Punts que has de tenir clars en llegir-lo:
lossés el que s'optimitza;metricsés el que s'observa. L'accuracy no és derivable (és un recompte d'encerts), així que no pot ser la pèrdua; es mostra perquè els humans seguim el progrés.- La cadena
"adam"fa servir els valors per defecte; l'objectekeras.optimizers.Adam(...)permet ajustar el learning rate quan calgui. - El
batch_size(mini-batch) no va acompile()sinó afit(), juntament amb les èpoques — ho veurem en acció a la propera lliçó. - La coherència activació-de-sortida ↔ pèrdua és responsabilitat teva: Keras no t'avisarà si aparelles softmax amb
binary_crossentropy; simplement entrenarà malament.
Errors Comuns i Consells
- Aparellar malament sortida i pèrdua. Els tres aparellaments vàlids són: lineal+MSE/MAE, sigmoide+BCE, softmax+CCE. Qualsevol altra combinació (softmax amb BCE, sigmoide amb CCE…) entrena estrany o directament malament, sovint sense donar cap error explícit.
categorical_crossentropyamb etiquetes enteres. Si les teves etiquetes són0..K-1(no one-hot) i fas servir la CCE normal, Keras llança un error de formes o aprèn brossa. Fes servirsparse_categorical_crossentropyo converteix ambkeras.utils.to_categorical.- Optimitzar l'accuracy directament. No es pot: no és derivable. La pèrdua és el substitut derivable; accepta que de vegades la pèrdua baixa sense que l'accuracy es mogui (la xarxa guanya confiança en encerts que ja tenia).
- Batch massa gran "perquè va més ràpid". Cada època té menys actualitzacions i el gradient perd el soroll beneficiós; a més pot esgotar la memòria de la GPU. Comença a 32 o 64.
- Canviar d'optimitzador abans que de learning rate. Si l'entrenament va malament, el primer que cal tocar és $\eta$ (prova ÷10 i ×10); canviar SGD per Adam sense revisar $\eta$ és tractar el símptoma.
- Comparar pèrdues entre problemes diferents. Un MSE de 0.05 i una BCE de 0.05 no són comparables ni "bons" en abstracte; la pèrdua només té sentit comparada amb ella mateixa al llarg de l'entrenament (i amb una línia base ximple, com predir sempre la mitjana).
Exercicis
- Entropia creuada a mà. El detector de frau avalua 4 comandes amb etiquetes reals
y = [1, 0, 1, 0]i prediu probabilitatsy_hat = [0.9, 0.2, 0.3, 0.95]. Calcula la BCE total (mitjana de les 4) amb numpy i a mà terme a terme. Quina comanda aporta més pèrdua i per què? - Elecció raonada. Per a cada cas de TecnoMarket, indica activació de sortida, pèrdua (nom de Keras) i una mètrica raonable: (a) estimar el temps de lliurament en dies d'una comanda; (b) classificar tiquets de suport en {facturació, enviament, garantia, altres}; (c) decidir si mostrar una oferta a un client (sí/no); (d) predir el preu de recompra de mòbils usats sabent que hi ha taxacions atípiques ocasionals.
- Cursa d'optimitzadors. Reutilitza la xarxa numpy 3-8-1 de la lliçó anterior i afegeix momentum a l'actualització (guarda una velocitat
vW1, vb1, vW2, vb2inicialitzada a zeros i aplica $v = 0.9v - \eta \nabla$; $w = w + v$). Entrena 3000 èpoques amb SGD pur i amb momentum fent servir la mateixa $\eta = 0.5$ i compara la pèrdua a les èpoques 100, 500 i 1000.
Solucions
Exercici 1.
y = np.array([1, 0, 1, 0])
y_hat = np.array([0.9, 0.2, 0.3, 0.95])
bce = -np.mean(y*np.log(y_hat) + (1-y)*np.log(1-y_hat)) # -> 1.135Terme a terme: $-\log(0.9)=0.105$; $-\log(1-0.2)=0.223$; $-\log(0.3)=1.204$; $-\log(1-0.95)=2.996$. Mitjana ≈ 1.13. La que més aporta és la quarta comanda (pèrdua ≈ 3.0): la xarxa va dir "95 % frau" i era legítima — confiança alta equivocada, just el que l'entropia creuada castiga amb més duresa (més i tot que la tercera comanda, que també falla però amb menys convicció).
Exercici 2. (a) Regressió: sortida lineal, loss="mse", mètrica mae (interpretable en dies). (b) Multiclasse de 4 categories: softmax de 4 neurones, sparse_categorical_crossentropy (etiquetes enteres), mètrica accuracy. (c) Binària: 1 sigmoide, binary_crossentropy, accuracy. (d) Regressió amb outliers declarats: sortida lineal, loss="mae" (robusta davant de taxacions atípiques), mètrica mae.
Exercici 3. Canvis mínims al bucle d'entrenament:
vW1 = np.zeros_like(W1); vb1 = np.zeros_like(b1)
vW2 = np.zeros_like(W2); vb2 = np.zeros_like(b2)
# ... despres de calcular dW1, db1, dW2, db2 al backward:
vW1 = 0.9*vW1 - eta*dW1; W1 += vW1
vb1 = 0.9*vb1 - eta*db1; b1 += vb1
vW2 = 0.9*vW2 - eta*dW2; W2 += vW2
vb2 = 0.9*vb2 - eta*db2; b2 += vb2Resultat típic: amb momentum la pèrdua a l'època 100 ja és on l'SGD pur arriba cap a la 400–600; a l'època 1000 tots dos s'acosten al mateix valor final, però momentum hi va arribar molt abans. (Si amb momentum la pèrdua oscil·la al principi, és la inèrcia acumulant massa impuls: baixa $\eta$ a 0.1 i torna a comparar — bon exemple que optimitzador i learning rate s'ajusten junts.)
Conclusió
Ja tens les dues decisions d'entrenament sota control. La funció de pèrdua tradueix "equivocar-se" a un nombre derivable, i es tria pel tipus de problema formant parella amb l'activació de sortida: lineal+MSE/MAE per a regressió, sigmoide+BCE per a binària, softmax+CCE per a multiclasse. L'optimitzador decideix com fer servir el gradient: mini-batch com a estratègia universal de dades, learning rate com l'hiperparàmetre més delicat, i Adam (momentum + adaptació per paràmetre) com a punt de partida robust. I has vist que a Keras tot això es declara en una línia de compile().
Amb això, el mòdul ha completat totes les peces: neurona i capes (02-01), activacions (02-02), forward i backward (02-03), pèrdues i optimitzadors (02-04). A la propera lliçó les ensamblem totes: construiràs, entrenaràs i avaluaràs a Keras la teva primera xarxa neuronal completa sobre un dataset real d'imatges, seguint la metodologia del curs — prototip públic primer, TecnoMarket després.
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
