Алгоритм back propagation. Пример работы

Смотреть материал на YouTube | RuTube

Итак, наша задача вычислить весовые коэффициенты  НС с помощью градиентного алгоритма:

который мы с вами расписывали следующим образом:

Отсюда хорошо видно, что конкретный вид градиента меняется в зависимости от выбранной функции потерь  и функций активации НС . Кроме того, учитывая, как правило, большой объем обучающей выборки , выполнять суммирование по всем образам на каждой итерации работы градиентного алгоритма слишком расточительно. Поэтому на практике выбирают  случайно отобранных образов из обучающей выборки и только по ним считается градиент:

Набор из таких  образов часто называют батчем (batch, англ. пакет) или мини-батчем. А сам градиентный алгоритм превращается в стохастический градиентный спуск (SGD).

Но и это еще не все. Современные НС часто содержат огромное количество параметров : от десятков тысяч до триллионов. И если вычислять градиент функции потерь стандартным способом, то потребовалось бы порядка  операций, где  – число коэффицентов . Это очень много. Поэтому был придуман алгоритм, применимый именно к НС, который позволяет вычислять тот же самый градиент за линейное число операций, примерно:

где  – число слоев НС. Этот алгоритм получил название back propagation (обратное распространение ошибки). Впервые, в 1974 году, его предложил советский математик Галушкин А. И. Позже, в 1986 году, он был немного усовершенствован группой американских ученых, которые и дали ему такое название back propagation.

Математический вывод алгоритма обратного распространения ошибки при квадратической функции потерь я уже приводил в курсе по машинному обучению. Здесь же наглядно продемонстрирую принцип его работы на примере простой трехслойной НС.

Пусть начальные веса связей выбираются случайным образом в диапазоне [-0.5; 0,5]. Верхний индекс у весовых коэффициентов показывает их принадлежность к тому или иному слою. Каждый нейрон имеет дифференцируемую функцию активации .

На первом шаге делается прямой проход по сети. Пропускаем через нее вектор наблюдения  и запоминаем все выходные значения нейронов скрытых слоев:

      

и последнее выходное значение d:

После этого вычисляется величина ошибки, как производная по функции потерь:

В частности, при квадратической функции потерь, имеем:

На данный момент все должно быть понятно. Мы много раз подробно рассматривали процесс распространения сигнала по НС, и вы это уже хорошо себе представляете. А вот дальше начинается самое главное – обратное распространение ошибки.

Итак, у нас есть ошибка  и выбранная функция активации . Первое, что нам нужно, – это вычислить локальный градиент для выходного нейрона. Это делается по формуле:

Используя вычисленный локальный градиент, пропускаем его обратно по весам связей и вычисляем ошибки для предыдущего слоя:

А затем, по аналогии, вычисляются следующие значения локальных градиентов:

Для первого скрытого слоя, снова выполняется пересчет ошибок:

и соответствующих локальных градиентов:

После этого выполняется корректировка весов связей в соответствии с градиентным алгоритмом, начиная с последнего (выходного) слоя и доходя до первого:

 при

 при

В результате, мы выполнили одну итерацию алгоритма обучения НС. На следующей итерации следует взять другой входной вектор из обучающего множества. Лучше всего это сделать случайным образом, чтобы не формировались возможные ложные закономерности в последовательности данных при обучении НС. Повторяя много раз этот процесс, весовые коэффициенты   будут все точнее формировать выходные значения для обучающей выборки.

Вот так, в целом выглядит идея работы алгоритма обучения по методу back propagation (обратного распространения ошибки). Давайте теперь в качестве примера обучим следующую НС:

В качестве обучающего множества выберем все возможные варианты (здесь 1 – это да, -1 – это нет):

Вектор наблюдений

Требуемый отклик

[-1, -1, -1]

-1

[-1, -1, 1]

1

[-1, 1, -1]

-1

[-1, 1, 1]

1

[1, -1, -1]

-1

[1, -1, 1]

1

[1, 1, -1]

-1

[1, 1, 1]

-1

На каждой итерации работы алгоритма, мы будем подавать случайно выбранный вектор и корректировать веса, чтобы приблизиться к значению требуемого отклика. В качестве функции активации выберем гиперболический тангенс:

со значением производной:

Пример реализации алгоритма back propagation на Python с использованием тензоров пакета PyTorch:

neuro_net_12.py: https://github.com/selfedu-rus/neuro-pytorch/

Конечно, это довольно простой, примитивный пример, частный случай, когда можно обучить НС так, чтобы она вообще не выдавала никаких ошибок. Чаще всего в реальных задачах остается некоторый процент ошибок и наша задача сделать так, чтобы этих ошибок было как можно меньше.

Видео по теме