Мягкое введение в нейронные сети

Нейронные сети IV: Графический подход

Эта серия сообщений о нейронных сетях является частью коллекции заметок во время Facebook PyTorch Challenge, предшествовавшего Программе Deep Learning Nanodegree в Udacity.

СОДЕРЖАНИЕ

  1. Введение
  2. Графическое представление нейронных сетей
  3. Шаблоны в вычислениях - Гейтс
  4. Заключение

1. Введение

Как и в предыдущих частях, мы будем работать с той же структурой нейронной сети.

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

Математически мы вычисляем градиент этих ошибок и обновляем веса следующим образом:

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

2. Графическое представление нейронных сетей.

Пришло время узнать, как ведут себя наши нейронные сети. Если вы когда-либо использовали фреймворк машинного обучения, такой как TensorFlow или PyTorch, мы собираемся попытаться определить, что скрывается за этими несколькими строками кода, которые упрощают вашу жизнь.

Что ж, хотите верьте, хотите нет, но наша дружественная нейронная сеть, с которой мы работали, в точности такая, как на рисунке 1.

Давайте сначала посмотрим, что представляет собой каждая форма и цвет:

Желтые квадраты - переменные. X - вход, Y - выход, каким должен был быть выход прямого процесса; и J - ошибка между реальным выходом Y и Y_hat.

Синие формы соответствуют математическим операциям между слоями. Это в основном поэлементные функции (активации), а также матричное сложение и умножение.

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

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

Идея, которую нам нужно извлечь из этого, заключается в следующем:

Сначала мы вводим наши входные данные z3 и y в качестве входных данных для функции (COST), которая описана в формуле. F7. Их значения выделены серым цветом. Таким образом, прямо сейчас мы можем рассчитать локальные градиенты. Это частные производные текущего уравнения (мы видим их черным цветом под и над полем). Если мы возьмем уравнение. F7, и мы производим его, результат будет (учитывая, что у нас есть только 1-временной шаг, поэтому n = 1):

Затем мы всегда запускаем процесс BackProp с локального градиента самой функции, который, очевидно, равен 1. После этого мы хотим распространить эту ошибку назад к ответственному за совершенную ошибку. Что мы делаем, так это применяем цепное правило, чтобы разложить одну производную на более простые.

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

Функция активации, используемая на этом рисунке, - это сигмовидная функция.

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

Затем, когда он поступает, у нас есть dJ / da2,, что в основном означает, «насколько ответственным за значение J является a2». Применяя цепное правило, мы можем определить, насколько ответственным за этот J является z2 - (1) на рисунке 3.

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

Почему мы рассчитываем эти градиенты?

Зачем распространять значение стоимости J в обратном направлении? Нам нужно вспомнить, как сети учатся. Они обновляют значение весов на основе градиента ошибки по отношению к весам. Мы хотим знать, «насколько веса нейронов ответственны за совершенную ошибку», чтобы мы могли скорректировать их значения и заставить нашу сеть учиться. Итак, в конце концов, мы хотим найти dJ / dW1 и dJ / dW2.

Хорошо, теперь, когда мы знаем инструменты и цели, давайте разработаем обратные уравнения для нашей сети!

Обратное распространение

Посмотрите на следующие уравнения одновременно с обратным ходом на рисунке 1.

Итак, мы идем! Мы выполнили весь процесс BackProp и так легко вычислили интересующие нас градиенты! Это значения, которые мы будем использовать для обновления значений весов и уменьшения ошибки в следующий раз. Но теперь давайте посмотрим поближе и сделаем то, что люди по-прежнему делают лучше, чем машины, - давайте найдем закономерности.

3. Паттерны в вычислениях - Гейтс.

Как мы подробно видели на рисунках 2 и 3, обратное распространение для каждого компонента глобальной сети состоит в основном в умножении градиента, получаемого от конца сети, на локальный градиент. Это волшебство ИИ, и это так просто!

Еще одна закономерность, которую мы видим, - это то, как работают разные блоки. В мире искусственного интеллекта у них есть своя собственная терминология, а именно:

Добавить ворота

В прямом проходе add gates дает добавление входов в качестве выходных.

В обратном проходе добавочные ворота называются дистрибьюторами. Взгляните на одно из пар уравнений B2-B2 или B7-B8. Они представляют собой процесс BackProp каждого из двух шлюзов добавления, имеющихся в сети. Локальный градиент для них обоих равен 1, поэтому мы называем их дистрибьюторами. Они просто захватывают градиент, который к нему приходит, и передают его нетронутым всем его входам.

Умножить ворота

В прямом проходе умножение ворот дает умножение входов в качестве выходных.

В обратном проходе многократные ворота называются переключателями. Взгляните на одно из уравнений пары B4-B5 или B9-B10. Они представляют собой процесс BackProp каждого шлюза умножения в сети. Локальный градиент для них обоих является значением другого входа, поэтому мы называем их переключателями.

Активации

В прямом проходе слои применяют функцию, которую мы выбрали для них (функцию активации), ко входу, чтобы вычислить выход.

При обратном проходе слои просто умножают свое собственное значение производной на входящий градиент, чтобы вычислить выходной градиент (также называемый нижним градиентом). Взгляните на уравнение 6. Две типичные функции активации - сигмовидный или гиперболический тангенс.

Калькулятор стоимости - критерий PyTorch

Затраты (также очень часто называемые потерями), как мы видели, - это ошибка, допущенная сетью при сравнении ее с реальным значением. Это можно интерпретировать как последний шаг в прямом проходе или как первый шаг в обратном проходе.

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

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

4. Вывод

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

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