propagazione indietro nella CNN


15

Ho la seguente CNN:

rete di rete

  1. Comincio con un'immagine di input di dimensioni 5x5
  2. Quindi applico la convoluzione usando il kernel 2x2 e stride = 1, che produce una mappa delle caratteristiche di dimensioni 4x4.
  3. Quindi applico 2x2 max-pooling con stride = 2, che riduce la mappa delle caratteristiche a dimensioni 2x2.
  4. Quindi applico il sigmoid logistico.
  5. Quindi uno strato completamente collegato con 2 neuroni.
  6. E un livello di output.

Per semplicità, supponiamo che io abbia già completato il passaggio in avanti e calcolato δH1 = 0,25 e δH2 = -0,15

Quindi dopo il passaggio in avanti completo e il passaggio all'indietro parzialmente completato, la mia rete appare così:

rete dopo il passaggio in avanti

Quindi calcolo i delta per il livello non lineare (sigma logistico):

δ11=(0.250.61+0.150.02)0.58(10.58)=0.0364182δ12=(0.250.82+0.150.50)0.57(10.57)=0.068628δ21=(0.250.96+0.150.23)0.65(10.65)=0.04675125δ22=(0.251.00+0.150.17)0.55(10.55)=0.06818625

Quindi, propaga i delta al livello 4x4 e imposto tutti i valori che sono stati filtrati con max pooling su 0 e la mappa sfumata è simile alla seguente:

inserisci qui la descrizione dell'immagine

Come posso aggiornare i pesi del kernel da lì? E se la mia rete avesse un altro livello convoluzionale prima di 5x5, quali valori dovrei usare per aggiornare i pesi del kernel? E nel complesso, il mio calcolo è corretto?


Per favore, chiarisci cosa ti confonde. Sai già come fare la derivata del massimo (tutto è zero tranne dove il valore è massimo). Quindi, dimentichiamo il max pooling. Il tuo problema è nella convoluzione? Ogni patch di convoluzione avrà i propri derivati, è un lento processo computazionale.
Ricardo Cruz,

La migliore fonte è il libro di apprendimento approfondito - certamente non è una lettura facile :). La prima convoluzione è la stessa cosa di dividere l'immagine in patch e quindi applicare una normale rete neurale, in cui ogni pixel è collegato al numero di "filtri" che hai usando un peso.
Ricardo Cruz,

1
La tua domanda è in sostanza come vengono adattati i pesi del kernel usando la backpropagation?
JahKnows,

@JahKnows ..e come vengono calcolati i gradienti per il livello convoluzionale, dato l'esempio in questione.
koryakinp,

Esiste una funzione di attivazione associata ai livelli convoluzionali?
JahKnows,

Risposte:


9

Una convoluzione impiega un principio di condivisione del peso che complicherà significativamente la matematica ma proviamo a superare le erbacce. Traggo la maggior parte delle mie spiegazioni da questa fonte .


Forward pass

Come hai osservato, il passaggio in avanti dello strato convoluzionale può essere espresso come

xi,jl=mnwm,nloi+m,j+nl1+bi,jl

k1k2k1=k2=2x0,0=0.25mn

backpropagation

Supponendo che si stia utilizzando l'errore quadratico medio (MSE) definito come

E=12p(tpyp)2

vogliamo determinare

Ewm,nlmnw0,01=0.13HK

(Hk1+1)(Wk2+1)

44w0,01=0.13x0,01=0.25

Ewm,nl=i=0Hk1j=0Wk2Exi,jlxi,jlwm,nl

Questo scorre attraverso l'intero spazio di output, determina l'errore che sta contribuendo all'output e quindi determina il fattore di contributo del peso del kernel rispetto a quell'output.

Chiamiamo il contributo all'errore dal delta dello spazio di output per semplicità e per tenere traccia dell'errore di backpropagated,

Exi,jl=δi,jl

Il contributo dei pesi

La convoluzione è definita come

xi,jl=mnwm,nloi+m,j+nl1+bi,jl

in tal modo,

xi,jlwm,nl=wm,nl(mnwm,nloi+m,j+nl1+bi,jl)

m=mn=n

xi,jlwm,nl=oi+m,j+nl1

Quindi di nuovo nel nostro termine di errore

Ewm,nl=i=0Hk1j=0Wk2δi,jloi+m,j+nl1

Discesa gradiente stocastica

w(t+1)=w(t)ηEwm,nl

Calcoliamo alcuni di essi

import numpy as np
from scipy import signal
o = np.array([(0.51, 0.9, 0.88, 0.84, 0.05), 
              (0.4, 0.62, 0.22, 0.59, 0.1), 
              (0.11, 0.2, 0.74, 0.33, 0.14), 
              (0.47, 0.01, 0.85, 0.7, 0.09),
              (0.76, 0.19, 0.72, 0.17, 0.57)])
d = np.array([(0, 0, 0.0686, 0), 
              (0, 0.0364, 0, 0), 
              (0, 0.0467, 0, 0), 
              (0, 0, 0, -0.0681)])

gradient = signal.convolve2d(np.rot90(np.rot90(d)), o, 'valid')

array ([[0.044606, 0.094061], [0.011262, 0.068288]])

Ew


Per favore fatemi sapere se ci sono errori nella derivazione.


Aggiornamento: codice corretto


Ewm,nl

1
gradient = signal.convolve2d(np.rot90(np.rot90(d)), o, 'valid')
Sun Bee

Vorrei suggerire di rivedere questa risposta. In particolare, il codice fornito in Python potrebbe essere verificato
Duloren,
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.