
В прошлой статье мы рассмотрели концептуально все слои и функции, из которых будет состоять будущая модель. Сегодня мы выведем формулы, которые будут отвечать за обучение этой модели. Слои будем разбирать в обратном порядке — начиная с функции потерь и заканчивая сверточным слоем. Если возникнут трудности с пониманием формул, рекомендую ознакомиться с подробным объяснением (на картинках) метода обратного распространения ошибки, и также вспомнить о правиле дифференцирования сложной функции.
Вывод формулы для обратного распространения ошибки через функцию потерь
Это просто частная производная функции потерь
С производной
Сначала я использовал среднеквадратическое отклонение, но для задачи классификации лучше применить cross-entropy (ссылка с объяснением). Ниже формула для backprop, попытался максимально подробно написать вывод формулы:
Помним, что
Вывод формулы backprop через функции активации
… через ReLU
где
То есть мы пропускаем ошибку через те элементы, которые были выбраны максимальными во время прямого прохождения через функцию активации (умножаем ошибку с предыдущих слоев на единицу), и не пропускаем для тех, которые не были выбраны и, соответственно, не повлияли на результат (умножаем ошибку с предыдущих слоев на ноль).
… через сигмоиду
Здесь нужно помнить, что
При этом
Далее обозначим
… также через softmax (или здесь)
Эти расчеты показались мне немного сложнее, так как функция softmax для i-того выхода зависит не только от своего
Применяем формулу
При этом
И частная производная по
Исходя из формулы выше, есть нюанс с тем, что должна возвращать функция (в коде) при обратном распространении ошибки для

В случае softmax
При этом значения
Речь шла как раз об этой последней в разложении матрице —
Бэкпроп через полносвязную сеть

Вывод формулы backprop для обновления матрицы весов
fc-сети
Раскладываем сумму в числителе и получаем, что все частные производные равны нулю, кроме случая
И вот так это будет выглядеть матричном виде:
Размерность матрицы
Вывод формулы backprop для обновления матрицы 
Для bias все вычисления очень схожи с предыдущим пунктом:
Понятно, что
В матричном виде тоже все довольно просто:
Вывод формулы backprop через 
В формуле ниже сумма по
Раскладываем числитель и видим, что все частные производные равны нулю, кроме того случая, когда
И в матричном виде:
Далее матрицы в “раскрытом” виде. Замечу, что индексы самой последней матрицы я намеренно оставил в том виде, в каком они были до транспонирования, чтобы лучше было видно, какой элемент куда перешел после транспонирования.
Бэкпроп через макспулинг
Ошибка “проходит” только через те значения исходной матрицы, которые были выбраны максимальными на шаге макспулинга. Остальные значения ошибки для матрицы будут равны нулю (что логично, ведь значения по этим элементам не были выбраны функцией макспулинга во время прямого прохождения через сеть и, соответственно, никак не повлияли на итоговый результат).

Вот демонстрация макспулинга на python:
demo_of_maxpooling.ipynb
Здесь вторая матрица, которую возвращает функция, и есть координаты выбранных максимальных значений на этапе макспулинга.
Бэкпроп через сверточную сеть

Вывод формулы backprop для обновления ядра свертки
(1) здесь просто подставляем формулу для
(2) здесь раскладываем сумму в числителе по
то есть все частные производные в числителе, кроме тех, для которых которых
Все выше относится к конволюции. Формула backprop для кросс-корреляции выглядит аналогично, за исключением смены знака при
Здесь важно увидеть, что в итоговой формуле не участвует само ядро свертки. Происходит некое подобие операции свертки, но с участием уже
demo_of_conv_backprop_through_kernel.ipynb
Вывод формулы backprop для обновления весов bias
Аналогично предыдущему пункту, только заменяем
то есть, если разложить сумму по всем
Для одной карты признаков всего один bias, который “связан” со всеми элементами этой карты. Соответственно, при корректировке значения bias должны учитываться все значения из карты, полученные при обратном распространении ошибки. В качества альтернативного варианта можно брать столько bias для отдельной карты признаков, сколько элементов находится в этой карте, но в таком случае параметров bias будем слишком много — больше, чем параметров самих ядер свертки. Для второго случая также легко посчитать производную — тогда каждая
Вывод формулы backprop через слой конволюции
Здесь все аналогично предыдущим выводам:
Раскладывая сумму в числителе по
Получившиеся выражения — это та же самая операция свертки, причем в качестве ядра выступает знакомое нам ядро
Здесь можно посмотреть демонстрационный код:
demo_of_conv_backprop_through_input.ipynb
Интересно, что если мы выполняем кросс-корреляцию, то на этапе прямого прохождения через сеть мы не переворачиваем ядро свертки, но переворачиваем его при обратном распространении ошибки при прохождении через слой свертки. Если же применяем формулу конволюции — все происходит ровно наоборот.
В этой статье мы вывели и подробно рассмотрели все формулы обратного распространения ошибки, то есть формулы, позволяющие будущей модели обучаться. В следующей статье мы соединим все это в один цельный код, который и будет называться сверточной сетью, и попробуем эту сеть обучить предсказывать классы на настоящем датасете. А также проверим, насколько все вычисления корректны в сравнении с библиотекой для машинного обучения pytorch.
Следующая часть серии: Сверточная сеть на python. Часть 3. Применение модели