Я приведу вам полный пример, не буду коротким, но, надеюсь, вы его получите. Для простоты я опускаю как функции смещения, так и функции активации, но как только вы их получите, достаточно просто добавить их. Помните, что обратное распространение по сути то же самое в CNN, как и в простом MLP, но вместо умножения у вас будут свертки. Итак, вот мой образец:
Введите:
.7 -.3 -.7 .5
.9 -.5 -.2 .9
-.1 .8 -.3 -.5
0 .2 -.1 .6
Ядро:
.1 -.3
-.5 .7
Выполнение сверточного выхода (Результат 1-го сверточного слоя и ввод для 2-го сверточного слоя):
.32 .27 -.59
.99 -.52 -.55
-.45 .64 .13
L2 Ядро:
-.5 .1
.3 .9
Активация L2:
.73 .29
.37 -.63
Здесь у вас будет плоский слой и стандартная MLP или SVM, чтобы выполнить фактическую классификацию. Во время обратного распространения вы получите дельту, которая для забавы, предположим, следующая:
-.07 .15
-.09 .02
Это всегда будет тот же размер, что и ваша активация перед выравниванием слоя. Теперь, чтобы вычислить дельту ядра для текущего L2, вы свяжете активацию L1 с вышеуказанной дельтой. Я не буду записывать это снова, но результат будет:
.17 .02
-.05 .13
Обновление ядра выполняется как L2.Kernel - = LR * ROT180 (dL2.K), что означает, что вы сначала поворачиваете вышеуказанную матрицу 2x2, а затем обновляете ядро. Вот для нашего игрушечного примера получается:
-.51 .11
.3 .9
Теперь, чтобы вычислить дельту для первого сверточного слоя, напомним, что в MLP у вас было следующее: current_delta * current_weight_matrix. Ну, в слое Conv, у вас почти тоже самое. Вы должны свернуть исходное Ядро (до обновления) слоя L2 с вашей дельтой для текущего слоя. Но эта свертка будет полной сверткой. Результат оказывается:
.04 -.08 .02
.02 -.13 .14
-.03 -.08 .01
С этим вы перейдете к 1-му сверточному слою и свернете исходный ввод с этой дельтой 3x3:
.16 .03
-.09 .16
И обновите ядро L1 так же, как указано выше:
.08 -.29
-.5 .68
Тогда вы можете начать с подачи вперед. Вышеуказанные вычисления были округлены до 2 десятичных знаков, и для расчета новых значений в ядре использовалась скорость обучения .1
TLDR:
Вы получите дельта
Вы вычисляете следующую дельту, которая будет использоваться для следующего слоя как: FullConvolution (Li.Input, delta)
Вычисление дельты ядра, которая используется для обновления ядра: Convolution (Li.W, delta)
Перейти на следующий слой и повторить.