7. Neural Network and Deep Learning

Le reti neurali sono popolari per problemi che comportano un ragionamento di basso livello, con molti dati disponibili, come l’image interpretation e la speech recognition e la machine translation, poichè sono molto flessibili e capaci di inventare nuove feature.

1 Reti Neurali Feedforward

Una rete neurale feedforward è una funzione di predizione dato l’input x definita come f(x) = f_n(f_{n - 1}(...(f_2(f_1(x)))))

dove ogni funzione f_i mappa un vettore di valori su un vettore.

La funzione f_i è l’i-esimo strato.

Il numero di funzioni composte n è la profondità della rete neurale. L’ultimo layer f_n è il layer di output. Gli altri layer sono layer nascosti. Ogni componente del vettore di output di un layer è detto unità.

In una rete neurale feedforward, il layer di input ha un’unità per feature di input e ogni layer nascosto è una funzione lineare composta da una funzione di attivazione \phi non lineare.

La funzione lineare prende un vettore di valori in come input e ritorna un vettore out in funzione dei valori in input in[k] allo strato:

out[j] = \phi\left(\displaystyle \sum_k in[k] \cdot w[k, j]\right) dove w[k, j] è un peso da apprendere per ogni coppia input-output del layer.

Una funzione di attivazione per layer nascosti deve essere quasi ovunque differenziabile in modo che metodi basati su discesa di gradiente funzionino.

Una funzione di attivazione comune è la ReLU: \phi(x) = max(0, x), che ha derivata 0 per x < 0 e 1 per x > 0. Si assume che per x = 0 la derivata sia 0. Se tutti i layer nascosti utilizzassero la ReLU si avrebbe una rete di funzioni lineari per parti.

La funzione di attivazione per il layer di output dipende dal tipo di output y e dalla loss che si vuole minimizzare:

  • y reale, errore quadratico: \phi(x) = x (identità)

  • y booleana, log loss binaria: sigmoide

  • y categorica, log loss categorica: softmax

Il principio è che per ognuna di queste scelte la funzione di attivazione e la loss si complementano l’una con l’altra in modo da avere una derivata semplice, in questo caso proporzionata a \hat{Y}(e) - Y(e).

Una rete neurale può avere valori reali in input, quindi per feature categoriche non booleane si utilizza il one-hot encoding.

L’ampiezza di uno strato è il numero di elementi del vettore di uscita dello strato. La larghezza di una rete neurale è la larghezza massima di tutti gli strati. La progettazione di una rete comprende la profondità della rete (numero di layer) e la larghezza di ogni strato nascosto.

Una rete con un solo strato nascosto - purché sia sufficientemente ampia - può approssimare qualsiasi funzione continua sui reali, o qualsiasi funzione di input discreti a output discreti. L’ampiezza richiesta può essere proibitiva, e in genere è meglio che una rete sia profonda piuttosto che molto ampia: gli strati inferiori forniscono caratteristiche utili per semplificare gli strati superiori.

2 Apprendimento dei parametri

La back-propagation implementa la discesa di gradiente stocastica per aggiornare tutti i pesi:

  • Per ogni esempio e del batch, si aggiorna ogni peso w proporzionalmente a

  • \dfrac{\partial}{\partial w} error(e), usando due proprietà delle derivate:

    • regola di decomposizione lineare: la derivata di una funzione lineare aw + b è: \dfrac{\partial}{\partial w} (a w + b) = a, quindi la derivata è il numero che moltiplica w nella funzione lineare

    • regola della catena: se g è funzione di w e se f, funzione che non dipende da w, è applicata a g(w), allora: \dfrac{\partial}{\partial w} f(g(w)) = f^{'}(g(w)) \cdot \dfrac{\partial}{\partial w} g(w), dove f^{'} è la derivata di f.

