propagación hacia atrás en CNN

15

Tengo la siguiente CNN:

red layour

  1. Comienzo con una imagen de entrada de tamaño 5x5
  2. Luego aplico convolución usando kernel 2x2 y stride = 1, que produce un mapa de características de tamaño 4x4.
  3. Luego aplico 2x2 max-pooling con stride = 2, que reduce el mapa de características al tamaño 2x2.
  4. Luego aplico logístico sigmoide.
  5. Luego una capa completamente conectada con 2 neuronas.
  6. Y una capa de salida.

En aras de la simplicidad, supongamos que ya completé el pase directo y calculé δH1 = 0.25 y δH2 = -0.15

Entonces, después del paso hacia adelante completo y el paso hacia atrás parcialmente completado, mi red se ve así:

red después de pasar adelante

Luego calculo deltas para la capa no lineal (sigmoide logístico):

δ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

Luego, propago deltas a la capa 4x4 y establezco todos los valores que se filtraron mediante la agrupación máxima a 0 y el mapa de degradado se ve así:

ingrese la descripción de la imagen aquí

¿Cómo actualizo los pesos del kernel desde allí? Y si mi red tenía otra capa convolucional antes de 5x5, ¿qué valores debería usar para actualizar los pesos del kernel? Y en general, ¿es correcto mi cálculo?

koryakinp
fuente
Por favor aclara lo que te confunde. Ya sabes cómo hacer la derivada del máximo (todo es cero excepto donde el valor es máximo). Entonces, olvidemos la agrupación máxima. ¿Es tu problema en la convolución? Cada parche de convolución tendrá sus propios derivados, es un proceso computacional lento.
Ricardo Cruz
La mejor fuente es el libro de aprendizaje profundo , ciertamente no es una lectura fácil :). La primera circunvolución es lo mismo que dividir la imagen en parches y luego aplicar una red neuronal normal, donde cada píxel se conecta a la cantidad de "filtros" que tiene usando un peso.
Ricardo Cruz
1
¿Es su pregunta en esencia cómo se ajustan los pesos del kernel mediante el uso de la retropropagación?
JahKnows
@JahKnows ... y cómo se calculan los gradientes para la capa convolucional, dado el ejemplo en cuestión.
koryakinp
¿Hay una función de activación asociada con sus capas convolucionales?
JahKnows

Respuestas:

9

Una convolución emplea un principio de distribución de peso que complicará las matemáticas de manera significativa, pero tratemos de superar las malezas. Estoy sacando la mayor parte de mi explicación de esta fuente .


Pase adelantado

Como observó, el paso hacia adelante de la capa convolucional se puede expresar como

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

k1k2k1=k2=2x0,0=0.25mn

Propagación hacia atrás

Suponiendo que está utilizando el error cuadrático medio (MSE) definido como

E=12p(tpyp)2

queremos determinar

Ewm,nlmnw0,01=0.13HK

(Hk1+1)(Wk2+1)

44w0,01=0.13x0,01=0.25

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

Esto itera en todo el espacio de salida, determina el error que la salida está contribuyendo y luego determina el factor de contribución del peso del núcleo con respecto a esa salida.

Llamemos a la contribución al error desde el delta del espacio de salida para simplificar y realizar un seguimiento del error propagado hacia atrás,

Exi,jl=δi,jl

El aporte de los pesos

La convolución se define como

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

así,

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

m=mn=n

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

Luego de vuelta en nuestro término de error

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

Descenso de gradiente estocástico

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

Vamos a calcular algunos de ellos.

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')

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

Ew


Avíseme si hay errores en la derivación.


Actualización: código corregido

JahKnows
fuente
Ewm,nl
1
gradient = signal.convolve2d(np.rot90(np.rot90(d)), o, 'valid')
Sun Bee
Me gustaría sugerir revisar esta respuesta. En particular, el código provisto en Python podría ser verificado
Duloren