Открытие черного ящика

Алгоритм основного обучения искусственной нейронной сети: демистификация обратного распространения

Понимание основного процесса работы алгоритма обратного распространения на простом примере

Мотивация

Недавно на интервью по машинному обучению меня попросили объяснить, как работает алгоритм обратного распространения ошибки.

Я не был готов к этому вопросу и не знал, с чего начать. Хотя у меня было некоторое понимание того, как это работает, все это было в моей голове. Я не мог понять, откуда объяснять и какой пример использовать.

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

Предпосылки

Прежде чем начать, я предполагаю, что у вас есть некоторое представление о том, как работает искусственная нейронная сеть.

По крайней мере, до того момента, когда вы знаете, как выглядит типичная архитектура нейронной сети и каковы роли входных слоев, скрытых слоев, синапсов, весов, смещений, выходных слоев и функций стоимости. 😅

Что такое обратное распространение?

Если вы начали знакомиться с машинным обучением и искусственной нейронной сетью, возможно, вы уже встречали термин обратное распространение.

Давайте сначала посмотрим на определение и поймем, что это такое и что оно делает:

Обратное распространение, сокращение от обратное распространение ошибок, представляет собой алгоритм контролируемого обучения искусственных нейронных сетей с использованием градиентного спуска. — Brilliant.org

Учитывая искусственную нейронную сеть и функцию ошибок, алгоритм обратного распространения вычисляет отрицательный градиент функции ошибок по отношению к весам сети.

Это основной алгоритм обучения искусственной нейронной сети.

Если это было давно, то вы, возможно, уже поняли цель обратного распространения.

В этой статье, вместо того, чтобы сосредоточиться на том, что это такое, мы собираемся понять, как это на самом деле работает и почему это так здорово.

Попробуем разобраться на самом простом примере.

Как это работает? - Максимально просто

Чтобы понять алгоритм, давайте возьмем пример простой искусственной нейронной сети с одним входным и одним выходным слоями.

Он имеет вход (x)с весом (w) и выход (ŷ).

Примечание. Здесь мы не собираемся использовать какие-либо скрытые слои, функции активации или добавлять какие-либо единицы смещения.

Поскольку у нас нет скрытых слоев и мы не используем никаких функций активации, наш вывод (ŷ)является произведением ввода (x) и вес (w):

ŷ = x * w

Теперь предположим, что у нас есть обучающие данные с входом (x) = 1,5 и ожидаемым результатом (y) = 0,5.

+-----------+--------------------+
|input(x)   | expected output(y) |
+-----------+--------------------+
| 1.5       | 0.5                |
+-----------+--------------------+

При заданном входе 1,5 мы ожидаем, что наша сеть выдаст результат 0,5.

давайте инициализируем наш вес (w) случайным значением w=0,8 и посмотрим, что получится.

1.5 * 0.8 = 1.2
+-----------+--------------------+---------------+
|input(x)   | expected output(y) | output(ŷ)     |
+-----------+--------------------+---------------+
| 1.5       | 0.5                | 1.2           |
+-----------+--------------------+---------------+

При текущем весе, как видите, получается 1,2.

Теперь нам нужно определить ошибку для нашей сети, с помощью которой она может узнать, насколько плохо она работала.

Для простоты возьмем разницу между фактическим и ожидаемым выходом, а затем возведем ее в квадрат.

j = (ŷ - y)²

Теперь, когда у нас есть функция ошибки (j), наша задача — минимизировать ее. Алгоритм обратного распространения пытается сделать это путем спуска по функции ошибки: это называется градиентным спуском.

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

Теперь, чтобы выполнить обратное распространение, нам нужно вычислить производную (скорость изменения) нашей функции ошибок (j).

Поскольку у нас нет большого контроля над нашей сетью, мы минимизируем нашу ошибку, изменив вес (w).

Наше выражение для скорости изменения (j) по отношению к (w) будет:

Чтобы вычислить нашу первую производную, мы должны использовать цепное правило дифференцирования.

Цепное правило говорит нам, как взять производную функции внутри функции, а правило степени говорит нам уменьшить наш показатель степени 2 и умножить его.

Примечание. Здесь мы берем производную от нашей внешней функции и умножаем ее на нашу внутреннюю функцию. Поскольку y=0,5, что является константой, производная от константы равна 0, а также не изменяется относительно w, поэтому мы остаемся с dŷ/dw.

dj/dw = 2(ŷ - y)*d(ŷ)/dw

Поскольку ŷ=x.w:

dj/dw = 2(ŷ - y) *d(1.5 * w)/d(w) = 2(ŷ-y)*1.5 = 4.5w - 1.5

теперь, когда у нас есть наше уравнение: dj/dw = 4.5w-1.5 давайте выполним градиентный спуск.

По сути, мы собираемся вычесть скорость изменения нашей функции ошибок относительно веса из нашего старого веса и попутно умножить изменение на нашу скорость обучения (lr) = 0,1.

Примечание. Скорость обучения определяет, насколько большой шаг мы хотим сделать.

Наша формула для спуска нашего градиента будет:

w(new) := w(old)-lr(dj/dw)
w(new) := w(old) - 0.1(4.5w(old) - 1.5)

Теперь давайте рассчитаем наш новый вес по этой формуле:

+-----------+--------------------+
|old weight | new weight         |
+-----------+--------------------+
| 0.8       | 0.59               |
+-----------+--------------------+
| 0.59      | 0.4745             |
+-----------+--------------------+
| 0.4745    | 0.410975           |
+-----------+--------------------+
| 0.410975  | 0.37603625         |
+-----------+--------------------+
| 0.37603625| 0.3568199375       |
+-----------+--------------------+
+------------+-----------+
|0.3568199375| 0.333333  |
+------------+-----------+

Мы успешно обучили нашу нейронную сеть.

Оптимальный вес для нашей сети — 0,333.

1.5 * 0.333 = 0.5
+-----------+--------------------+---------------+
|input(x)   | expected output(y) | output(ŷ)     |
+-----------+--------------------+---------------+
| 1.5       | 0.5                | 0.5           |
+-----------+--------------------+---------------+

Заключительные слова

Вот как работает основной процесс обратного распространения, чтобы найти оптимальные веса в искусственных нейронных сетях.

Мы видели процесс для очень простой сети без какой-либо функции активации или смещений. Тем не менее, в реальном мире процесс такой же, но немного сложный, поскольку мы должны распространяться назад ко многим скрытым слоям с единицами нелинейности и смещения.

Я полагаю, что для интервью и выражения вашего понимания этого объяснения достаточно.

Не ваша чашка чая?

Если это объяснение также не цепляет ваш мозг или вы хотите узнать больше, то вы можете следовать серии руководств Нейронная сеть от 3Blue1Brown и серии Раскрытие тайны нейронной сети от Welch Labs.

Они также объяснили пошаговый процесс с хорошими визуальными представлениями.

Или, если вы хотите узнать об этом с другой точки зрения, то вот — хорошее объяснение от Брэндона.

Надеюсь, вы чему-то научились 😀. Спасибо за чтение.