В свертке используется принцип распределения веса, который значительно усложнит математику, но давайте попробуем пробиться через сорняки. Я рисую большую часть своих объяснений из этого источника .
Прямой проход
Как вы заметили, прямой проход сверточного слоя может быть выражен как
xli,j=∑m∑nwlm,nol−1i+m,j+n+bli,j
k1k2k1=k2=2x0,0=0.25mn
обратное распространение
Предполагая, что вы используете среднеквадратичную ошибку (MSE), определенную как
E=12∑p(tp−yp)2
мы хотим определить
∂E∂wlm′,n′m′n′w10,0=−0.13HK выходной размер после сверточного слоя будет
(H−k1+1)(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′ .
Он выполняет итерацию по всему выходному пространству, определяет ошибку, которую вносит вывод, а затем определяет коэффициент вклада веса ядра по отношению к этому выводу.
Давайте для простоты будем называть вклад в ошибку из выходной дельты пространства, чтобы отслеживать обратную ошибку,
∂E∂xli,j=δli,j
Вклад от весов
Свертка определяется как
xli,j=∑m∑nwlm,nol−1i+m,j+n+bli,j ,
Таким образом,
∂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′
Тогда вернемся к нашей ошибке
∂Е∂весLм', н'= ∑ЧАС- к1я = 0ΣW- к2J = 0δLя , джол - 1я + м', j + n',
Стохастический градиентный спуск
вес( т + 1 )= ш( т )- η∂Е∂весLм', н'
Давайте посчитаем некоторые из них
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')
массив ([[0,044606, 0,094061], [0,011262, 0,068288]])
Теперь вы можете поместить это в уравнение SGD вместо ∂Е∂вес,
Пожалуйста, дайте мне знать, если есть ошибки в выводе.
Обновление: исправленный код