Tengo la siguiente CNN:
- Comienzo con una imagen de entrada de tamaño 5x5
- Luego aplico convolución usando kernel 2x2 y stride = 1, que produce un mapa de características de tamaño 4x4.
- Luego aplico 2x2 max-pooling con stride = 2, que reduce el mapa de características al tamaño 2x2.
- Luego aplico logístico sigmoide.
- Luego una capa completamente conectada con 2 neuronas.
- 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í:
Luego calculo deltas para la capa no lineal (sigmoide logístico):
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í:
¿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?
machine-learning
convnet
backpropagation
cnn
kernel
koryakinp
fuente
fuente
Respuestas:
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
Propagación hacia atrás
Suponiendo que está utilizando el error cuadrático medio (MSE) definido como
queremos determinar
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,
El aporte de los pesos
La convolución se define como
así,
Luego de vuelta en nuestro término de error
Descenso de gradiente estocástico
Vamos a calcular algunos de ellos.
Avíseme si hay errores en la derivación.
Actualización: código corregido
fuente
gradient = signal.convolve2d(np.rot90(np.rot90(d)), o, 'valid')