Dapprendimento continuo ha fatto un passo da gigante nel mondo dell’intelligenza artificiale. Al momento, le reti neurali superano altri tipi di algoritmi su dati non tabulari: immagini, video, audio, ecc. I modelli di deep learning di solito hanno una forte complessità e forniscono milioni o addirittura miliardi di parametri addestrabili. Ecco perché nell’era moderna è essenziale utilizzare tecniche di accelerazione per ridurre i tempi di allenamento.
Uno degli algoritmi più comuni eseguiti durante l’allenamento è propagazione all’indietro consistente nel modificare i pesi di una rete neurale rispetto ad una data funzione di perdita. La backpropagation viene solitamente eseguita tramite discesa del gradiente che tenta di far convergere passo dopo passo la funzione di perdita verso un minimo locale.
A quanto pare, la discesa del gradiente ingenua non è solitamente una scelta preferibile per addestrare una rete profonda a causa del suo lento tasso di convergenza. Ciò ha spinto i ricercatori a sviluppare algoritmi di ottimizzazione che accelerano la discesa del gradiente.
Prima di leggere questo articolo, si consiglia vivamente di conoscere il media mobile esponenziale concetto utilizzato negli algoritmi di ottimizzazione. In caso contrario, puoi fare riferimento all’articolo qui sotto.
La discesa del gradiente è l’algoritmo di ottimizzazione più semplice che calcola i gradienti della funzione di perdita rispetto ai pesi del modello e li aggiorna utilizzando la seguente formula:
Per capire perché la discesa del gradiente converge lentamente, guardiamo l’esempio seguente di a burrone dove una data funzione di due variabili dovrebbe essere minimizzata.
Un burrone è un’area in cui la superficie è molto più ripida in una dimensione che in un’altra
Dall’immagine possiamo vedere che il punto di partenza e i minimi locali hanno coordinate orizzontali diverse e sono coordinate verticali quasi uguali. Utilizzando la discesa del gradiente per trovare i minimi locali è probabile che la funzione di perdita oscilli lentamente verso gli assi verticali. Questi rimbalzi si verificano perché la discesa del gradiente non memorizza alcuna cronologia dei gradienti precedenti, rendendo i passaggi del gradiente più indeterminati ad ogni iterazione. Questo esempio può essere generalizzato a un numero maggiore di dimensioni.
Di conseguenza, sarebbe rischioso utilizzare un tasso di apprendimento elevato poiché potrebbe portare a una disconvergenza.
Sulla base dell’esempio sopra, sarebbe auspicabile creare una funzione di perdita eseguendo passi più grandi nella direzione orizzontale e passi più piccoli in quella verticale. In questo modo la convergenza sarebbe molto più rapida. Questo effetto è ottenuto esattamente da Momentum.
Momentum utilizza una coppia di equazioni ad ogni iterazione:
La prima formula utilizza una media in movimento esponenziale per i valori del gradiente dw. Fondamentalmente, viene fatto per memorizzare informazioni di tendenza su una serie di valori di gradiente precedenti. La seconda equazione esegue il normale aggiornamento della discesa del gradiente utilizzando il valore della media mobile calcolato sull’iterazione corrente. α è il tasso di apprendimento dell’algoritmo.
Lo slancio può essere particolarmente utile per casi come quelli sopra. Immagina di aver calcolato i gradienti su ogni iterazione come nell’immagine sopra. Invece di usarli semplicemente per aggiornare i pesi, prendiamo diversi valori passati ed eseguiamo letteralmente l’aggiornamento nella direzione della media.
Sebastian Ruder descrive concisamente l’effetto di Momentum nel suo carta: “Il termine quantità di moto aumenta per le dimensioni i cui gradienti puntano nelle stesse direzioni e riduce gli aggiornamenti per le dimensioni i cui gradienti cambiano direzione. Di conseguenza, otteniamo una convergenza più rapida e un’oscillazione ridotta”.
Di conseguenza, gli aggiornamenti eseguiti da Momentum potrebbero apparire come nella figura seguente.
In pratica, la quantità di moto di solito converge molto più velocemente della discesa del gradiente. Con Momentum ci sono anche meno rischi nell’utilizzare tassi di apprendimento più elevati, accelerando così il processo di formazione.
In Momentum si consiglia di scegliere un β vicino a 0,9.
AdaGrad è un altro ottimizzatore con l’obiettivo di adattare la velocità di apprendimento ai valori del gradiente calcolati. Potrebbero verificarsi situazioni in cui durante l’allenamento, una componente del vettore peso ha valori di gradiente molto grandi mentre un’altra ne ha estremamente piccoli. Ciò accade soprattutto nei casi in cui un parametro poco frequente del modello sembra avere una scarsa influenza sulle previsioni. Vale la pena notare che con parametri frequenti tali problemi solitamente non si verificano poiché, per il loro aggiornamento, il modello utilizza molti segnali di previsione. Poiché per il calcolo del gradiente vengono prese in considerazione molte informazioni provenienti dai segnali, i gradienti sono generalmente adeguati e rappresentano una direzione corretta verso il minimo locale. Tuttavia, questo non è il caso dei parametri rari che possono portare a gradienti estremamente ampi e instabili. Lo stesso problema può verificarsi con dati sparsi in cui sono presenti troppo poche informazioni su determinate funzionalità.
AdaGrad affronta il problema di cui sopra adattando in modo indipendente il tasso di apprendimento per ciascuna componente di peso. Se i gradienti corrispondenti a una certa componente del vettore dei pesi sono grandi, allora il rispettivo tasso di apprendimento sarà piccolo. Al contrario, per gradienti più piccoli, il tasso di apprendimento sarà maggiore. In questo modo, Adagrad affronta i problemi dei gradienti di fuga ed esplosione.
Sotto il cofano, Adagrad accumula quadrati in termini di elementi dw² di gradienti da tutte le iterazioni precedenti. Durante l’aggiornamento del peso, invece di utilizzare il normale tasso di apprendimento α, AdaGrad lo ridimensiona dividendo α per la radice quadrata dei gradienti accumulati √vₜ. Inoltre, un piccolo termine positivo ε viene aggiunto al denominatore per evitare una potenziale divisione per zero.
Il più grande vantaggio di AdaGrad è che non è più necessario regolare manualmente la velocità di apprendimento poiché si adatta durante l’allenamento. Tuttavia, c’è un lato negativo di AdaGrad: il tasso di apprendimento diminuisce costantemente con l’aumento delle iterazioni (il tasso di apprendimento è sempre diviso per un numero cumulativo positivo). Pertanto l’algoritmo tende a convergere lentamente durante le ultime iterazioni dove diventa molto basso.
RMSProp è stato elaborato come miglioramento rispetto ad AdaGrad che affronta il problema del decadimento del tasso di apprendimento. Analogamente ad AdaGrad, RMSProp utilizza una coppia di equazioni per le quali l’aggiornamento del peso è assolutamente lo stesso.
Tuttavia, invece di memorizzare una somma cumulativa di gradienti quadrati dw² per vₜ, la media mobile esponenziale viene calcolata per i gradienti quadrati dw². Gli esperimenti mostrano che RMSProp generalmente converge più velocemente di AdaGrad perché, con la media in movimento esponenziale, pone maggiore enfasi sui valori del gradiente recente piuttosto che distribuire equamente l’importanza tra tutti i gradienti semplicemente accumulandoli dalla prima iterazione. Inoltre, rispetto ad AdaGrad, la velocità di apprendimento in RMSProp non sempre decade con l’aumentare delle iterazioni permettendo di adattarsi meglio in situazioni particolari.
In RMSProp si consiglia di scegliere β vicino a 1.
Perché non utilizzare semplicemente un gradiente quadrato per vₜ invece della media mobile esponenziale?
È noto che la media mobile esponenziale distribuisce pesi più elevati ai recenti valori del gradiente. Questo è uno dei motivi per cui RMSProp si adatta rapidamente. Ma non sarebbe meglio se invece della media mobile prendessimo in considerazione solo l’ultimo gradiente quadrato ad ogni iterazione (vₜ = dw²)? A quanto pare, l’equazione di aggiornamento si trasformerebbe nel modo seguente:
Come possiamo vedere, la formula risultante è molto simile a quella utilizzata nella discesa del gradiente. Tuttavia, invece di utilizzare un valore di gradiente normale per l’aggiornamento, ora utilizziamo il segno del gradiente:
- Se dw > 0poi un peso w viene diminuito di α.
- Se dw < 0poi un peso w è aumentato di α.
Per riassumere, se vₜ = dw²quindi i pesi del modello possono essere modificati solo di ±α. Sebbene questo approccio funzioni a volte, non è ancora flessibile, l’algoritmo diventa estremamente sensibile alla scelta di α e le grandezze assolute del gradiente vengono ignorate, il che può rendere il metodo estremamente lento nella convergenza. Un aspetto positivo di questo algoritmo è il fatto che è richiesto solo un singolo bit per memorizzare i segni dei gradienti, il che può essere utile nei calcoli distribuiti con severi requisiti di memoria.
Per il momento Adam è l’algoritmo di ottimizzazione più famoso nel deep learning. Ad alto livello, Adam combina gli algoritmi Momentum e RMSProp. Per raggiungere questo obiettivo, tiene semplicemente traccia delle medie in movimento esponenziale rispettivamente per i gradienti calcolati e per i gradienti quadrati.
Inoltre, è possibile utilizzare la correzione del bias per le medie mobili per un’approssimazione più precisa dell’andamento del gradiente durante le prime iterazioni. Gli esperimenti mostrano che Adam si adatta bene a quasi tutti i tipi di architettura di rete neurale sfruttando i vantaggi sia di Momentum che di RMSProp.
Secondo il Carta Adamobuoni valori predefiniti per gli iperparametri sono β₁ = 0,9, β₂ = 0,999, ε = 1e-8.
Abbiamo esaminato diversi algoritmi di ottimizzazione nelle reti neurali. Considerato come una combinazione di Momentum e RMSProp, Adam è il più superiore tra loro e si adatta in modo efficace a set di dati di grandi dimensioni e reti profonde. Inoltre, ha un’implementazione semplice e pochi requisiti di memoria che lo rendono una scelta preferibile nella maggior parte delle situazioni.
Tutte le immagini, se non diversamente specificato, sono dell’autore
Fonte: towardsdatascience.com