Connect with us

ИИ 101

Что такое градиентный спуск?

mm

Что такое градиентный спуск?

Если вы читали о том, как обучаются нейронные сети, вы, скорее всего, уже сталкивались с термином “градиентный спуск”. Градиентный спуск является основным методом оптимизации производительности нейронной сети, снижая уровень ошибок/потерь сети. Однако градиентный спуск может быть немного трудным для понимания для тех, кто новичок в машинном обучении, и эта статья попытается дать вам приличное представление о том, как работает градиентный спуск.

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

Что такое градиенты?

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

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

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

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

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

Расчет градиентов и градиентного спуска

Градиентный спуск начинается с места высоких потерь и, посредством нескольких итераций, делает шаги в направлении наименьших потерь, стремясь найти оптимальную конфигурацию весов. Фото: Роман Сузи via Wikimedia Commons, CCY BY SA 3.0 (https://commons.wikimedia.org/wiki/File:Gradient_descent_method.png)

Чтобы выполнить градиентный спуск, градиенты должны быть рассчитаны сначала. Чтобы рассчитать градиент, нам нужно знать функцию потерь/стоимости. Мы будем использовать функцию стоимости, чтобы определить производную. В исчислении производная просто относится к наклону функции в данной точке, поэтому мы по сути рассчитываем наклон холма на основе функции потерь. Мы определяем потерю, запуская коэффициенты через функцию потерь. Если мы представим функцию потерь как “f”, то мы можем заявить, что уравнение для расчета потери следующее (мы просто запускаем коэффициенты через нашу выбранную функцию стоимости):

Потеря = f(коэффициент)

Затем мы рассчитываем производную или определяем наклон. Получение производной потери скажет нам, в каком направлении вверх или вниз по наклону, давая нам соответствующий знак для корректировки наших коэффициентов. Мы представим соответствующее направление как “дельта”.

дельта = функция_производной(потеря)

Теперь мы определили, в каком направлении вниз по наклону к точке наименьшей потери. Это означает, что мы можем обновить коэффициенты в параметрах нейронной сети и, возможно, снизить потерю. Мы обновим коэффициенты на основе предыдущих коэффициентов минус соответствующее изменение значения, определенное направлением (дельта) и аргументом, который контролирует величину изменения (размер нашего шага). Аргумент, который контролирует размер обновления, называется “скоростью обучения“, и мы представим его как “альфа”.

коэффициент = коэффициент – (альфа * дельта)

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

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

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

Типы градиентного спуска

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

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

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

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

Блогер и программист с специализацией в Machine Learning и Deep Learning темах. Daniel надеется помочь другим использовать силу ИИ для социального блага.