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

Что мы рассмотрим?

Мы рассмотрим следующие алгоритмы оптимизации с их плюсами и минусами:

  1. Алгоритмы, основанные на правиле обновления веса.
  • Градиентный спуск
  • Градиентный спуск на основе импульса
  • Нестеров Ускоренный градиентный спуск

2. Алгоритмы оптимизации на основе размера партии.

  • Пакетный градиентный спуск
  • Мини-пакетный градиентный спуск
  • Стохастический градиентный спуск

3. Алгоритмы оптимизации на основе адаптивной скорости обучения.

  • Адаград
  • RMSProp
  • Адам

Итак, не теряя много времени, начнем с наших алгоритмов:

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

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

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

Уравнение градиентного спуска имеет вид

Давайте разберемся в этом уравнении

  1. Qj представляет любой параметр в нашей модели.
  2. α представляет собой скорость обучения, т. е. насколько быстро или медленно вы хотите обновлять параметры.
  3. ∂J(Q)/∂Qj производная, чтобы найти, как функция стоимости изменится, когда мы изменим наши параметры на крошечный бит (также называемый наклоном касательного сечения в точке).

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

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

Но есть проблема с градиентным спуском

Предположим, во время оптимизации нашей модели мы достигли точки, в которой наклон или градиент в этой точке плоский или Δw → 0, в этом случае наше обновление параметра будет очень небольшим или обновления не будет. Так как w = w-η∆w.

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

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

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

Градиентный спуск на основе импульса.

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

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

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

Уравнение для градиентного спуска на основе импульса задается следующим образом:

Vₜ = γ*Vₜ-₁ + η(Δw)- (1)
wₜ₊₁  = wₜ - vₜ - (2)
combining eq 1 and 2 we get
wₜ₊₁ = wₜ - γ*Vₜ-₁ - η(Δw) -(3)
0<γ<1
if γ*Vₜ-₁ is zero, then we have our old gradient descent algo
Let's see how this works
v₀ = 0
v₁ = γ*v₀ + η(Δw₁) = η(Δw₁) (since v₀ is 0)
v₂ = γ*v₁ + η(Δw₂) = γ*η(Δw₁) + η(Δw₂)
Similarly
vₜ = γ^t-1*ηΔw₁ ..... + ηΔwₜ

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

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

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

Преимущество градиентного спуска на основе импульса

  • Он будет быстро обновляться даже в областях плато графика градиентного спуска, в отличие от алгоритма градиентного спуска.

Недостаток градиентного спуска на основе импульса

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

Несмотря на эти недостатки, он все равно сходится быстрее, чем градиентный спуск.

Ускоренный градиентный спуск Нестерова

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

Давайте снова посмотрим на уравнение для градиентного спуска на основе импульса.

wₜ₊₁ = wₜ - γ*Vₜ-₁ - η(Δw)

Как видите, из wₜ вычитаются два члена, что приводит к большому обновлению wₜ₊₁, что, в свою очередь, приводит к перерегулированию. Итак, что сделал Нестеров, так это разбил приведенное выше уравнение на две части.

wₐ = wₜ - γ*Vₜ-₁
wₜ₊₁ = wₐ - η(Δwₐ)
vₜ = γ*Vₜ-₁ + η(Δwₐ)

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

Алгоритм оптимизации на основе размера пакета

В основном это означает, сколько примеров ваша модель на самом деле видит, прежде чем она обновит параметры веса. В зависимости от размера партии их можно разделить на 3 категории.

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

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

X = np.arange(10) # input features having 10 examples
Y = np.arange(10) # output labels having 10 examples
for a in range(epochs):
    for x,y in zip(X,Y):
       Δw+=calculate_grad(w,x,y)
    w = w - η(Δw)

Преимущества пакетного градиентного спуска

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

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

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

Стохастический градиентный спуск

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

X = np.arange(10) # input features having 10 examples
Y = np.arange(10) # output labels having 10 examples
for a in range(epochs):
    for x,y in zip(X,Y):
       Δw+=calculate_grad(w,x,y)
       w = w - η(Δw)

Преимущества стохастического градиентного спуска

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

Недостатки стохастического градиентного спуска

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

Пакетный мини-градиентный спуск

Mini Batch предлагает лучшее из обоих миров. В этом мы обновляем параметры после просмотра подмножества примеров.

