Questa domanda arriva ad alcune qualità molto importanti di RNN e DNN in generale. Risponderò a ciascuna delle tue domande secondarie, anche se non nello stesso ordine (cercherò di evidenziare dove lo faccio)
Condivisione dei parametri
Innanzitutto, la qualità più importante degli RNN si chiama condivisione dei parametri . I dati sequenziali vengono in genere immessi in livelli separati. Per un input di lunghezza 20, una rete RNN avrebbe 20 layer. Gli stessi parametri interni sono usati per ogni strato, quindi tutti e 20 gli strati usano gli stessi pesi e bias . Confronta questo con un percettrone multistrato che avrebbe 20 pesi e distorsioni separati.Wb
La condivisione dei parametri ha diversi vantaggi:
- Ora abbiamo molti meno parametri. C'è 1 blocco ripetuto invece di 20 livelli separati. Una riduzione di 20x!
- Questo moltiplica efficacemente i dati di allenamento. Il livello ricorrente impara da ogni parola in una singola frase di esempio mentre ogni livello in una MLP impara da una singola parola per frase.
- La nostra rete è ora molto più flessibile. Possiamo allenarci su frasi fino a 20 parole e quindi generalizzare a una frase di 25 parole aggiungendo più passaggi o utilizzando un RNN dinamico
Architettura di rete
Chiedete delle attivazioni tanh e sigmoid. Per rispondere a questo dobbiamo parlare di architetture RNN specifiche. Il semplice RNN discusso sopra ha un'unica attivazione. I semplici RNN tendono a creare il problema dei gradienti di fuga (o che esplodono!) A causa della ripetuta applicazione degli stessi pesi e funzione di attivazione.
I blocchi RNN con gate (come GRU e LSTM) utilizzano meccanismi di gating per passare attivazioni dentro e fuori dagli stati di memoria e per combinare gli stati di memoria con l'input per generare l'output di ciascun blocco. Per questo motivo, le porte possono impedire al gradiente di propagarsi all'indietro. Sigmoid è una funzione di attivazione comune per cancelli perché schiaccia le attivazioni su (0,1) --- 0 interrompe completamente l'attivazione e 1 la lascia passare. Tuttavia, qualsiasi funzione di attivazione decente con un profilo di compressione simile funziona. Aneddoticamente, il sigmoide duro è abbastanza comune in questi giorni.
Oltre alle porte, i blocchi RNN con gate hanno uno stato interno per il quale l'attivazione varia un po '. Poiché il gating limita il backprop a gradiente, abbiamo molta flessibilità su questa attivazione. Non deve essere schiacciato per esempio, ed è qui che si vedono spesso le attivazioni di rettifica (relu, elu, islu, ecc.). Tanh è anche una scelta perfettamente sensata.
Per quanto riguarda distorsioni e pesi, ogni attivazione in una cella RNN ha in genere il suo peso e la sua propensione. Quindi un GRU ha 3 attivazioni (nascosto, aggiorna e ripristina) e ognuna ha il suo peso e la sua propensione. Tuttavia, ricorda che come RNN, ognuno di questi viene riutilizzato per ogni timestep.
Passaggio all'indietro
Questo copre abbastanza bene il passaggio in avanti ma fai anche una domanda importante su come l'errore si propaga all'indietro. Esistono due metodi per avvicinarsi a questo.
Forzatura dell'insegnante
Per gli RNN che generano una previsione in ogni fase (come la previsione del risultato delle fasi successive, traduzione o riconoscimento dei fonemi), la forzatura dell'insegnante è un metodo per isolare ogni fase dell'RNN. Rimuovendo queste dipendenze, Teacher Forcing consente a RNN di utilizzare il backprop convenzionale con la regola della catena.
Ma come funziona? Le reti di forzatura degli insegnanti hanno architetture di treni e prove separate. Per l'allenamento, ad ogni timestep , l'ingresso viene concatenato con il target precedente, . Immagina questo per una rete incaricata di prevedere il seguente personaggio. La rete ha appena tentato di prevedere il personaggio per il precedente timestep. Ma invece usiamo il personaggio osservato in quel momento (lo sappiamo perché siamo nella fase di addestramento). Così l'errore al passo temporale dipende solo dal valore osservato in e l'ingresso a . Abbiamo quindi rimosso tutte le connessioni nel tempo dalla rete.txtyt−1tt−1t
Al test, non conosciamo il vero valore ad ogni timestep, quindi sostituiamo con l'output del layer precedente . In questo caso, le connessioni temporali sono tornate, ma solo per la fase di test.yt−1ot−1
Propagazione indietro nel tempo
Ma non dobbiamo ricorrere al forzante degli insegnanti. La propagazione retroattiva nel tempo ci consente di applicare l'algoritmo backprop agli RNN. Considerare la rete con timestep e input , stato nascosto , output e valore osservato per ciascun timestep.nxhoy
BPTT funziona nei seguenti passaggi.
- Calcola il gradiente per ogni coppia . (Questo può essere fatto tutto in una volta.)∇otot,yt
- Calcola il gradiente per ogni timestep, iniziando dall'ultimo timestep e procedendo iterativamente all'indietro. (Questo deve essere fatto uno alla volta.)∇ht
- Questo ci dà bordi per ogni parametro interno del nostro RNN. Il trucco per aggiornare i parametri è trovare il contributo del gradiente per ogni timestep (es. anche se abbiamo solo un ) e quindi sommare quei gradienti per aggiornare i parametri interni.n ∇WtW
Ulteriori letture
Consiglio vivamente il capitolo 10 di Goodfellow, Bengio e Courville's Deep Learning per ulteriori informazioni sugli RNN. Inoltre, il libro RNN di Graves è fantstic per dettagli di livello superiore