Backpropagation gradiente tramite connessioni salta ResNet


22

Sono curioso di sapere come i gradienti vengono retro-propagati attraverso una rete neurale usando i moduli ResNet / salta le connessioni. Ho visto un paio di domande su ResNet (ad es. Rete neurale con connessioni skip-layer ) ma questa fa domande specifiche sulla retro-propagazione dei gradienti durante l'allenamento.

L'architettura di base è qui:

inserisci qui la descrizione dell'immagine

Ho letto questo documento, Study of Residual Networks for Image Recognition , e nella Sezione 2 parlano di come uno degli obiettivi di ResNet sia consentire un percorso più breve / più chiaro per il gradiente da propagare all'indietro verso il livello base.

Qualcuno può spiegare come il gradiente scorre attraverso questo tipo di rete? Non capisco bene come l'operazione di aggiunta, e la mancanza di un livello parametrizzato dopo l'aggiunta, consenta una migliore propagazione del gradiente. Ha qualcosa a che fare con il modo in cui il gradiente non cambia quando scorre attraverso un operatore add e viene in qualche modo ridistribuito senza moltiplicazione?

Inoltre, posso capire come il problema del gradiente evanescente è alleviato se il gradiente non ha bisogno di fluire attraverso gli strati di peso, ma se non c'è flusso di gradiente attraverso i pesi, come si aggiornano dopo il passaggio all'indietro?


Solo una domanda idiota, perché passiamo x come connessione skip e non calcoliamo inversa (F (x)) per ottenere x alla fine. È causa di complessità computazionale?
Yash Kumar Atri il

Non ho capito il tuo punto the gradient doesn't need to flow through the weight layers, potresti spiegarlo?
anu

Risposte:


13

Aggiungi restituisce il gradiente allo stesso modo ad entrambi gli input. Puoi convincerti di questo eseguendo quanto segue in tensorflow:

import tensorflow as tf

graph = tf.Graph()
with graph.as_default():
    x1_tf = tf.Variable(1.5, name='x1')
    x2_tf = tf.Variable(3.5, name='x2')
    out_tf = x1_tf + x2_tf

    grads_tf = tf.gradients(ys=[out_tf], xs=[x1_tf, x2_tf])
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        fd = {
            out_tf: 10.0
        }
        print(sess.run(grads_tf, feed_dict=fd))

Produzione:

[1.0, 1.0]

Quindi, il gradiente sarà:

  • passato ai livelli precedenti, invariato, tramite la connessione skip-layer e anche
  • passato al blocco con i pesi e utilizzato per aggiornare quei pesi

Modifica: c'è una domanda: "qual è l'operazione nel punto in cui la connessione autostradale e il blocco della rete neurale si ricollegano, nella parte inferiore della Figura 2?"

La risposta è: sono sommati. Puoi vederlo dalla formula di Figura 2:

produzioneF(X)+X

Ciò che dice è che:

  • i valori nel bus ( )X
  • vengono aggiunti ai risultati del passaggio dei valori del bus, , attraverso la rete, ovveroXF(X)
  • per dare l'output dal blocco residuo, che ho etichettato qui comeproduzione

Modifica 2:

Riscrivere in parole leggermente diverse:

  • in avanti, i dati di input scorrono lungo il bus
    • nei punti lungo il bus, i blocchi residui possono imparare ad aggiungere / rimuovere valori al vettore del bus
  • nella direzione all'indietro, le pendenze scorrono verso il basso lungo il bus
    • lungo la strada, i gradienti aggiornano i blocchi residui che attraversano
    • anche i blocchi residui modificheranno leggermente i gradienti

I blocchi residui modificano i gradienti che scorrono all'indietro, ma non ci sono funzioni di "schiacciamento" o "attivazione" attraverso i quali i gradienti scorrono. Le funzioni "schiacciamento" / "attivazione" sono ciò che causa il problema del gradiente di esplosione / fuga, quindi rimuovendo quelli dal bus stesso, mitigiamo considerevolmente questo problema.

Modifica 3: Personalmente immagino una resnet nella mia testa come il seguente diagramma. È topologicamente identico alla figura 2, ma mostra più chiaramente forse come il bus scorre direttamente attraverso la rete, mentre i blocchi residui ne toccano i valori e aggiungono / rimuovono alcuni piccoli vettori contro il bus:

inserisci qui la descrizione dell'immagine


1
se il gradiente viene anche passato attraverso i blocchi di peso (proprio come nelle reti normali), da dove viene il vantaggio resnet? certo, consente al gradiente di saltare direttamente all'ingresso di base ma come può offrire un aumento delle prestazioni quando l'altro percorso è ancora allenato normalmente?
Simon,

3
Vedo. Quindi un gradiente sta saltando direttamente indietro a x, l'altro si propaga attraverso i pesi di nuovo a x. vengono riassunti quando raggiungono x a causa della divisione di x in 2 percorsi? in tal caso, il gradiente non sta ancora cambiando mentre torna indietro attraverso questi livelli?
Simon,

1
I gradienti scorrono fino in fondo alla pila, invariati. Tuttavia, ogni blocco contribuisce con i propri cambiamenti di gradiente nello stack, dopo aver applicato gli aggiornamenti di peso e generato il proprio set di gradienti. Ogni blocco ha sia input che output, e le sfumature fluiranno fuori dall'input, di nuovo nel gradiente "autostrada".
Hugh Perkins,

1
@RonakAgrawal ha aggiunto una modifica che mostra la somma operatoin della Figura 2 e la spiega
Hugh Perkins,

1
aggiunta una seconda modifica riformulando un po 'la mia spiegazione :)
Hugh Perkins,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.