propagation de retour dans CNN

15

J'ai le CNN suivant:

configuration du réseau

  1. Je commence par une image d'entrée de taille 5x5
  2. Ensuite, j'applique la convolution en utilisant un noyau 2x2 et stride = 1, ce qui produit une carte de caractéristiques de taille 4x4.
  3. Ensuite, j'applique un pool max 2x2 avec stride = 2, ce qui réduit la carte des entités à la taille 2x2.
  4. Ensuite, j'applique le sigmoïde logistique.
  5. Ensuite, une couche entièrement connectée avec 2 neurones.
  6. Et une couche de sortie.

Par souci de simplicité, supposons que j'ai déjà terminé la passe avant et calculé δH1 = 0,25 et δH2 = -0,15

Donc, après la passe avant complète et la passe arrière partiellement terminée, mon réseau ressemble à ceci:

réseau après passe avant

Ensuite, je calcule les deltas pour la couche non linéaire (sigmoïde logistique):

δ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

Ensuite, je propage les deltas à la couche 4x4 et définit toutes les valeurs qui ont été filtrées par max-pooling à 0 et la carte de dégradé ressemble à ceci:

entrez la description de l'image ici

Comment puis-je mettre à jour les poids du noyau à partir de là? Et si mon réseau avait une autre couche convolutionnelle avant 5x5, quelles valeurs devrais-je utiliser pour mettre à jour les poids du noyau? Et dans l'ensemble, mon calcul est-il correct?

koryakinp
la source
Veuillez clarifier ce qui vous déroute. Vous savez déjà faire la dérivée du maximum (tout est nul sauf là où la valeur est maximale). Alors, oublions le max-pooling. Votre problème est-il dans la convolution? Chaque patch de convolution aura ses propres dérivés, c'est un processus de calcul lent.
Ricardo Cruz
La meilleure source est le livre d'apprentissage en profondeur - certes pas une lecture facile :). La première convolution est la même chose que de diviser l'image en patchs puis d'appliquer un réseau neuronal normal, où chaque pixel est connecté au nombre de "filtres" que vous avez en utilisant un poids.
Ricardo Cruz
1
Votre question est-elle essentiellement de savoir comment les poids du noyau sont ajustés en utilisant la rétropropagation?
JahKnows
@JahKnows ..et comment les gradients sont calculés pour la couche convolutionnelle, étant donné l'exemple en question.
koryakinp
Existe-t-il une fonction d'activation associée à vos couches convolutives?
JahKnows

Réponses:

9

Une convolution utilise un principe de partage du poids qui compliquera considérablement les mathématiques, mais essayons de passer au travers des mauvaises herbes. Je tire l'essentiel de mon explication de cette source .


Passe avant

Comme vous l'avez observé, la passe avant de la couche convolutionnelle peut être exprimée comme

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

où dans notre cas k1 et k2 est la taille du noyau, dans notre cas k1=k2=2 . Donc, cela dit pour une sortie x0,0=0.25 comme vous l'avez trouvé. m et n parcourent les dimensions du noyau.

Rétropropagation

En supposant que vous utilisez l'erreur quadratique moyenne (MSE) définie comme

E=12p(tpyp)2,

nous voulons déterminer

Ewm,nl afin de mettre à jour les poids. metnsont les indices de la matrice du noyau à ne pas confondre avec ses itérateurs. Par exemplew0,01=0.13dans notre exemple. Nous pouvons également voir que pour une image d'entréeHxKla dimension de sortie après la couche convolutionnelle sera

(Hk1+1) x(Wk2+1) .

44w0,01=0.13x0,01=0.25

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

Cela itère sur tout l'espace de sortie, détermine l'erreur que la sortie contribue, puis détermine le facteur de contribution du poids du noyau par rapport à cette sortie.

Appelons la contribution à l'erreur du delta de l'espace de sortie pour plus de simplicité et pour garder une trace de l'erreur rétrograde,

Exi,jl=δi,jl

La contribution des poids

La convolution est définie comme

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

Donc,

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

m=mn=n

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

Puis revenons à notre terme d'erreur

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

Descente de gradient stochastique

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

Calculons certains d'entre eux

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

tableau ([[0,044606, 0,094061], [0,011262, 0,068288]])

Maintenant, vous pouvez mettre cela dans l'équation SGD à la place de Ew.


Veuillez me faire savoir s'il y a des erreurs dans la dérivation.


Mise à jour: code corrigé

JahKnows
la source
Comment Ewm,nlressemblera au cas où mon filtre a plusieurs canaux?
koryakinp
1
gradient = signal.convolve2d(np.rot90(np.rot90(d)), o, 'valid')
Sun Bee
Je voudrais suggérer de revoir cette réponse. En particulier, le code fourni en python pourrait être vérifié
Duloren