Главная/ Блог / Нейросети Часть 2

Все о градиентном спуске
или как учится нейронная сеть

[ Нейросети Часть 2 ]

Все о градиентном спуске или как учится нейронная сеть

Smartiqa Article
  • Дата: 12 октября 2020
  • Автор: Калинин Даниил

Этот материал относится к циклу статей о нейронных сетях


Как нейронные сети получили свое название, из каких компонентов они состоят, как они обучаются и главное - являются ли они полноценным искусственным интеллектом, способным заменить человека?

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

В статье рассказывается о принципе работы сверточных нейронных сетей

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

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

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

Вспомним, как работает нейросеть

Перед тем как начать, давайте освежим в памяти материал прошлой статьи. Из нее мы узнали, что нейронная сеть ‒ это инструмент для восстановления зависимости между входными данными и результатом. Каждый нейрон умножает данные с каждого своего входа на вес связи, определяющий, насколько эти данные важны, а затем суммирует (такая сумма называется взвешенной) все данные. После этого нейрон "активируется" ‒ передает данные дальше, если найденная сумма больше некоторого значения. В противном случае, он затухает, и данные не идут на другие нейроны.
Пример простейшей нейронной сети
Пример простейшей нейронной сети
На изображении выше приведен пример простейшей полносвязной нейросети, каждый слой которой состоит из одного нейрона. Здесь веса связи ‒ это w1, w2, w3 и w4, Σ‒ сумматор, а φ ‒ функция активации.

Человек готовит для нейросети данные в формате (входные-данные, ожидаемый-ответ). Затем происходит следующее:
1. Нейронная сеть прогоняет через себя входные данные, получает ответ (скорее всего неверный);
2. Полученный ответ нейросеть сравнивает с верным, находит ошибку (например, вычитая свой ответ из данного);
3. По вычисленной ошибке нейросеть определяет, как изменить веса связей так, чтобы ошибка стала меньше;
4. Нейросеть меняет веса, уменьшая ошибку;

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

Читайте также

Градиент

Чтобы понять, откуда нейронная сеть узнает, как ей поменять свои параметры (параметрами будем называть веса связей) для уменьшения ошибки, нужно разобраться в том, что такое градиент. На самом деле, градиент (в математике) ‒ это просто стрелочка, которая указывает, в каком направлении функция растет быстрее всего. Звучит, наверное, сложно, но суть очень простая. Давайте посмотрим на график параболы y=x².
График параболы с отмеченной точкой А и градиентом в ней
График параболы с отмеченной точкой А и градиентом в ней
На рисунке мы отметили точку А с координатами (2, 4) и визуализировали градиент в ней. Видно, что получилась голубая стрелочка указывающая в направлении роста. Возможно у читателя возникнет вопрос, почему стрелка направлена именно так. Ответ кроется в глубинах математики, но если коротко, то это связано со скоростью роста функции в этой точке (с ее производной). Странный значок перед y называется набла, это общепринятое обозначение градиента. Такая запись говорит: вот здесь начерчен градиент функции y(x).

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

А причем тут нейросети?

Разобравшись в том, что же такое градиент, читатель задастся вопросом: причем тут нейросети? Ответ очевиден. Помните, нейросеть должна каждый раз находить ошибку между результатом своей работы и верным ответом, а затем определять, как менять веса для уменьшения ошибки. Оказывается, существует очень-очень сложная зависимость ошибки от всех параметров нейросети. То есть
L = f(w1, w2, w3, …, wn),
где L – это ошибка, а f(w1, w2, w3, …, wn) – функция от весов связей в нейронной сети. Думаю, тут стоит прояснить, почему ошибка зависит от параметров модели (так мы иногда будем называть нейросети): нейронная сеть не может повлиять на ответ, подготовленный человеком, но она может изменить свой ответ (который как раз и зависит от всех параметров модели) так, чтобы ошибка стала меньше.

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

И тут перед нами открываются чудеса математики, а именно ‒ антиградиент. Оказывается, если градиент, указывающий в направлении наискорейшего роста функции, просто развернуть на 180 градусов, то он будет указывать в противоположном направлении: направлении наискорейшего убывания функции. Это замечательное свойство поможет нам постепенно "спуститься" к минимуму функции ошибки.

Градиентный спуск

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

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

Тут есть множество тонкостей, например, на каждом шаге спуска мы умножаем значение градиента на постоянную величину от 0 до 1 (эта величина подбирается человеком), чтобы не шагнуть слишком далеко. Может возникнуть такая ситуация, что минимум находится слева от нас, мы шагаем чересчур далеко, и вот минимум уже справа от нас, шагаем еще раз ‒ минимум опять слева, и так до бесконечности. Такой случай со знакомой нам параболой приведен в анимации ниже.
Пример неудачного градиентного спуска
Пример неудачного градиентного спуска
Как видно из анимации, из-за слишком большого значения градиента вблизи точки (0, 0), мы постоянно "перескакиваем" минимум, поэтому и нужно умножать градиент на число от 0 до 1, а спуск к минимуму делать плавным.

Напоследок

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

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

Ну, и в самом конце, приведу красивую анимацию градиентного спуска для одной из функций, чтобы вы поняли, что математика бывает очень красивой наукой.
Пример градиентного спуска
Пример градиентного спуска
12 ОКТЯБРЯ / 2020
Как вам материал?

Читайте также