Dato un modello addestrato, quando sbaglia, come facciamo a descrivere l’errore commesso? Nella Parte 1 abbiamo risposto a questa domanda scomponendo l’errore nella somma di tre parti ben distinte. Il bias dipende dal modello stesso. La varianza dipende invece dal fatto che il modello è stato addestrato su un campione finito e quindi varia al variare della composizione del dataset. E infine c’è il rumore, elemento che fa parte dei dati utilizzati e non si può eliminare in alcun modo. Il risultato che abbiamo ottenuto da questa scomposizione sta proprio nella sua natura additiva. Natura che emerge dal calcolo della media e che ci permette di studiare questi tre pezzi uno alla volta.
Nella Parte 2 abbiamo messo alla prova quanto appreso in un nuovo contesto. Passando dalla regressione alla classificazione, abbiamo visto come l’additività non sia più applicabile. Non esiste una media tra categorie, per questo motivo bisogna ragionare sulla moda. Ne è quindi venuto fuori che l’errore si scrive ancora in funzione di bias e varianza, ma non come somma, e che il contributo della varianza cambia segno a seconda del bias. Se la previsione dominante è sbagliata, un modello instabile sbaglia meno di uno stabile.
Qual è il punto in comune tra le prime due parti di questo articolo? La misura. In entrambi i casi si prende in esame un modello già addestrato, si osserva l’errore e lo si scompone. Alla fine della seconda parte, con il double descent, abbiamo anche anticipato che l’osservazione dell’errore dipende dal modo in cui valutiamo la capacità di generalizzare del modello.
Cosa manca? Uno strumento come il manometro legge la pressione, non la cambia. Nessuna delle due parti ci dice come intervenire sulle condizioni che producono l’errore che abbiamo letto.
Possiamo introdurre l’ultimo argomento di questa serie con una sola parola: regolarizzazione.
Dai palloncini ai pistoni
Nelle prime due parti il gas stava in un palloncino, ed era l’oggetto giusto finché si trattava di misurare. Un palloncino però ha un difetto per quello che dobbiamo fare adesso, e cioè che il suo volume dipende da quanto gas ci mettiamo dentro. Non può essere enorme e quasi vuoto, perché senza abbastanza gas si affloscia. Qui ci serve qualcosa che rappresenti la condizione in cui pochissime molecole vagano in uno spazio sterminato.
Spesso nei manuali di termodinamica si usa come esempio un cilindro con pistone. Ed è un’immagine che qui ci può tornare utile, perché il volume lo decide il pistone e non è determinato direttamente dal gas che contiene.
Nei due palloncini a sinistra la quantità di gas è diversa e il volume si adatta di conseguenza, perché un palloncino con poco gas si affloscia e non tiene la forma. Nei due cilindri a destra le molecole sono invece le stesse in entrambi i casi, e a stabilire il volume è soltanto la posizione del pistone.
La Parte 2 si è chiusa su una domanda. Un modello sovra-parametrizzato può assumere infinite configurazioni tutte compatibili con i dati, cioè è un gas con troppo volume a disposizione, eppure qualcosa lo fa assestare su una configurazione regolare invece che erratica.
Prima di dire cosa sia quel qualcosa, dobbiamo capire quanto è grande davvero quel volume. La risposta è interessante, ed è il vero motivo per cui la regolarizzazione è indispensabile.
Riprendiamo anche l’immagine del modello che passa vicino ai punti osservati. Il comportamento che assume non è affatto un dettaglio marginale. In alta dimensione, i dati osservati occupano infatti una porzione minuscola dello spazio delle possibili configurazioni. La maggior parte dello spazio si trova “tra” i dati. È proprio in questa regione, dove non abbiamo osservazioni dirette, che emerge la “forma” assunta dal modello.
Facciamo un esempio numerico. Prendiamo un problema descritto da $40$ variabili, cioè uno spazio a $40$ dimensioni, e suddividiamo ogni dimensione in $10$ intervalli. Nulla di particolarmente preciso, serve solo per avere un ordine di grandezza. Da questa partizione otteniamo $10^{40}$ regioni possibili dello spazio.
Attenzione al punto: le dimensioni le stabiliscono le variabili che descrivono il problema, mentre il numero di esempi disponibili dice soltanto quanto riusciamo a popolare quello spazio. Ed è dal confronto tra le due cose che nasce la difficoltà.
Se disponiamo di $10^4$ esempi, cioè diecimila punti, in media abbiamo un solo dato ogni
$$ \frac{10^{40}}{10^{4}} = 10^{36} \quad \text{regioni.} $$La maggior parte dello spazio rimane quindi completamente priva di osservazioni. I pochi punti disponibili sono dispersi e isolati in un enorme insieme di regioni mai osservate. È proprio in queste regioni che il modello estende la struttura appresa dai dati disponibili, e questa estensione ha un ruolo cruciale nel determinare la sua prestazione su dati nuovi. Nel Machine Learning il fenomeno prende il nome di maledizione della dimensionalità.
Otto dati osservati collocati in uno spazio a una, due e tre dimensioni. A ogni dimensione aggiunta il numero di regioni si moltiplica per dieci, mentre i dati disponibili restano gli stessi. Con quaranta dimensioni le regioni diventano $10^{40}$.
Proviamo a vedere il problema dal punto di vista del pistone. Immaginiamolo tirato quasi fino a fine corsa. Un gas rarefatto, in queste condizioni, occupa una porzione esigua dell’enorme volume disponibile. Le sue molecole possono disporsi in un numero sterminato di configurazioni, tutte ugualmente compatibili con lo stato macroscopico che osserviamo. Stiamo cioè osservando una condizione di massima incertezza. E in questo stato delle cose, spingere il pistone diventa un’azione finalizzata a ridurre lo spazio e rendere il sistema più prevedibile.
La regolarizzazione di fatto ha lo stesso compito. E lo fa prendendo in considerazione i due fenomeni che determinano il divario tra addestramento e test: l’overfitting e la presenza di regioni non vincolate.
Nel primo caso, il modello non si limita a rappresentare la struttura del fenomeno, ma si adatta ai dati di addestramento fino a incorporare anche le loro peculiarità accidentali e il rumore associato ai singoli campioni. La rappresentazione appresa diventa così troppo specifica rispetto agli esempi osservati e perde capacità di generalizzazione.
Le regioni non vincolate, invece, sono le porzioni dello spazio in cui i dati di addestramento non sono presenti, o sono estremamente scarsi. Qui le osservazioni forniscono poche o nessuna informazione diretta sul comportamento che il modello dovrebbe assumere. Di conseguenza il modello può produrre una grande varietà di soluzioni, tutte compatibili con i dati osservati ma molto diverse tra loro. In alta dimensione questo fenomeno diventa particolarmente rilevante, perché i dati tendono a essere estremamente dispersi, e quindi anche un insieme di addestramento molto numeroso può lasciare gran parte dello spazio priva di osservazioni.
A sinistra la curva rossa attraversa ogni punto osservato e ne incorpora anche il rumore, allontanandosi così dalla funzione tratteggiata che avrebbe dovuto approssimare. A destra le fasce grigie coprono gli intervalli privi di osservazioni, nei quali i dati non impongono al modello alcun comportamento.
La soluzione da cercare è quindi quella di far sì che la regolarizzazione causi un restringimento dello spazio delle possibilità, “spingendo” il modello verso le soluzioni che presentano migliori proprietà di generalizzazione. Quindi verso soluzioni più stabili, che variano in modo più graduale e che dipendono meno dai dettagli dei singoli campioni.
In altre parole, la regolarizzazione impedisce al modello di distribuirsi liberamente nelle regioni non vincolate dai dati e ne limita i gradi di libertà. Appunto come per il nostro pistone, non si impone dove debba trovarsi ogni particella, ma si limita lo spazio entro cui può distribuirsi.
Tutto dovrebbe essere reso il più semplice possibile, ma non più semplice
Questa frase, comunemente attribuita a Einstein, è una buona scusa per aggiungere una considerazione alla questione della regolarizzazione. La regolarizzazione nasce infatti dall’esigenza di limitare la complessità del modello senza comprometterne la capacità di generalizzare.
Una nota sulla citazione. La formulazione che tutti conosciamo non compare in nessuno scritto di Einstein. Deriva in realtà da una parafrasi che Roger Sessions pubblicò nel 1950 di un’osservazione einsteiniana del 1933, decisamente più prolissa e più cauta. Il che, per una frase sui rischi della semplificazione eccessiva, direi che calza a pennello.
Vedremo come arrivare a questo risultato cominciando dal modificare non la rete, ma il criterio con cui la giudichiamo durante l’addestramento: la loss.
Aggiungiamo elementi alla loss
Ed ecco la loss:
$$ \hat\phi = \operatorname*{argmin}_{\phi} \big[\,L(\phi)\,\big] = \operatorname*{argmin}_{\phi} \left[\sum_{i=1}^{N} \mathcal{L}\big(f(x_i,\phi),\,y_i\big)\right] $$La scrittura $\operatorname*{argmin}_\phi$ indica il valore di $\phi$ che rende minima l’espressione, mentre la sommatoria è la loss totale, cioè la somma degli errori commessi dal modello $f(x_i,\phi)$ su tutti gli $N$ esempi.
Per “spingere” il modello verso certe soluzioni aggiungiamo il termine $g(\phi)$ e il coefficiente $\lambda$:
$$ \hat\phi = \operatorname*{argmin}_{\phi} \left[\sum_{i=1}^{N} \mathcal{L}\big(f(x_i,\phi),\,y_i\big) + \lambda\cdot g(\phi)\right] $$Il termine $g(\phi)$ assume valori elevati per le configurazioni dei parametri che vogliamo penalizzare e valori più bassi per quelle che vogliamo favorire. Il coefficiente $\lambda$, che assumiamo positivo, determina invece il peso della preferenza introdotta da $g(\phi)$ rispetto all’aderenza ai dati.
Se è piccolo prevale l’aderenza ai dati, se è grande aumenta l’importanza della preferenza espressa attraverso $g(\phi)$.
Possiamo quindi interpretare $g(\phi)$ come una forza di richiamo, mentre $\lambda$ ne determina l’intensità. È il pistone che avanza e riduce il volume a disposizione delle molecole. Allo stesso modo il termine di regolarizzazione spinge i parametri verso la regione gradita, restringendo lo spazio che il gas può occupare. Il coefficiente $\lambda$ è la forza con cui premiamo sul pistone.
I tre cerchi rappresentano lo spazio che i parametri possono occupare per valori crescenti di $\lambda$. Le frecce sono la forza di richiamo esercitata da $g(\phi)$ e la loro lunghezza cresce insieme a $\lambda$. Più questa forza aumenta, più i parametri restano confinati vicino allo zero.
Ora, quali configurazioni penalizzare e quali favorire è una scelta che facciamo noi. Attraverso $g(\phi)$ introduciamo cioè nel modello una preferenza sulla soluzione da apprendere. Resta però una domanda. C’è un motivo per preferire certi parametri, oppure stiamo solo agendo in modo arbitrario?
La risposta arriva guardando da dove nascono le loss, cioè dal criterio di massima verosimiglianza.
$$ \hat\phi = \operatorname*{argmax}_{\phi} \left[\prod_{i=1}^{N} P(y_i \mid x_i, \phi)\right]. $$Qui $P(y_i\mid x_i,\phi)$ rappresenta la probabilità che il modello assegna all’uscita osservata $y_i$, dato l’input $x_i$ e i parametri $\phi$. In altre parole, misura quanto il modello considera plausibile la risposta corretta per quel particolare esempio.
Moltiplicando queste probabilità su tutti gli esempi del dataset otteniamo
$$ \prod_{i=1}^{N} P(y_i\mid x_i,\phi). $$Questo prodotto misura quanto l’intero dataset è compatibile con il modello. Se il modello assegna alta probabilità alle risposte osservate, la verosimiglianza è alta. Se invece assegna bassa probabilità a molte di esse, la verosimiglianza risulta bassa. Per questo il prodotto prende il nome di verosimiglianza del dataset.
Aggiungiamo ora una distribuzione a priori $P(\phi)$. Questa distribuzione descrive quanto consideriamo plausibili le diverse configurazioni dei parametri $\phi$ prima di osservare i dati. In questo modo possiamo incorporare nel modello una preferenza su quali soluzioni riteniamo più ragionevoli.
Il criterio diventa appunto
$$ \hat\phi = \operatorname*{argmax}_{\phi} \left[P(\phi)\prod_{i=1}^{N} P(y_i \mid x_i, \phi)\right]. $$Il primo fattore, $P(\phi)$, esprime ciò che assumevamo sui parametri prima di vedere i dati. Il secondo, lo abbiamo già visto, misura quanto bene quei parametri spiegano i dati osservati. Il prodotto mette quindi insieme, **ciò che in un primo momento reputavamo plausibile ** con ciò che i dati ci mostrano.
Questo criterio si chiama massimo a posteriori, o MAP (Maximum A Posteriori). La soluzione scelta è quella che, combinando informazione a priori e dati osservati, risulta più plausibile dopo aver visto il dataset.
Prendendo infine il logaritmo negativo, il prodotto si trasforma in una somma e il problema di massimizzazione diventa un problema di minimizzazione. In questo modo il termine di probabilità può essere espresso come un termine di regolarizzazione, secondo la relazione
$$ \lambda\cdot g(\phi) = -\log P(\phi). $$Il termine di regolarizzazione è quindi il logaritmo negativo di una distribuzione a priori sui parametri. Il che significa che penalizzare certi parametri equivale a dichiarare che a priori li riteniamo improbabili.
È la stessa struttura logaritmica che collega entropia e probabilità nel pezzo sul caffè, dove il logaritmo negativo di una probabilità ricompare come costo.
Quindi, alla fine, scegliere un termine di regolarizzazione significa stabilire quali valori dei parametri consideriamo plausibili prima di osservare i dati. E la teoria della probabilità fornisce esattamente il linguaggio e gli strumenti necessari per formalizzare questo tipo di assunzione a priori.
Regolarizzazione L2 (Weight Decay)
Finora $g(\phi)$ è rimasto un termine astratto. La forma più diffusa è anche la più semplice. Se vogliamo penalizzare i parametri che assumono valori grandi, basta agire sulla somma dei loro quadrati.
$$ \hat\phi = \operatorname*{argmin}_{\phi} \left[\sum_{i=1}^{N} \mathcal{L}\big(f(x_i,\phi),\,y_i\big) + \lambda \sum_{j} \phi_j^2\right] $$Qui l’indice $j$ scorre appunto su tutti i parametri. Questa è la norma L2, che in letteratura compare anche come regolarizzazione di Tikhonov o ridge regression. Quando i parametri di uno strato sono organizzati in una matrice, questa penalizzazione coincide con il quadrato della norma di Frobenius della matrice dei pesi, che è quindi lo stesso oggetto scritto in notazione matriciale.
Il legame con il paragrafo precedente è immediato. Il logaritmo negativo di una gaussiana centrata in zero contiene infatti proprio un termine quadratico. Per questo, introdurre una penalizzazione L2 equivale, dal punto di vista probabilistico, ad assumere che i parametri del modello $\phi_j$ seguano a priori una distribuzione gaussiana di media nulla. I valori piccoli sono quindi considerati più plausibili, mentre quelli molto grandi diventano progressivamente meno probabili. Anche $\lambda$ acquista in questa lettura un significato preciso, perché è inversamente proporzionale alla varianza di quella gaussiana: più stretta è la campana a priori, più forte è la penalizzazione.
Questo si vede direttamente nella formula, dove il termine $\lambda\sum_j \phi_j^2$ aumenta quanto più i parametri si allontanano da zero. Per esempio, se un parametro vale $\phi_j=1$, il suo contributo alla penalizzazione è $1^2=1$. Se vale $\phi_j=5$, il contributo diventa $5^2=25$. A parità di errore sui dati, il secondo modello viene quindi penalizzato molto di più. La L2 non è dunque una scelta fatta per consuetudine, in quanto esprime il fatto che un buon modello dovrebbe riuscire a generalizzare senza dover ricorrere a parametri troppo grandi.
Dai pesi piccoli alla funzione regolare. In una rete il termine si applica ai pesi e non ai bias (qui si intende l’intercetta della funzione lineare), e da qui viene il nome weight decay, cioè decadimento dei pesi. Ogni strato calcola la propria uscita come somma pesata delle attivazioni che riceve, quindi con pesi piccoli l’uscita varia poco anche quando l’ingresso varia molto. La cosa vale per ogni strato, e l’effetto si accumula lungo tutta la rete. Nel caso estremo, con tutti i pesi azzerati, l’uscita non dipende più dall’ingresso e resta il solo bias finale, che è la funzione più piatta immaginabile.
L’effetto di $\lambda$. Con $\lambda$ piccolo, il termine di regolarizzazione incide poco e la rete continua ad adattarsi a tutti i punti dei dati, compreso il rumore. Aumentando $\lambda$, la rete deve trovare un equilibrio tra due esigenze opposte: rimanere aderente ai dati e, allo stesso tempo, mantenere una funzione regolare. Di conseguenza, le oscillazioni più brusche vengono progressivamente attenuate. Se $\lambda$ diventa troppo grande, però, il termine di regolarizzazione prevale su quello di aderenza ai dati e la funzione risulta eccessivamente piatta, fino a non riuscire più a rappresentare adeguatamente i dati.
Gli stessi punti osservati, approssimati con tre valori crescenti di $\lambda$. Nel primo caso la curva attraversa ogni punto e ne segue tutte le oscillazioni. Nel secondo riproduce l'andamento generale senza inseguire i singoli valori. Nel terzo la penalizzazione prevale e la funzione diventa troppo piatta per descrivere i dati.
Nel linguaggio della Parte 2 si tratta di spostarsi lungo il compromesso tra bias e varianza, quello di un colpo al cerchio e uno alla botte. Una rete che si adattava troppo ai dati vede scendere la varianza, perché non è più costretta a passare per ogni punto. In cambio il bias sale, dato che l’insieme delle funzioni disponibili si è ristretto a quelle regolari.
La L2 è quindi la compressione, cioè il gesto di spingere il pistone. Il volume accessibile si riduce, le molecole, che qui sono i pesi, vengono costrette verso il centro e gli stati estremi diventano impossibili. I pesi grandi corrispondono alle molecole lontane e veloci, quelle dalle traiettorie violente. Un gas compresso è più ordinato e meno disperso, e a questo corrisponde una funzione più regolare.
N.B. Questa è una nota molto “tecnica”, potete saltarla se non siete interessati all’argomento.
L’efficacia della regolarizzazione $L_2$ come strumento per migliorare la generalizzazione nelle reti neurali è stata ampiamente discussa. Sebbene la penalizzazione $L_2$ (o weight decay) favorisca pesi di norma ridotta, la sola norma $L_2$ dei parametri non costituisce necessariamente una misura adeguata della complessità funzionale della rete. In particolare, per architetture con attivazioni positivamente omogenee, come le ReLU, la funzione rappresentata dalla rete può rimanere invariata a fronte di opportune riscalature dei pesi tra i diversi strati. Di conseguenza, la norma $L_2$ dei singoli pesi può variare senza riflettere direttamente la complessità della funzione appresa.
Un’alternativa consiste nel considerare la costante di Lipschitz della rete, che quantifica quanto rapidamente l’uscita del modello può variare al variare dell’ingresso. Per una rete feed-forward, un limite superiore della costante di Lipschitz può essere ottenuto come prodotto delle norme spettrali delle matrici dei pesi. Questa quantità compare in diverse teorie dei generalization bounds. In particolare, Bartlett, Foster e Telgarsky (2017) hanno introdotto un bound basato sulla spectral complexity, che dipende dal prodotto delle norme spettrali e da un termine correttivo legato alle altre norme dei pesi. Gli autori mostrano inoltre una correlazione empirica tra questa misura di complessità, la costante di Lipschitz e il rischio di generalizzazione.
Come scendere ubriachi da una montagna
Di solito, quando scendi a piedi da una montagna da sobrio, guardi attentamente il paesaggio, cerchi di calcolare la direzione della discesa più ripida, metti il piede in un punto sicuro, ti fermi, ricalcoli e procedi. È un metodo efficace ma lento. E soprattutto non è perfetto, perché anche il passo più prudente ha comunque una sua lunghezza. Dove il pendio è dolce arrivi più o meno dove volevi, ma dove è ripido il piede scavalca il punto che avevi scelto e atterri più in basso del previsto. Il risultato è che, senza averlo deciso, tendi a evitare le pareti verticali e a preferire i pendii larghi.
Mi hanno detto invece che, quando ti lanci giù per le pendici di una montagna (prendiamone una della Puglia, dove al massimo parliamo di colline), magari convinto di aver visto un grizzly inesistente, il tuo unico obiettivo è arrivare a fondo valle il prima possibile.
In questo caso, barcolli e fai passi imprevedibili. Ed è proprio questa imprevedibilità a rendere il metodo interessante. Se, per esempio, durante la discesa finisci dentro una piccola buca, cioè commetti un errore di percorso, il passo successivo potrebbe farti uscire da quella buca per puro caso. In questo modo puoi evitare di rimanere bloccato in un punto che sembra fondo valle ma non è e continuare a cercare la vera valle, quella più bassa. Inoltre, muovendoti senza fermarti continuamente a calcolare il passo successivo, riesci a scendere molto più velocemente.
In breve, la “discesa ubriaca” è caotica, ma è proprio quel caos a renderla efficace. I passi imprevedibili permettono di uscire casualmente dagli errori e di continuare a esplorare il terreno, mentre la velocità evita di spendere troppo tempo per cercare, passo dopo passo, la direzione perfetta. Ed è qualcosa di molto simile a quello che permette ai modelli di intelligenza artificiale di imparare rapidamente senza rimanere bloccati in una soluzione che sembra buona, ma che non è necessariamente la migliore.
A sinistra la traiettoria della discesa da sobri, fatta di passi brevi e regolari lungo la pendenza. A destra quella della discesa da ubriachi, i cui passi irregolari le permettono di abbandonare la conca superficiale in alto e di raggiungere il minimo più profondo.
L’idea della discesa ubriaca si ritrova anche nella Stochastic Gradient Descent (SGD), un metodo di ottimizzazione in cui i parametri del modello vengono aggiornati usando, a ogni passo, solo una parte dei dati invece dell’intero dataset. Questa parte dei dati prende il nome di batch. Si parla di “stochastic” proprio perché ogni batch cambia casualmente da un aggiornamento all’altro, introducendo una componente casuale nel percorso di discesa. Di conseguenza, anche il gradiente calcolato su di esso varia. Se cerchiamo quindi una loss continua che riproduca l’effetto medio degli aggiornamenti stocastici, accanto al termine dovuto ai passi finiti deve comparirne un secondo.
Comunque sia, se dovete provare qualcosa, fatelo su carta. Non provateci a casa, e soprattutto non provateci in montagna.
Ma fermiamoci un attimo per capire dove siamo arrivati. Nella sezione precedente abbiamo scritto un termine, gli abbiamo dato un peso e lo abbiamo aggiunto alla loss. Questa si chiama regolarizzazione esplicita.
Come si sarà capito, adesso stiamo parlando di un secondo metodo. Alcune scelte che facciamo per ragioni pratiche, e non con l’intenzione di regolarizzare, finiscono per esercitare esattamente lo stesso effetto. Nessuno le ha scritte nella loss, eppure ci sono. Questa si chiama regolarizzazione implicita.
Intanto vediamo che forma assume la loss che descrive ciò che la SGD fa davvero (mentre se volete ripassare il Gradient Descent in modo strano potete farlo nell’articolo dedicato: it’s all about origami part 2).
$$ \tilde L_{\mathrm{SGD}}(\phi) = \underbrace{ L(\phi) + \frac{\eta}{4} \left\lVert \frac{\partial L}{\partial\phi} \right\rVert^2 }_{\text{come nella GD}} + \underbrace{ \frac{\eta}{4M} \sum_{m=1}^{M} \left\lVert \frac{\partial L_m}{\partial\phi} - \frac{\partial L}{\partial\phi} \right\rVert^2 }_{\text{variazione tra i batch}} $$I simboli. $\eta$ è il learning rate già visto, cioè la lunghezza del passo. $M$ è il numero di batch in cui abbiamo diviso il dataset, e $m$ ne indica uno in particolare. $L_m$ è la loss calcolata su quel singolo batch, mentre $L$ è quella su tutti i dati. Le doppie barre indicano la lunghezza al quadrato di un vettore, quindi misurano quanto due direzioni sono distanti.
La prima parte della formula è il costo dei passi finiti di cui parlavamo, cioè quello che fa la GD anche senza batch. La loss $L(\phi)$ è la discesa che credevamo di fare, e il termine con il gradiente al quadrato è la preferenza per i pendii larghi che ci ritroviamo comunque a seguire (Barrett e Dherin, 2021). La seconda parte è ciò che aggiunge la SGD (Smith, Dherin, Barrett e De, 2021).
Per capire cosa c’è di particolare nella SGD, immaginiamo di dividere il dataset in tanti piccoli gruppi. La GD li analizza tutti insieme e decide in quale direzione muoversi. La SGD, invece, ne analizza uno alla volta. E ogni gruppo, naturalmente, può raccontare una storia leggermente diversa.
Un batch potrebbe dirci di andare verso destra, un altro un po’ più verso l’alto, un altro ancora in una direzione completamente diversa. Il gradiente calcolato su tutto il dataset rappresenta invece una sorta di direzione media.
L’ultimo termine della formula serve quindi a tenere conto di questa differenza. Ci dice quanto le indicazioni dei singoli batch si allontanano dalla direzione complessiva. Se i batch sono d’accordo, il termine è piccolo. Se invece sono in disaccordo, diventa grande.
Ed è proprio qui che compare un aspetto interessante. Questo termine non si limita a registrare il disaccordo tra i batch, lo penalizza e quindi spinge il modello verso le regioni in cui i gruppi di dati sono sostanzialmente d’accordo su dove andare. Nella letteratura si parla di gradient alignment.
Le frecce sottili indicano i gradienti calcolati sui singoli batch, quella spessa la loro direzione media. Nel caso di sinistra i batch suggeriscono direzioni molto diverse tra loro e l'ultimo termine della formula assume un valore elevato. In quello di destra le direzioni quasi coincidono e il termine si riduce quasi a zero.
Questo aiuta anche a capire perché, in pratica, la SGD possa funzionare meglio della GD e perché, spesso, i batch più piccoli risultino più efficaci di quelli grandi. Più il batch è piccolo, infatti, più le indicazioni dei singoli gruppi possono variare e di conseguenza questo effetto di regolarizzazione aumenta.
In altre parole, il rumore della SGD si comporta un po’ come la temperatura in un gas. Un sistema caldo tende a non stabilizzarsi nel minimo più profondo e stretto. L’agitazione lo rende più difficile da trattenere lì e favorisce le regioni di minimo più ampie, dove le configurazioni compatibili sono più numerose.
È lo stesso principio del $F = E - TS$ che abbiamo visto nel pezzo sul caffè. La temperatura dà maggior peso all’ampiezza delle regioni, cioè l’entropia, contro la profondità, cioè l’energia.
Due minimi di uguale profondità. In quello stretto le oscillazioni del sistema bastano a farlo risalire lungo le pareti e ad allontanarlo dal fondo. In quello ampio le stesse oscillazioni non sono sufficienti e il sistema vi rimane.
A questo punto però conviene chiarire un possibile equivoco. Prima abbiamo detto che regolarizzare significa comprimere il gas, ora diciamo che conviene scaldarlo, e sembrano due mosse opposte. In realtà sono due modi diversi di agire sul sistema. La L2 agisce sul volume, cioè su dove i pesi hanno il permesso di stare. La SGD agisce sulla temperatura, cioè su quanto il sistema è agitato mentre cerca dove sistemarsi. Un gas può benissimo essere compresso e caldo allo stesso tempo, e infatti nella pratica weight decay e batch piccoli si usano insieme.
Ecco perché le regioni di minimo più ampie tendono a generalizzare meglio. Ed ecco anche perché, entro certi limiti, conviene “scaldare” il sistema introducendo rumore o usando batch piccoli.
Fermarsi al momento giusto
Un metodo di regolarizzazione decisamente pratico consiste nell’interrompere l’addestramento prima che sia arrivato a convergenza. Questo metodo si chiama early stopping e la sua efficacia è dovuta al fatto che tendenzialmente la rete impara prima l’andamento sottostante ai dati e solo in un secondo momento inizia ad adattarsi al rumore. Fermandosi al momento giusto, si riesce a catturare l’andamento ideale senza incorporare il rumore.
La curva verde è l'errore misurato sui dati di addestramento e continua a diminuire. Quella rossa è l'errore sui dati nuovi, che dopo un minimo torna a crescere perché da quel momento il modello inizia ad adattarsi al rumore. Il punto evidenziato indica dove conviene interrompere l'addestramento.
L’early stopping può essere interpretato in due modi, che non sono necessariamente alternativi.
Da un lato, interrompere l’addestramento quando i pesi sono ancora relativamente vicini alla loro inizializzazione introduce una forma di regolarizzazione implicita molto vicina alla L2. Nel caso della regressione lineare, per esempio, fermare il gradient descent prima della convergenza impedisce ai pesi di crescere eccessivamente e favorisce quindi soluzioni con pesi più piccoli, che è esattamente ciò che otterremmo scrivendo una penalizzazione quadratica nella loss.
Dall’altro lato, fermarsi presto limita la complessità effettiva che il modello riesce a raggiungere. In questa lettura il numero di iterazioni diventa a tutti gli effetti un parametro che controlla la complessità, allo stesso modo in cui lo è il numero di parametri. E questo apre un collegamento diretto con il fenomeno del double descent rispetto al numero di epoche (epoch-wise double descent), in cui l’errore di generalizzazione varia in modo non monotono al crescere del tempo di addestramento: diminuisce, raggiunge un picco in prossimità della soglia di interpolazione e, superata questa soglia, torna a diminuire. Va detto che il legame tra epoche e complessità non è una spiegazione generale del fenomeno, che può dipendere anche dal modo in cui componenti diverse della rete vengono apprese a velocità differenti.
Ma perché, superata la soglia di interpolazione, l’errore torna a scendere invece di continuare a salire?
In prossimità della soglia di interpolazione, il modello dispone di un numero di parametri appena sufficiente per adattarsi ai dati. Di conseguenza lo spazio delle soluzioni che descrivono bene il dataset è molto ristretto. Il modello ha poca libertà di scegliere tra soluzioni diverse e può essere costretto ad adottare una soluzione particolarmente sensibile al rumore presente nei dati. È qui che questa fragilità diventa massima, e da qui nasce il picco dell’errore di generalizzazione.
Superata la soglia, lo scenario cambia. I parametri diventano più del necessario e le soluzioni compatibili con i dati diventano infinite. È allora che il problema non è più trovare una soluzione che interpoli i dati, ma capire quale, tra le infinite possibili, venga selezionata.
Vale la pena sottolineare un punto, perché è di fatto la risposta alla domanda lasciata aperta nella Parte 2. Nel double descent la selezione avviene anche quando nessuno ha scritto un termine di regolarizzazione nella loss. A scegliere, in quel caso, è il bias implicito dell’ottimizzatore, che tra le infinite soluzioni compatibili con i dati tende a convergere verso quella di norma più piccola. Il pistone, in altre parole, non lo spingiamo sempre noi. A volte è già posizionato in un determinato punto.
Altri metodi pratici. Fra i tanti, il più noto è probabilmente il dropout. A ogni iterazione si spegne casualmente un sottoinsieme delle unità nascoste. Nelle vecchie reti dense si arrivava a spegnerne circa la metà, mentre nelle architetture moderne si usano tassi molto più bassi. Ogni passaggio usa quindi una rete leggermente diversa.
Un modo intuitivo per capirne l’effeto, è pensare a un gruppo di programmatori che lavorano sullo stesso progetto. Se ogni programmatore conosce solo i file su cui lavora abitualmente, basta che uno di loro non sia disponibile perché il lavoro si blocchi. Se invece tutti conoscono abbastanza bene il progetto da poter lavorare anche quando qualcuno manca, il sistema è molto più robusto.
Il dropout impone alla rete qualcosa di simile. Poiché a ogni passaggio alcune unità vengono spente, la rete non può contare sempre sulle stesse unità per produrre una certa risposta. È quindi costretta a distribuire l’informazione e a costruire rappresentazioni che funzionano anche quando alcuni componenti vengono a mancare.
Poi c’è la data augmentation, che affronta lo stesso problema dal lato opposto. Invece di stringere il modello, aumenta il numero di dati artificialmente. Da ogni esempio se ne generano altri applicando trasformazioni che non ne cambiano il significato, come ruotare o ritagliare un’immagine. Tornando al conto delle $10^{36}$ regioni vuote, è il tentativo di popolarne qualcuna in più anziché vietare al modello di attraversarle.
Infine l’ensembling, che rinuncia proprio a scegliere. Si addestrano più modelli e se ne media la previsione. Nel linguaggio della Parte 1 è un approccio che impatta direttamente sulla varianza, perché mediando su più configurazioni le fluttuazioni dovute al particolare campione di addestramento tendono a cancellarsi.
Tutti e tre riducono il rischio che la rete si adatti troppo ai dettagli del training set e favoriscono soluzioni più robuste, capaci di generalizzare meglio a dati nuovi.
Dal Gas Ideale al Gas Reale
Ora possiamo dire di avere tutto il necessario per chiudere questo lungo articolo. E per farlo ripercorriamo quanto fatto dal punto di vista del nostro cilindro chiuso da un pistone mobile. All’interno c’è un gas, formato da un numero enorme di molecole che si muovono continuamente in tutte le direzioni. Quando queste molecole urtano contro il pistone, esercitano una forza che tende a spingerlo verso l’esterno. La pressione del gas nasce, a livello microscopico, proprio dalla somma di questi innumerevoli urti.
Per descrivere questo sistema possiamo iniziare con un modello molto semplice: il gas ideale.
Nel gas ideale facciamo due importanti semplificazioni. Immaginiamo che le molecole siano così piccole da poter trascurare il loro volume e supponiamo che non esercitino forze reciproche, se non durante gli urti. In questo modo le molecole possono essere considerate libere di muoversi all’interno del recipiente.
Il comportamento del gas è allora descritto dalla semplice relazione
$$ PV=nRT. $$Questa è la legge dei gas ideali. Non descrive un gas particolare, ma rappresenta un modello astratto, costruito eliminando alcuni dettagli della realtà per concentrarsi sulle relazioni fondamentali tra pressione, volume, temperatura e quantità di materia.
Finché queste semplificazioni sono ragionevoli, il modello funziona molto bene. Ma cosa succede quando il pistone comprime molto il gas?
A quel punto le molecole si avvicinano. Il loro volume non può più essere ignorato e le forze che esercitano l’una sull’altra diventano importanti. Le molecole, infatti, non sono punti descritti matematicamente e non sono completamente indipendenti. Si attraggono e si respingono.
Il gas reale è quindi diverso dal gas ideale proprio perché la realtà introduce dei vincoli che nel modello ideale si sceglie di ignorare.
È qui che entra in gioco Johannes Diderik van der Waals, fisico olandese vissuto tra il 1837 e il 1923. Nel 1873 propose un’equazione capace di correggere la legge dei gas ideali introducendo proprio gli effetti dovuti al volume delle molecole e alle loro interazioni:
$$ \left(P+\frac{an^2}{V^2}\right)(V-nb)=nRT. $$I due nuovi termini hanno un significato fisico molto concreto.
Il termine $b$ rende conto dello spazio che le molecole si portano via. Se il cilindro ha volume $V$, non tutto questo spazio è realmente disponibile per il movimento delle particelle, perché una parte è occupata dalle molecole stesse e una parte è resa inaccessibile dal fatto che due molecole non possono avvicinarsi oltre un certo limite. Per questo nell’equazione compare $V-nb$, dove $nb$ è il cosiddetto volume escluso.
Il termine $\frac{an^2}{V^2}$ rappresenta invece l’effetto delle attrazioni tra le molecole. Una molecola che sta per urtare il pistone viene richiamata all’indietro dalle compagne che si è lasciata dietro, e arriva quindi meno violentemente di quanto farebbe se fosse davvero libera. Il risultato è che la pressione effettivamente misurata sul pistone è più bassa di quella che prevederebbe il modello ideale, ed è per questo che il termine va sommato a $P$ per ricostruire il valore ideale.
A sinistra il gas ideale, le cui molecole sono trattate come punti privi di volume e senza interazioni reciproche. A destra il gas reale, dove il cerchio tratteggiato attorno a ogni molecola delimita lo spazio che le altre non possono occupare, mentre le linee indicano le forze di attrazione.
Van der Waals compie quindi un passaggio importante: non abbandona il modello ideale, lo corregge introducendo nella sua struttura i vincoli della realtà.
Ed è proprio questo passaggio che ci permette di stabilire un collegamento con la regolarizzazione nell’addestramento dei modelli.
Quando addestriamo un modello di machine learning, possiamo immaginare di avere un modello molto libero, capace di adattarsi ai dati di addestramento. Questa libertà è utile, ma può diventare un problema. Se il modello è troppo libero, può imparare non soltanto la struttura che ci interessa, ma anche il rumore e le particolarità accidentali presenti nei dati.
La regolarizzazione introduce allora un vincolo. Per esempio, la penalizzazione L2 rende costose le soluzioni caratterizzate da pesi troppo grandi. Il modello rimane libero di apprendere, ma non è più completamente libero di adattarsi a qualsiasi dettaglio dei dati.
Il parallelismo con van der Waals non è un’identità matematica. La sua equazione non è una regolarizzazione L2 e il termine $\frac{an^2}{V^2}$ non è, in senso tecnico, l’equivalente di una penalizzazione sui pesi. La somiglianza è invece nella logica della modellazione.
Nel gas ideale partiamo da un modello semplice e libero da vincoli, e nel gas reale introduciamo informazioni sulla struttura fisica del sistema, in quanto le molecole occupano spazio e interagiscono tra loro. Nell’apprendimento automatico partiamo da un modello che ha una certa capacità di adattarsi ai dati, e con la regolarizzazione introduciamo un vincolo che limita questa libertà e gli impedisce di inseguire indiscriminatamente ciò che osserva nei dati di addestramento.
In entrambi i casi, quindi, il passaggio fondamentale è lo stesso: un modello troppo libero viene reso più strutturato attraverso l’introduzione di vincoli.
Il pistone ci offre una buona immagine per capire questa idea. Nel gas ideale il pistone può essere descritto attraverso una relazione semplice, perché abbiamo scelto di ignorare ciò che accade a livello microscopico. Nel gas reale, invece, il movimento del pistone risente della presenza concreta delle molecole, del loro volume e delle loro interazioni. Allo stesso modo, nella regolarizzazione non chiediamo al modello di smettere di imparare, ma gli imponiamo una struttura che renda il suo apprendimento più controllato.
E qui si chiude anche il cerchio delle tre parti. Nella Parte 1 abbiamo imparato a leggere l’errore separandolo in bias, varianza e rumore. Nella Parte 2 abbiamo scoperto che quella lettura cambia natura quando cambia il problema, e che il segno stesso della varianza dipende dal contesto. In questa terza parte abbiamo smesso di leggere e abbiamo iniziato a spingere, scoprendo che spingere significa quasi sempre la stessa cosa: scambiare un po’ di varianza in cambio di un po’ di bias, e farlo nella direzione giusta.
Potremmo dire che van der Waals ci mostra una versione fisica della stessa intuizione.
Per descrivere meglio la realtà, non sempre dobbiamo rendere il modello più libero. Spesso dobbiamo aggiungere i vincoli giusti.
Parole chiave
- Regolarizzazione: insieme di tecniche che limitano la libertà del modello durante l’addestramento per ridurre l’overfitting e migliorare la capacità di generalizzare.
- Maledizione della dimensionalità: fenomeno per cui, all’aumentare del numero di variabili, lo spazio delle configurazioni cresce esponenzialmente mentre i dati disponibili rimangono sparsi in una porzione minuscola di esso.
- Regolarizzazione esplicita: termine aggiunto direttamente alla loss per penalizzare le configurazioni dei parametri indesiderate.
- Regolarizzazione implicita: effetto regolarizzante che emerge da scelte pratiche come l’uso di batch piccoli o l’inizializzazione dei parametri, senza che venga scritto alcun termine aggiuntivo nella loss.
- Regolarizzazione L2 (weight decay): forma di regolarizzazione esplicita che penalizza i parametri grandi aggiungendo alla loss la somma dei loro quadrati. Equivale ad assumere a priori che i parametri seguano una distribuzione gaussiana centrata in zero.
- Massima verosimiglianza: criterio di stima che sceglie i parametri che rendono massima la probabilità di osservare i dati. Da questo criterio derivano le funzioni di loss più comuni.
- Massimo a posteriori (MAP): estensione della massima verosimiglianza che incorpora una distribuzione a priori sui parametri. Il termine di regolarizzazione corrisponde al logaritmo negativo di questa distribuzione.
- SGD (Stochastic Gradient Descent): metodo di ottimizzazione che aggiorna i parametri usando a ogni passo solo un sottoinsieme casuale dei dati. Introduce rumore nel percorso di discesa, favorendo minimi più ampi che tendono a generalizzare meglio.
- Early stopping: tecnica che interrompe l’addestramento prima della convergenza, nel momento in cui l’errore sui dati di validazione smette di migliorare. Impedisce al modello di adattarsi al rumore dei dati di addestramento.
- Bias implicito dell’ottimizzatore: tendenza dell’algoritmo di ottimizzazione a selezionare, tra le infinite soluzioni compatibili con i dati, quelle con norma più piccola, anche in assenza di un termine di regolarizzazione esplicito.