Курс машинного обучения продолжается некоторое время, и сегодня я познакомлю вас с первым алгоритмом машинного обучения с помощью Python из 0: Gradient Descent!
Давайте изучим этот классический алгоритм шаг за шагом, начиная с небольшого примера.
1. Как спуститься с горы как можно быстрее?
Прежде чем изучать алгоритм, давайте рассмотрим пример из повседневной жизни: спуск с горы. Представьте, что вы отправляетесь в путешествие и поднимаетесь на гору, после того, как вы поднялись на вершину горы, уже вечер, и скоро солнце сядет, поэтому вам нужно найти способ как можно скорее спуститься с горы, а затем пойти есть Haidilao.
Как быстрее всего спуститься с горы? Правильно, сжаться в шар и скатиться с самого крутого направления, но мы люди, а не шары, поэтому мы не можем скатиться напрямую, но мы можем извлечь уроки из этого метода и изменить нашу стратегию.
Чтобы спуститься с горы быстрее всего, вам нужно всего лишь выполнить следующие 3 шага в цикле:
- Оглянитесь вокруг, чтобы найти самый крутой участок дороги
- пройти некоторое расстояние по самому крутому участку дороги
- Повторяйте вышеуказанные шаги до подножия горы.
Предполагая, что у вас есть возможность найти самый крутой маршрут в вашем текущем местоположении, вам нужно только повторить вышеуказанные шаги, чтобы спуститься к подножию горы, чтобы съесть Хайдилао за кратчайшее время и на кратчайшем расстоянии!
Это практический пример метода градиентного спуска Давайте формально изучим основную идею метода градиентного спуска.
Во-вторых, основная идея градиентного спуска
Шаги метода математического градиентного спуска точно такие же, как и в примере со спуском с горы, но они выражены в математической формуле, вот изображение функции для наглядного пояснения:
Думайте об этом функциональном изображении как о горе. В этот момент вы находитесь на вершине горы и хотите найти самый быстрый способ спуститься с горы. Затем выполните 3 шага, упомянутых выше, чтобы спуститься с горы. самое крутое направление спуска, пройти немного дальше и так далее, и, наконец, добраться до вышеуказанного маршрута спуска.
2.1 Какую задачу решает алгоритм?
Чтобы спуститься с горы как можно быстрее, мы использовали метод градиентного спуска; затем, в соответствии с математической кривой, применение метода градиентного спуска к функции заключается в том, чтобы как можно быстрее найти глобальный минимум или локальный минимум функции. , а затем, в соответствии с проблемой машинного обучения, метод градиентного спуска заключается в том, чтобы как можно скорее найти минимальное значение функции стоимости модели, а затем получить параметры модели;
Следовательно, задача, решаемая методом градиентного спуска, состоит в том, чтобы найти минимальное значение функции при наибольшей скорости.
2.2 Как это выразить математическими формулами?
Давайте сначала воспользуемся формулой для выражения шагов спуска с горы:
Как и формула спуска, формула градиентного спуска может быть записана в одну строку формулы:
Поясним эту формулу подробнее на примере спуска с горы:
- левая часть уравнения
моя позиция на вершине горы в следующий момент: следующее значение функции
- правая часть уравнения
моя позиция на вершине горы в текущий момент: текущее значение функции
- скорость обучения
: размер шага итерации алгоритма
-
Является самым быстрым направлением спуска: направление, в котором значение функции падает быстрее всего в текущий момент
-
- запланированное расстояние в текущий момент: расстояние, на которое алгоритм спускается на текущей итерации
-
Это можно понимать как гора, с которой вы хотите спуститься: функция, выполняемая алгоритмом
здесьЭто называется скорость обучения в алгоритме, Хотя это трудно понять из названия, его функция состоит в том, чтобы контролировать размер шага алгоритма для уменьшения каждой итерации, то есть, сколько шагов нужно делать каждый раз, спускаясь с горы.
Вам может быть интересно, почему к направлению спуска добавляется знак минус.На самом деле, математически эта формулаЭто означает, чтобы найти частную производную, также называется, чтобы найти градиент, Градиент функции - это направление, в котором значение функции увеличивается быстрее всего, и добавление отрицательного знака здесь означает направление, в котором значение функции падает быстрее всего, что означает самый быстрый спуск (самое крутое) направление.
Однако ни скорость обучения, ни градиент не являются величиной, которую нужно уменьшить на значение функции в текущий момент, Величина снижения текущей функции равна произведению двух, не следует ошибочно думать, что скорость обучения — это расстояние, на которое падает текущая функция, это всего лишь мера, ее можно понимать как шкалу, а не фактическое значение.
Давайте посмотрим на итерационный процесс алгоритма интуитивно, исходя из фактической кривой градиентного спуска.
3. Интуитивное понимание метода градиентного спуска
Следующий пример объясняет одномерный () Процесс градиентного спуска:
Алгоритм итеративно спускается от фиолетовой точки данных в правом верхнем углу кривой и, наконец, спускается к нижней зеленой точке, чтобы найти минимальное значение функции, и завершает алгоритм, чтобы подробно проанализировать процесс спуска:
- Вычислить градиент (наклон или частную производную) в первой точке данных, где градиент больше 0
- Вычислить следующее значение функции:
- Повторяйте вышеуказанные шаги, пока градиент нижней зеленой точки не станет равным 0.
Вот краткое описание скорости обученияВлияние на алгоритм:
- если
Если он слишком мал, размер шага каждого обновления очень мал, что приводит к большому количеству шагов для достижения оптимальной точки;
- если
Если он слишком велик, размер шага каждого обновления очень велик.При приближении к оптимальной точке легко пропустить оптимальную точку, потому что размер шага слишком велик, и в конечном итоге алгоритм не может сходиться или даже расходиться;
Хотя скорость обучения повлияет на размер шага итерации, нужно ли нам каждый раз вручную обновлять скорость обучения?
ненужный! Потому что размер шага итерации будет каждый раз автоматически уменьшаться! По мере того, как точка данных приближается к самой низкой точке, наклон в этой точке становится все меньше и меньше, значение градиентастановится меньше и
, поэтому после умножения двух
также становится меньше, что в дальнейшем приводит к
Значение уменьшается все медленнее.
Когда алгоритм, наконец, дойдет до нижней точки, наклон в зеленой точке будет равен 0, то есть градиент равен 0, и формула градиентного спуска больше не изменится:
Поэтому алгоритм считает, что оптимальное значение найдено и больше не спускается итеративно, и на этом алгоритм заканчивается.
Этот пример итеративно спускается справа налево.Если начальная точка данных находится слева, будет ли алгоритм работать правильно? Ничего страшного, разница только в том, что градиент меньше 0, а знак минус в формуле становится знаком плюс, можете попробовать проанализировать сами.
В-четвертых, метод градиентного спуска для соответствия функциональной линии
После того, как теория будет представлена, давайте перейдем к практической части.Denglong поможет вам реализовать метод градиентного спуска с Python и использовать этот алгоритм для соответствия следующим точкам данных (население-прибыль):
Из-за нехватки места я поясняю только тот код, который считаю здесь более важным.Другие основные данные по загрузке приводить не будем.Пакет руководства не привожу.В конце статьи есть полный код,и комментарии внутри очень подробно.Рекомендую скачать и съесть.Star Oh!
4.1 Выбор модели
Этот набор данных относительно прост, всего с одним популяционным признаком, но для удобства вычисления кода мы искусственно добавляем признаки функциональная модель с использованием линейной регрессии:
Сначала определим эти два параметра:
# X.shape[1] = 2,表示参数数量 n = 2
# theta = [theta_0 = 0, theta_1 = 0]
theta = np.zeros(X.shape[1])
Наша конечная цель – найти оптимальные параметры (,
), чтобы можно было минимизировать общую среднеквадратичную ошибку аппроксимации прямой линией Как выразить среднеквадратичную ошибку? Это требует введения функции стоимости.
4.2 Функция стоимости
Функция стоимости, как следует из названия, представляет собой величину ошибки подбора, соответствующую каждому набору параметров.Если вы хотите добиться наилучшего эффекта подбора набора данных, функция стоимости, соответствующая параметру, должна принимать минимальное значение.Здесь Я выбираю обычно используемую среднеквадратичную ошибку в качестве функции стоимости:
Эта функция стоимости вычисляет набор параметров (,
) Среднеквадратическая ошибка между предсказанным значением подобранных данных и истинным значением, давайте посмотрим, как эта функция записывается в коде, Здесь нам нужно использовать некоторые знания линейной алгебры:
# Cost Function
# X: R(m * n) 特征矩阵
# y: R(m * 1) 标签值矩阵
# theta: R(n) 线性回归参数
def cost_function(theta, X, y):
# m 为样本数
m = X.shape[0]
# 误差 = theta * x - y
inner = X @ theta - y
# 将向量的平方计算转换为:列向量的转置 * 列向量
square_sum = inner.T @ inner
# 缩小成本量大小,这里无特殊含义
cost = square_sum / (2 * m)
# 返回 theta 参数对应的成本量
return cost;
Наш метод градиентного спуска применяется к этой функции стоимости, чтобы найти минимальное значение функции стоимости, а затем найти соответствующие параметры при взятии минимального значения (,
).
4.3 Вычисление градиента
Градиентный спуск должен использовать градиент определенной точки, то есть производную.Посмотрите на код для нахождения градиента:
# 计算偏导数
def gradient(theta, X, y):
# 样本数量
m = X.shape[0]
# 用向量计算复合导数
inner = X.T @ (X @ theta - y)
# 不要忘记结果要除以 m
return inner / m
На самом деле это не сложно, это функция стоимостиСделайте сложный вывод:
Поскольку приведенный выше код представлен вектором, столбец векторов содержит все параметры, поэтому умножение векторов, содержащих параметры, эквивалентно символу суммирования в формуле, и порядок вычисления вектора будет немного другим, вот Не буду вдаваться в подробности, но пока могу понять.
4.4 Выполнение алгоритма пакетного градиентного спуска
Готово, вот и настала самая важная часть, логический код метода пакетного градиентного спуска на самом деле очень прост, то есть выполнить цикл =_=:
# 批量梯度下降法
# epoch: 下降迭代次数 500
# alpha: 初始学习率 0.01
def batch_gradient_decent(theta, X, y, epoch, alpha = 0.01):
# 计算初始成本:theta 都为 0
cost_data = [cost_function(theta, X, y)]
# 创建新的 theta 变量,不与原来的混淆
_theta = theta.copy()
# 迭代下降 500 次
for _ in range(epoch):
# 核心公式:theta = theta - 学习率 * 梯度
_theta = _theta - alpha * gradient(_theta, X, y)
# 保存每次计算的代价数据用于后续分析
cost_data.append(cost_function(_theta, X, y))
# 返回最终的模型参数和代价数据
return _theta, cost_data
Входящие параметры мы вводили ранее, а затем просматриваем:
- theta: параметр линии, который нужно предсказать
- X: образец значения абсцисс
- y: образец значения ординаты
- эпоха: количество итераций для спуска
- альфа: скорость обучения
Конечным результатом является параметр с наименьшей ошибкой подбора исходных данных после 500 итераций.и данные о затратах для каждого расчета
.
Дополнение: партия здесь означает, что среднеквадратическая ошибка всех выборок вычисляется на каждой итерации, а не по одной выборке за раз, но мы часто опускаем слово партия, что прямо называется методом градиентного спуска.
4.5 Результаты тестовой подгонки
Давайте вызовем приведенный выше метод пакетного градиентного спуска и посмотрим на предсказанные параметры:
epoch = 500
final_theta, cost_data = batch_gradient_decent(theta, X, y, epoch)
final_theta
вывод:
array([-2.28286727, 1.03099898])
Давайте визуализируем данные о стоимости, чтобы увидеть, продолжает ли она снижаться:
cost_data
Функция стоимости постепенно уменьшается по мере увеличения числа итераций, пока 4,713809 практически не изменится.На данный момент мы нашли параметры линейной модели, которые, по нашему мнению, являются наиболее подходящими данными, поскольку функция стоимости достигла минимального значения.
Тогда посмотрите на эффект примерки, выглядит неплохо:
V. Резюме
Вышеизложенное является моим базовым пониманием метода одномерного градиентного спуска.Есть еще много недостатков.Я надеюсь, что вы можете исправить меня.Некоторые коды в тексте используют знание исчисления и линейной алгебры.Рекомендуется вернуться и просмотреть алгоритм, чтобы лучше понять алгоритм ^_^ !
Кроме того, я также написал собственное резюме о методе многомерного градиентного спуска:Машинное обучение с нуля: введение в многомерный градиентный спуск!, принцип почти тот же, и настоятельно рекомендуется практиковать его.
Проект в тексте супердетален и аннотирован полным кодом:AI-Notes, научитесь не забывать возвращаться и дать мне Звезду Ха.
Эта статья была первоначально опубликована в одноименной учетной записи WeChat «Denglong», следуйте поиску WeChat и отвечайте «1024», вы знаете!