содержание
Предположения сценария для градиентного спуска
Математическое объяснение алгоритма градиентного спуска
Примеры алгоритмов градиентного спуска
Градиентный спуск для одномерных функций
Градиентный спуск для многомерных функций
Реализация алгоритма градиентного спуска
Перепечатать адресМожно совместить с моим постом в блогеРеализация загрузки градиента NumpyПо сравнению
- Предположения сценария для градиентного спуска
- градиент
- Математическое объяснение алгоритма градиентного спуска
- Примеры алгоритмов градиентного спуска
- Реализация алгоритма градиентного спуска
- Further reading
Эта статья начнется со сцены спуска, сначала изложит основную идею алгоритма градиентного спуска, затем математически объяснит принцип алгоритма градиентного спуска и, наконец, реализует простой пример алгоритма градиентного спуска!
Предположения сценария для градиентного спуска
Основную идею градиентного спуска можно сравнить с процессом спуска с горы. Предположим сценарий: человек застрял на горе и ему нужно спуститься с горы (т.е. найти самую низкую точку горы, которая является долиной). Но в это время густой туман на горе был очень густым, в результате чего видимость была очень плохой. Следовательно, путь вниз с горы определить невозможно, и он должен использовать информацию вокруг себя, чтобы найти путь вниз с горы. В это время он может использовать алгоритм градиентного спуска, чтобы помочь себе спуститься с горы. Конкретно, исходя из его текущего положения, ищем самое крутое место в этом положении, а затем идем в сторону места, где высота горы падает.Так же, если наша цель подняться на гору, то есть подняться вершине горы, то в это время она должна подниматься в самом крутом направлении. Затем каждый раз, когда вы будете проходить определенное расстояние, вы будете многократно использовать один и тот же метод и, наконец, сможете успешно добраться до долины.
image.png
Можно также предположить, что самая крутая часть горы не видна сразу невооруженным глазом, а требует сложного инструмента для измерения, и в то же время человек имеет возможность измерить самое крутое направление в это время. Таким образом, каждый раз, когда человек проходит какое-то расстояние, требуется время, чтобы измерить самое крутое направление в этом месте, что отнимает много времени. Итак, чтобы добраться до подножия горы до захода солнца, необходимо максимально сократить количество направлений. Это дилемма.Если измерение частое, оно может обеспечить абсолютно правильное направление спуска, но это очень трудоемко.Если измерение слишком маленькое, есть риск отклонения от трассы. Следовательно, необходимо найти подходящую частоту для измерения направления, чтобы направление спуска не было ошибочным, и в то же время это не занимало слишком много времени!
градиентный спуск
Основной процесс градиентного спуска очень похож на сцену спуска с горы.
Во-первых, у нас естьдифференциалФункция. Эта функция представляет гору. Наша цель — найти минимум этой функции, который является основанием горы. Согласно предыдущему сценарному предположению, самый быстрый способ спуститься с горы — это найти самое крутое направление текущего положения, а затем спуститься в этом направлении, соответствующем функции, то есть найти значение заданной точки .градиент, а затем в направлении, противоположном градиенту, вы можете заставить значение функции падать быстрее всего! Поскольку направление градиента — это направление, в котором функция изменяется быстрее всего (подробно будет объяснено позже).
Поэтому мы неоднократно используем этот метод для многократного получения градиента, и, наконец, мы можем достичь локального минимума, что аналогично процессу спуска с горы. И нахождение градиента определяет самое крутое направление, которое является средством измерения направления в сцене. Так почему же направление градиента является самым крутым? Далее начнем с дифференциации
дифференциал
Существуют разные точки зрения на значение дифференциации. Наиболее часто используются две из них:
-
На графике функции наклон касательной в точке
-
скорость изменения функции
Несколько примеров дифференциации:image.png
Все приведенные выше примеры относятся к дифференцированию с одной переменной.Когда функция имеет несколько переменных, существует дифференцирование с несколькими переменными, то есть каждая переменная дифференцируется отдельно.
image.png
градиент
Градиент на самом деле является обобщением многомерной дифференциации.
Вот пример:
image.png
Мы видим, что градиент должен различать каждую переменную отдельно, а затем разделять их запятыми.Градиент заключен в , что указывает на то, что градиент на самом деле является вектором.
Градиент — очень важное понятие в исчислении, и значение градиента упоминалось ранее.
- В одномерной функции градиент фактически является производной функции, представляющей наклон касательной к функции в данной точке.
- В многомерной функции градиент представляет собой вектор, вектор имеет направление, а направление градиента указывает направление наискорейшего подъема функции в данной точке.
Это также объясняет, почему нам нужно сделать все возможное, чтобы найти градиент! Нам нужно достичь подножия горы, и нам нужно наблюдать за самым крутым местом в это время на каждом шагу, а уклон подсказывает нам это направление. Направление градиента — это направление, в котором функция растет быстрее всего в данной точке, тогда противоположное направление градиента — это направление, в котором функция быстрее всего падает в данной точке, что нам и нужно. Итак, пока мы продолжаем идти в направлении градиента, мы можем достичь локального минимума!
image.png
Математическое объяснение алгоритма градиентного спуска
Выше мы потратили много места на введение основных идей и предположений сценария алгоритма градиентного спуска, а также концепции и идеи градиентов. Начнем математически объяснять процесс вычислений и идею алгоритма градиентного спуска!
image.png
Смысл этой формулы таков: J является функцией Θ.Наше текущее положение Θ0, и нам нужно пройти от этой точки до точки минимума J, которая является подножием горы. Прежде всего, мы сначала определяем прямое направление, которое является обратным градиенту, а затем берем размер шага расстояния, который равен α, После этого шага мы достигаем точки Θ1!
image.png
Вот некоторые распространенные вопросы об этой формуле:
- Что означает альфа?
α вызывается в алгоритме градиентного спуска какскорость обученияилиразмер шага, что означает, что мы можем контролировать расстояние каждого шага через α, чтобы гарантировать, что шаги не будут слишком большими, чтобы тащить яйца, ха-ха, на самом деле, это не значит идти слишком быстро и пропустить самую нижнюю точку. В то же время следите за тем, чтобы не идти слишком медленно, из-за чего солнце садится, а не спускается с горы. Так что выбор α часто очень важен в градиентном спуске! α не может быть слишком большим или слишком маленьким, слишком маленькое значение может привести к задержке достижения самой нижней точки, а слишком большое может привести к тому, что самая нижняя точка будет пропущена!
image.png
- Почему градиент умножается на отрицательный знак?
Знак минус перед градиентом означает движение в направлении, противоположном градиенту! Как мы упоминали ранее, направление градиента на самом деле является направлением, в котором функция растет быстрее всего в этой точке! И нам нужно идти в направлении самого быстрого спуска, что, естественно, является направлением отрицательного градиента, поэтому нам нужно добавить здесь отрицательный знак.
Примеры алгоритмов градиентного спуска
У нас есть базовое понимание процесса вычисления алгоритма градиентного спуска, поэтому давайте рассмотрим несколько небольших примеров алгоритма градиентного спуска, начиная с одномерной функции.
Градиентный спуск для одномерных функций
Предположим, что существует функция одной переменной
image.png
Дифференциация функции
image.png
инициализация, начиная с
image.png
скорость обучения
image.png
По расчетной формуле градиентного спуска
image.png
Запускаем итеративный процесс расчета градиентного спуска:
image.png
Как показано на рисунке, после четырех операций, то есть четырех шагов, в основном достигается самая нижняя точка функции, то есть подножие горы.
image.png
Градиентный спуск для многомерных функций
Предположим, что существует целевая функция
image.png
Минимальное значение этой функции теперь рассчитывается методом градиентного спуска. По наблюдению мы можем видеть, что минимальное значение на самом деле является точкой (0, 0). Но далее мы начнем с алгоритма градиентного спуска шаг за шагом, чтобы добраться до этого минимума!
Предположим, что начальная отправная точка:
image.png
Начальная скорость обучения:
image.png
Градиент функции:
image.png
Сделайте несколько итераций:
image.png
Мы обнаружили, что она в основном близка к точке минимума функции
image.png
Реализация алгоритма градиентного спуска
Ниже мы реализуем простой алгоритм градиентного спуска на питоне. Сценарий простойЛинейная регрессияПример: Предположим, теперь у нас есть ряд точек, как показано ниже.
image.png
Мы будем использовать градиентный спуск, чтобы подогнать эту линию!
Во-первых, нам нужно определить функцию стоимости, здесь мы выбираемФункция стоимости среднеквадратичной ошибки
image.png
в этом объявлении
-
m - количество точек в наборе данных
-
½ — константа, так что при вычислении градиента квадратное умножение здесь нейтрализует ½, и естественно нет лишнего постоянного коэффициента, что удобно для последующих вычислений, и не повлияет на результат.
-
y - значение истинной координаты y каждой точки в наборе данных.
-
h - наша функция прогнозирования, основанная на каждом входе x, прогнозируемое значение y вычисляется в соответствии с Θ, то есть
image.png
Из функции стоимости мы видим, что в функции стоимости есть две переменные, поэтому это проблема градиентного спуска с несколькими переменными.Чтобы решить градиент функции стоимости, нужно дифференцировать две переменные по отдельности.
image.png
Уточнены функция стоимости и градиент, а также предсказанная функциональная форма. Мы можем начать писать код. Но перед этим нужно пояснить, что для облегчения написания кода мы все формулы приведем в виде матриц, на питоне очень удобно вычислять матрицы, да и код станет очень лаконичным .
Чтобы перейти к вычислению матрицы, мы замечаем, что функция предсказания имеет вид
image.png
У нас есть две переменные, и чтобы заматрицировать эту формулу, мы можем добавить измерение к каждой точке x, значение этого измерения фиксировано на 1, и это измерение будет умножено на Θ0. Это облегчит наш единый матричный расчет
image.png
Затем мы преобразуем функцию стоимости и градиент в форму умножения матрицы на вектор.
image.png
coding time
Во-первых, нам нужно определить набор данных и скорость обучения
import numpy as np
# Size of the points dataset.
m = 20
# Points x-coordinate and dummy value (x0, x1).
X0 = np.ones((m, 1))
X1 = np.arange(1, m+1).reshape(m, 1)
X = np.hstack((X0, X1))
# Points y-coordinate
y = np.array([
3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12,
11, 13, 13, 16, 17, 18, 17, 19, 21
]).reshape(m, 1)
# The Learning Rate alpha.
alpha = 0.01
Далее мы определяем функцию стоимости и градиент функции стоимости в виде матричного вектора
def error_function(theta, X, y):
'''Error function J definition.'''
diff = np.dot(X, theta) - y
return (1./2*m) * np.dot(np.transpose(diff), diff)
def gradient_function(theta, X, y):
'''Gradient of the function J definition.'''
diff = np.dot(X, theta) - y
return (1./m) * np.dot(np.transpose(X), diff)
Наконец, основная часть алгоритма, итеративный расчет градиентного спуска.
def gradient_descent(X, y, alpha):
'''Perform gradient descent.'''
theta = np.array([1, 1]).reshape(2, 1)
gradient = gradient_function(theta, X, y)
while not np.all(np.absolute(gradient) <= 1e-5):
theta = theta - alpha * gradient
gradient = gradient_function(theta, X, y)
return theta
Когда градиент меньше 1e-5, это означает, что он перешел в относительно гладкое состояние, похожее на состояние долины.В это время продолжать итерацию не очень эффективно, поэтому можно выйти из цикла в в этот раз!
Полный код выглядит следующим образом
import numpy as np
# Size of the points dataset.
m = 20
# Points x-coordinate and dummy value (x0, x1).
X0 = np.ones((m, 1))
X1 = np.arange(1, m+1).reshape(m, 1)
X = np.hstack((X0, X1))
# Points y-coordinate
y = np.array([
3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12,
11, 13, 13, 16, 17, 18, 17, 19, 21
]).reshape(m, 1)
# The Learning Rate alpha.
alpha = 0.01
def error_function(theta, X, y):
'''Error function J definition.'''
diff = np.dot(X, theta) - y
return (1./2*m) * np.dot(np.transpose(diff), diff)
def gradient_function(theta, X, y):
'''Gradient of the function J definition.'''
diff = np.dot(X, theta) - y
return (1./m) * np.dot(np.transpose(X), diff)
def gradient_descent(X, y, alpha):
'''Perform gradient descent.'''
theta = np.array([1, 1]).reshape(2, 1)
gradient = gradient_function(theta, X, y)
while not np.all(np.absolute(gradient) <= 1e-5):
theta = theta - alpha * gradient
gradient = gradient_function(theta, X, y)
return theta
optimal = gradient_descent(X, y, alpha)
print('optimal:', optimal)
print('error function:', error_function(optimal, X, y)[0,0])
Запустив код, вычисленные результаты выглядят следующим образом
image.png
Подогнанная прямая выглядит следующим образом
image.png
резюме
До сих пор мы в основном представили основную идею и поток алгоритма метода градиентного спуска и реализовали простой алгоритм градиентного спуска, чтобы соответствовать прямой линии в python!
Наконец, вернемся к сценарным предположениям, предложенным в начале статьи:
Человек, спустившийся с горы, на самом деле представлялАлгоритм обратного распространения, путь спуска с горы на самом деле представляет собой параметр Θ, который искал алгоритм.Наиболее крутое направление текущей точки на горе на самом деле является направлением градиента функции стоимости в этой точке.Инструмент, используемый для наблюдения за самым крутым направлением на сценедифференциал. Время до следующего наблюдения определяется скоростью обучения α в нашем алгоритме.
Видно, что гипотеза сцены и алгоритм градиентного спуска хорошо согласованы!