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
xli,j=∑m∑nwlm,nol−1i+m,j+n+bli,j
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=12∑p(tp−yp)2,
nous voulons déterminer
∂E∂wlm′,n′ afin de mettre à jour les poids. m′etn′sont les indices de la matrice du noyau à ne pas confondre avec ses itérateurs. Par exemplew10,0=−0.13dans notre exemple. Nous pouvons également voir que pour une image d'entréeHxKla dimension de sortie après la couche convolutionnelle sera
(H−k1+1) x(W−k2+1) .
44w10,0=−0.13x10,0=0.25
∂E∂wlm′,n′=∑H−k1i=0∑W−k2j=0∂E∂xli,j∂xli,j∂wlm′,n′
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,
∂E∂xli,j=δli,j
La contribution des poids
La convolution est définie comme
xli,j=∑m∑nwlm,nol−1i+m,j+n+bli,j ,
Donc,
∂xli,j∂wlm′,n′=∂∂wlm′,n′(∑m∑nwlm,nol−1i+m,j+n+bli,j)
m=m′n=n′
∂xli,j∂wlm′,n′=ol−1i+m′,j+n′
Puis revenons à notre terme d'erreur
∂E∂wlm′,n′=∑H−k1i=0∑W−k2j=0δli,jol−1i+m′,j+n′
Descente de gradient stochastique
w( t + 1 )= w( t )- η∂E∂wlm′, n′
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 ∂E∂w.
Veuillez me faire savoir s'il y a des erreurs dans la dérivation.
Mise à jour: code corrigé