Sia f(e) = f_n(f_{n - 1}(…f_2(f_1(x_e)))) l’output della funzione di predizione per e con feature di input x_e e supponendo v_i = f_i(f_{i - 1}(…f_2(f_1(x_e)))), ovvero v_i = f_i(v_{i - 1}) e v_0 = x_e. I valori per v_i per 1 \leq i \leq n possono essere calcolati in una passata attraverso le funzioni annidate.

2.1 Aggiornamento dei pesi

Sia w un peso nella definizione di una f_j. f_i non dipende da w per i \neq j. La derivata di error(f(e)) rispetto a w è data da:

\begin{split} \dfrac{\partial}{\partial w} error(f(e)) & = error^{'}(v_n) \cdot \dfrac{\partial}{\partial w} f_n(v_{n - 1}) \\ & = error^{'}(v_n) \cdot \dfrac{\partial}{\partial w} f_n (f_{n - 1} (v_{n - 2})) \\ & = \text{...} \\ &= error^{'}(v_n) \cdot f_n^{'}(v_{n - 1}) \cdot f^{'}_{n - 1}(v_{n - 2}) \cdot ... \cdot \dfrac{\partial}{\partial w}(f_j (v_{j - 1})) \end{split}

dove f_i^{'} è la derivata di f_i rispetto ai suoi input, v_{n - 1} è il valore ricevuto dal layer n - 1. L’espansione termina fino a f_j. L’ultima derivata parziale non è istanza della regola della catena non essendo v_{j - 1} funzione di w, invece si usa la regola di decomposizione lineare, dove w viene moltiplicato per la componente di v_{j - 1} appropriata.

L’idea è che l’errore lo vedo alla fine nel layer output e devo correggere tutti i pesi di tutti i layer.

Non conosco però l’errore di ogni strato, ma conosco l’errore dell’ultimo. Posso calcolare i nuovi pesi sfruttando le proprietà delle derivate, fermandomi fino al layer che mi interessa.

La backpropagation determina l’aggiornamento per ogni peso in due passate per ogni esempio:

  • Predizione: dati i valori di input per ogni layer, calcolare il valore degli output del layer (calcola i v_i).

  • Back-propagate: andando a ritroso attraverso i layer si determina l’aggiornamento di ciascun peso dei layer lineari. Andando a ritroso viene calcolato error^{'}(v_n) \cdot \prod_{i = 0}^k f^{'}_{n - 1}(v_{n - i - 1}) per ogni k partendo da 0 e passato ai layer inferiori. Questo input è il termine d’errore per un layer, che viene combinato con i valori calcolati al passo di predizione per aggiornare i pesi del layer e calcolare il termine d’errore per il layer inferiore.

Se si memorizzano i risultati intermedi la backpropagation diventa una forma di programmazione dinamica per la discesa di gradiente stocastica.

3 Extra

3.1 Migliorare l’ottimizzazione

  • Momentum: velocità di aggiornamento di ciascun parametro, agisce come dimensione del passo per il parametro. Viene incrementato se l’accelerazione ha lo stesso segno, decrementato altrimenti

  • RMS-Prop (root mean squared propagation): l’ordine di grandezza del cambiamento per ogni peso dipende dal quadrato del gradiente rispetto al suo valore storico, invece di dipendere dal valore assoluto. Per ogni peso viene mantenuta una media mobile del quadrato del gradiente in modo da sapere di quanto il peso dovrebbe cambiare.

3.2 Evitare l’overfitting

Per evitare l’overfitting possiamo procedere con i seguenti metodi:

  • il tuning degli iperparametri (tramite cross validation). Gli iperparametri che possono essere calibrati possono essere l’algoritmo, numero di layer, ampiezza del layer, numero di epoche, learning rate, batch size, regolarizzazione L_1 e L_2;

  • dropout: si droppano casualmente alcune unità nel training. Ignorare un’unità equivale a settare temporaneamente l’output a 0. E’ controllata da un parametro che specifica la proporzione di valori annullati, tipicamente 0.5 per i layer nascosti e 0.2 per i layer di input;

  • Altri metodi: data augmentation, feature engineering, multi-task learning