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

В этой части 1 мы изучим и реализуем следующие алгоритмы с нуля в Python.

  1. Градиентный спуск
  2. Стохастический градиентный спуск (SGD)
  3. Пакетный градиентный спуск
  4. Мини-пакетный стохастический градиентный спуск

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

y = 2.5X + 1 (1)

где m = 2,5 и b = 1

Наш X имеет одну функцию со 100 точками данных. Мы собираемся заполнить X случайными значениями от -1 до 1. Затем мы можем вычислить y, используя уравнение (1), показанное выше.

import numpy as np
import random
# set seed for reproducibilty
np.random.seed(1) 
num_samples = 100
X = np.random.uniform(-1.,1.,num_samples)
m = 2.5
b = 1
y = m*X +b

Давайте посмотрим на визуализацию этой функции, выраженной уравнением (1)

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

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

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

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

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

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

Для нашей целевой функции MSE градиенты относительно m и b показаны ниже. Если вам интересно понять, как рассчитать градиенты, нажмите здесь

Код Python для пакетного градиентного спуска

import numpy as np
from sklearn.metrics import mean_squared_error
def batch_gradient_descent(X, y, lr, epochs): 
    m, b = 0.33, 0.48 # initialising the parameters
    # log stores m and b values for differnt updates 
    # mse stores the error
    log, mse = [], [] # lists to store learning process 
    N = len(X) # number of samples
for _ in range(epochs):               
        f = y - (m*X + b)   
        # Updating m and b
        m -= lr * (-2 * X.dot(f).sum() / N)
        b -= lr * (-2 * f.sum() / N)
log.append((m, b))
        mse.append(mean_squared_error(y, (m*X + b)))        
    return m, b, log, mse

На графике ниже показан пакетный градиентный спуск MSE для lr = 0,1 и эпох = 75.

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

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

Код Python для стохастического градиентного спуска:

import numpy as np
from sklearn.metrics import mean_squared_error
def SGD(X, y, lr, epochs):
    m, b = 0.5, 0.5  # initial parameters
    log, mse = [], [] # lists to store learning process
for _ in range(epochs):
        indexes = np.random.randint(0, len(X)) # random sample
        Xs = np.take(X, indexes)
        ys = np.take(y, indexes)
        N = len(X)
        f = ys - (m*Xs + b)
# Updating parameters m and b
        m -= lr * (-2 * Xs*(f).sum() / N)
        b -= lr * (-2 * f.sum() / N)
log.append((m, b))
        mse.append(mean_squared_error(y, m*X+b))
return m, b, log, mse

На приведенном ниже графике показана MSE в зависимости от эпох для lr = 0,85 и эпох = 500. Мы можем заметить, что в нашем примере мы смогли достичь локальных минимумов с более высокой скоростью обучения и большим количеством эпох.

Мини-пакетный градиентный спуск:

При мини-пакетном градиентном спуске обновления выполняются для мини-партии образцов. В нашем примере у нас есть 100 образцов. Таким образом, при размере пакета 10 у нас есть 100 обновлений за 10 эпох. Мини-пакетный градиентный спуск — это алгоритм выбора при обучении нейронной сети.

Код Python для мини-пакетного градиентного спуска

def minibatchgd(X, y, lr, epochs, batch_size):
    m, b = 0.5, 0.5 # initial parameters
    log, mse = [], [] # lists to store learning process
    for _ in range(epochs):
        total_len = len(X)
        for i in range(0, total_len, batch_size):
            Xs = X[i:i+batch_size]
            ys = y[i:i+batch_size]
            N = len(Xs)
            f = ys - (m*Xs + b)
            # Updating parameters m and b
            m -= lr * (-2 * Xs.dot(f).sum() / N)
            b -= lr * (-2 * f.sum() / N)
            log.append((m, b))
            mse.append(mean_squared_error(y, m*X+b))
return m, b, log, mse

График мини-пакетного градиентного спуска для эпох = 10 с lr = 0,5 и batch_size = 10 приведен ниже.

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

Подводя итог, для обучающего набора данных из «m» выборок, если

  1. размер мини-партии = ‘m’. — Пакетный градиентный спуск (все данные берутся за одну эпоху)
  2. размер мини-партии = «1» — стохастический градиентный спуск (одна выборка из всех данных для одной эпохи)
  3. размер мини-партии = ‘m’/100 — градиентный спуск мини-партии (m/100 образцов, взятых для одной эпохи)

Важные замечания:

  1. Скорость обучения гиперпараметров, эпохи, размер партии должны быть изменены так, чтобы MSE достигла минимума (в идеале 0).
  2. Мы можем заметить, что количество эпох в мини-пакетном градиентном спуске значительно меньше, чем в пакетном градиентном спуске и стохастическом градиентном спуске. Это означает, что минимумы достигаются за меньшее время обучения.
  3. Скорость обучения должна быть выбрана тщательно, и это довольно сложная задача.

В следующей части мы обсудим некоторые сложные алгоритмы оптимизатора. Код доступен по адресу https://github.com/bhuvanakundumani/optimizers.git.

Ссылки:
https://ruder.io/optimizing-gradient-descent/
https://www.kdnuggets.com/2020/12/optimization- алгоритмы-нейронные-сети.html
https://towardsdatascience.com/gradient-descent-from-scratch-e8b75fa986cc