В последнем уроке мы узнали о нашем первом алгоритме машинного обучения под названием «Линейная регрессия». Мы сделали это, используя метод под названием «Обычные наименьшие квадраты», но есть и другой подход. Этот подход становится основой нейронных сетей и называется Градиентный спуск. И пусть вас не пугает название, потому что подход на самом деле довольно прост, и мы также поймем, как его реализовать с помощью sklearn.

Рекомендуется знать основы многомерного исчисления, если вы не знакомы с ним, вы можете изучить его здесь.

Интуиция за градиентным спуском

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

Градиентный спуск – это алгоритм оптимизации, который используется для поиска локальных минимумов дифференцируемой функции.

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

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

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

Теперь, когда мы все прояснили, давайте начнем с понимания градиентного спуска на классическом примере альпиниста. Итак, давайте представим, что у нас есть наш друг Джон, который достиг вершины Эвереста. Вау, это то, чем можно гордиться, но теперь ему нужно достичь дна, поэтому Джон начинает делать шаги в направлении, указывающем на подножие горы, примерно так:

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

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

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

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

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

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

нашей целью было найти параметры θ0, θ1,…,θn. Теперь в OLS у нас была просто формула, которая при подаче входных данных находила матрицу θ. Но в градиентном спуске мы начинаем со случайных значений параметров, а затем продолжаем их изменять, пока не найдем значение параметров, близкое к локальному минимуму функции. ЖДАТЬ! Что это за функция?

Ну, мой плохой позвольте мне объяснить. Цель линейной регрессии — найти линию наилучшего соответствия, но как определить линию наилучшего соответствия? Что ж, наиболее подходящей линией была линия, которая при размещении на точечной диаграмме имела все точки как можно ближе к ней. Но как измерить это математически?

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

И это функция, значение которой мы должны минимизировать с помощью Gradient Descent. Короче говоря, нам нужно найти значение параметров, наиболее близкое к локальным минимумам функции MSE.

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

MSE соответствует описанию, у него есть только один минимум, и это глобальный минимум. Теперь, когда мы прояснили все вышеперечисленное, давайте начнем говорить о шагах в Gradient Descent.

Шаг 1: Указание начальных параметров

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

Шаг 2: Найдите частную производную функции стоимости

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

Как вы можете видеть в частной производной w.r.t. x мы взяли производную только от первого члена и обработали y и z как постоянные и сделали то же самое для частной производной относительно. y где мы взяли производную от второго члена и считали x и z постоянными.

Теперь давайте вычислим производную нашей функции потерь, которую для простоты назовем J(θ). J(θ) есть не что иное, как функция MSE.

Как видим, предсказанное значение ŷ зависит от параметров

Шаг 3: Шаг градиентного спуска

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

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

Если скорость обучения слишком низкая, сходимость будет медленной, а если она слишком высока, значение потерь может выйти за пределы допустимого. Поэтому важно найти оптимальную скорость обучения. Обычно мы начинаем с 0,1 и продолжаем обновлять его, деля на 10, пока не будет найдена оптимальная скорость. Например: 0,1, 0,01, 0,001, …

Шаг 4: Повторяйте до конвергенции

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

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

В sklearn линейная регрессия в linear_model использует OLS для поиска значений параметров, но для использования линейной регрессии с градиентным спуском мы используем SGDRegressor, присутствующий в linear_model. SGD означает стохастический градиентный спуск. Мы будем использовать набор данных о диабете, представленный в sklearn, в этом наборе данных есть словарь с матрицей признаков под ключевыми данными и целевой вектор под ключевой целью. Итак, начнем с загрузки данных.

1
2
3
4
5
6
7
8
9
#Importing the libraries
import numpy as np
from sklearn.datasets import load_diabetes
#Loading the diabetes dataset
diabetes = load_diabetes()
X = diabetes.data
Y = diabetes.target

Теперь, когда у нас есть данные, давайте создадим объект SGDRegressor и обучим его на данных. Для обучения данных мы используем метод fit() как обычно. max_iter используется для определения максимального количества эпох, а alpha используется для установки скорости обучения.

1
2
3
4
#Loading the data to the model
from sklearn.linear_model import SGDRegressor
reg = SGDRegressor(max_iter= 10000, alpha=0.0001)
reg.fit(X,Y)

Теперь давайте проверим, насколько точна модель, найдя значение RMSE. Для этой модели получилось 54,03.

1
2
3
4
#Calculating the mean square error
from sklearn.metrics import mean_squared_error
y_pred = reg.predict(X)
print(np.sqrt(mean_squared_error(Y, y_pred)))

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

Существует две категории градиентного спуска, которые включают стохастический градиентный спуск и пакетный градиентный спуск.

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

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

Алгоритм стохастического градиентного спуска

Как уже упоминалось, этот алгоритм использует один пример на итерацию. Пусть (x(I), y(I) — обучающая выборка

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

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

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

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

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

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

Алгоритм пакетного градиентного спуска

Пусть hθ(x) будет гипотезой линейной регрессии. Тогда функция стоимости определяется как:

Пусть Σ представляет собой сумму всех обучающих примеров от i=1 до m. Где xj(i) представляет j-й признак i-го обучающего примера. Если m велико, это займет много времени. Таким образом, пакетный градиентный спуск не рекомендуется для длинных наборов данных.

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

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

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

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

Спасибо за прочтение