X = np.arange(10) # input features having 10 examples
Y = np.arange(10) # output labels having 10 examples
Batch_size=2
for a in range(epochs):
    count=0
    for x,y in zip(X,Y):
       count+=1
       Δw+=calculate_grad(w,x,y)
       if(count%Batch_size):
           w = w - η(Δw)

Преимущества мини-пакетного градиентного спуска

  • Он использует преимущества векторизации, из-за чего обработка выполняется быстро.
  • Шум можно контролировать, настроив размер партии.

Предпочтительные размеры пакетов — 32, 64, 128 в зависимости от размера набора данных.

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

Адаптивная скорость обучения

Зачем нам нужна адаптивная скорость обучения?

На изображении выше предположим, что X1 — это разреженный объект, а X2 — плотный объект.

поэтому, если написать уравнение для градиента для w1 и w2, оно будет

Δw₁ = f(x)*(1-f(x))*x1
Δw₂ = f(x)*(1-f(x))*x2
Gradient Descent for w1 and w2
w1 = w1 - η(Δw₁)
w2 = w2 - η(Δw₂)

Итак, мы видим, что градиенты напрямую зависят от функции. Теперь, если X1 разреженное, то большинство элементов в нем будут нулевыми. В алгоритме градиентного спуска мы видим, что если градиент равен нулю, параметр не будет обновляться. Таким образом, для разреженных функций мы хотим, чтобы всякий раз, когда мы получаем какой-либо ненулевой элемент, скорость обучения должна быть высокой, чтобы она делала большое обновление в w (чтобы получить максимальную информацию от этих элементов). Точно так же в случае плотных функций параметры будут обновляться очень часто, и для этого мы хотим, чтобы наша скорость обучения была низкой, поскольку наше Δw₂ будет высоким.

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

У нас есть три алгоритма для решения одной и той же проблемы.

  • Адаград

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

Уравнение для Адаграда задается как

Vₜ = Vₜ-₁ + (Δw)^2 - (Eq.1)
wₜ₊₁  = wₜ - (η/Vₜ + ε)*(Δw) - (Eq.2)

Понимание приведенного выше уравнения:

  • Vₜ — это исторический термин, теперь из уравнения 1 мы видим, что для разреженных признаков Vₜ будет очень маленьким (поскольку (Δw)² будет равно нулю для большинства элементов).
  • Теперь, если мы разделим η на небольшое значение Vₜ, это приведет к большому обновлению wₜ₊₁ (подумайте об этом!).
  • Точно так же для плотных объектов Vₜ будет большим значением (поскольку (Δw)² будет ненулевым для большинства элементов).
  • Теперь, если мы разделим η на большое значение Vₜ, это сделает небольшое обновление wₜ₊₁ (поскольку скорость обучения снижается до небольшого значения из-за деления на большое значение!).

Но есть проблема с Adagrad

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

RMSProp

RMSProp решает проблему, созданную из-за Adagrad, контролируя параметр Vₜ от взрыва.

Уравнение для RMSProp имеет вид

Vₜ = β*Vₜ-₁ + (1-β)*(Δw)^2 - (Eq.1)
wₜ₊₁  = wₜ - (η/Vₜ + ε)*(Δw) - (Eq.2)

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

Адам

Адам — один из наиболее часто используемых алгоритмов оптимизации в отрасли. Adam представляет собой комбинацию градиентного спуска на основе Momentum и RMSProp.

Уравнение для Адама дается

mₜ = β*Vₜ-₁ + (1-β₁)*(Δw)^2 - (Eq.1)
vₜ = β*Vₜ-₁ + (1-β₂)*(Δw)^2 - Eq.2
wₜ₊₁  = wₜ - (η/Vₜ + ε)*(mₜ) - (Eq.3)
  • mₜ отвечает за поддержание импульса алгоритма и предотвращение его застревания в области плато.
  • Vₜ отвечает за адаптивную скорость обучения

Домашнее задание для вас

  • Есть еще один шаг, связанный с Адамом, и это исправление предубеждений. Проведите небольшое исследование по этому поводу.
  • Помимо вышеперечисленных алгоритмов оптимизации, есть еще несколько, которые могут помочь быстрее обучить вашу модель. Исследуйте тех.

Если вам понравилась статья, пожалуйста, нажмите на значок хлопка ниже👏👏