1. Обзор алгоритма градиентного спуска
1. Введение
Метод градиентного спуска, также известный как метод наискорейшего спуска, является наиболее часто используемым методом для решения задач оптимизации без ограничений.Это итерационный метод.Основной операцией каждого шага является решение вектора градиента целевой функции.Отрицательный направление градиента текущей позиции используется в качестве направления поиска (поскольку целевая функция быстрее всего спускается в этом направлении, что также является источником названия метода наискорейшего спуска).
Особенности метода градиентного спуска: чем ближе к целевому значению, тем меньше размер шага, тем медленнее скорость спуска.
Здесь каждый круг представляет собой градиент функции, а самый центр представляет собой крайнюю точку функции.Каждая итерация находит новую позицию в соответствии с градиентом, полученным из текущей позиции (используется для определения направления поиска и скорости вперед вместе с размером шага ) и размер шага , так что непрерывная итерация в конце концов достигает точки локального оптимума целевой функции (если целевая функция является выпуклой функцией, достигается глобальная оптимальная точка).
Мы объясним более интуитивно и ясно, что градиентный спуск на самом деле является формулой:
Вышеприведенная формула является формулой обновления позиции, Проще говоря, каждый раз, когда вы делаете шаг, вы записываете свою текущую позицию, которая представляет собой θi слева от знака равенства, так как далеко вы идете? Ответ должен быть α, так в каком направлении вы движетесь? Ответ — частная производная от J(θ) по θi.
инструкция:
Здесь мы различаем часто используемые функции:
-
Функция потерь (Loss Function) определяется на одном образце и вычисляет ошибку образца.
-
Функция стоимости (Cost Function) определяется на всей обучающей выборке и представляет собой среднее значение всех ошибок выборки, то есть среднее значение функции потерь.
-
Целевая функция определяется как: функция, которую необходимо оптимизировать в конце. Равен эмпирическому риску + структурному риску (то есть функции затрат + сроку регуляризации).
J (θ), используемый в градиентном спуске, является здесь функцией потерь.
2. Вывод
инструкция:
-
Здесь мы используем функцию линейной регрессии с двумя простыми параметрами θ0 и θ1 в качестве примера для вывода.
-
Знания, используемые при выводе:Частная производная
3. Вариант алгоритма градиентного спуска
Существует три основных варианта алгоритма градиентного спуска, главное отличие которых заключается в том, сколько данных используется для вычисления градиента целевой функции. Различные методы в основном выбирают компромисс между точностью и скоростью оптимизации.
1.Batch gradient descent (BGD)
Пакетный градиентный спуск (BGD), который требует вычисленийГрадиент по всему тренировочному набору,который:
Где η - это скорость обучения, которая используется для управления «сил» / «размером шага» обновления.
- преимущество:
Для выпуклых целевых функций гарантируется глобальный оптимум, для невыпуклых целевых функций гарантируется локальный оптимум.
- недостаток:
Медленно; невыполнимо при большом объеме данных; не может оптимизироваться онлайн (т. е. не может обрабатывать динамически генерируемые новые выборки).
2.Stochastic gradient descent (SGD)
Стохастический градиентный спуск (SGD), только вычисленияГрадиент образца, то есть обновить параметры для обучающей выборки xi и ее метки yi:
Постепенно снижая скорость обучения, SGD ведет себя очень похоже на BGD и, наконец, может иметь хорошую сходимость.
- преимущество:
Частота обновления быстрая и скорость оптимизации выше, оптимизация возможна онлайн (новые выборки, сгенерированные динамически, не могут быть обработаны), определенная случайность приводит к шансу выпрыгнуть из локального оптимума (случайность возникает из-за использования градиента образца для замены градиента общего образца).
- недостаток:
Случайность может усложнить сходимость, и даже если оптимальная точка будет достигнута, она все равно будет переоптимизирована, поэтому процесс оптимизации SGD более турбулентный, чем BGD.
3.Mini-batch gradient descent (MBGD)
Мини-пакетный градиентный спуск (MBGD), вычисленияГрадиент мини-пакета из n образцов:
MBGD — наиболее часто используемый метод оптимизации для обучения нейронных сетей.
- преимущество:
Турбулентность во время обновления параметров меньше, процесс сходимости более стабилен, и сложность сходимости снижается; градиент нескольких выборок может быть эффективно рассчитан с использованием существующей библиотеки линейной алгебры.
4. Вызов
С точки зрения вариантов алгоритма градиентного спуска мини-пакетный градиентный спуск (MBGD) является относительно хорошей стратегией, но он также не может гарантировать оптимальное решение. Кроме того, здесь возникает множество вопросов:
1) Как выбрать подходящую скорость обучения?
Если скорость обучения слишком мала, сходимость будет слишком медленной, а если скорость обучения слишком велика, сходимость будет турбулентной или даже отклонится от оптимальной точки.
2) Как определить стратегию корректировки скорости обучения?
В настоящее время скорость обучения в основном регулируется в соответствии с своего рода идеей «отжига», либо в соответствии с заранее определенным режимом, либо динамически изменяя скорость обучения в зависимости от того, удовлетворяет ли изменение значения целевой функции пороговому значению. Однако как «режим», так и «порог» должны быть указаны заранее и не могут быть адаптированы к различным наборам данных.
3) Уместно ли использовать одинаковую скорость обучения для всех обновлений параметров?
Если данных мало, а функции распределены неравномерно, кажется, что мы должны дать большое обновление менее частым функциям.
4) Как выйти из локального оптимума?
Теоретически только строго выпуклые функции могут получить глобальное оптимальное решение с помощью градиентного спуска. Однако то, с чем сталкивается нейронная сеть, в основном представляет собой строго невыпуклую целевую функцию, что также означает, что оптимизация легко попадает в локальный оптимум. На самом деле, наши трудности часто возникают из-за «седловых точек», а не из-за локальных минимумов. Седловая точка обычно имеет одинаковое значение функции потерь вокруг нее, что затрудняет работу SGD, поскольку градиент в каждом направлении близок к 0.
5. Алгоритм оптимизации градиентного спуска
Давайте поговорим о некоторых методах оптимизации градиентного спуска, обычно используемых в глубоком обучении для решения вышеуказанных проблем. Некоторые методы, непригодные для многомерных данных, больше не обсуждаются, например, метод Ньютона в методах второго порядка.
-
Momentum
-
Nesterov accelerated gradient
-
Adagrad
-
Adadelta
-
RMSprop
-
Adam
-
AdaMax
Все вышеперечисленные алгоритмы оптимизации, т.к. исследование блогера не глубокое, заинтересованные могут перейти наРезюме алгоритма оптимизации градиентного спускаподробно изучить.
2. Практика кодекса
1. Пакетный градиентный спуск (BGD)
#引库
#引入matplotlib库,用于画图
import matplotlib.pyplot as plt
from math import pow
#图片嵌入jupyter
%matplotlib inline
#为了便于取用数据,我们将数据分为x,y,在直角坐标系中(x,y)是点
x = [1,2,3,4,5,6]
y = [13,14,20,21,25,30]
print("打印初始数据图...")
plt.scatter(x,y)
plt.xlabel("X")
plt.ylabel("Y")
plt.show()
#超参数设定
alpha = 0.01#学习率/步长
theta0 = 0#θ0
theta1 = 0#θ1
epsilon = 0.001#误差
m = len(x)
count = 0
loss = []
for time in range(1000):
count += 1
#求偏导theta0和theta1的结果
temp0 = 0#J(θ)对θ0求导的结果
temp1 = 0#J(θ)对θ1求导的结果
diss = 0
for i in range(m):
temp0 += (theta0+theta1*x[i]-y[i])/m
temp1 += ((theta0+theta1*x[i]-y[i])/m)*x[i]
#更新theta0和theta1
for i in range(m):
theta0 = theta0 - alpha*((theta0+theta1*x[i]-y[i])/m)
theta1 = theta1 - alpha*((theta0+theta1*x[i]-y[i])/m)*x[i]
#求损失函数J(θ)
for i in range(m):
diss = diss + 0.5*(1/m)*pow((theta0+theta1*x[i]-y[i]),2)
loss.append(diss)
#看是否满足条件
'''
if diss<=epsilon:
break
else:
continue
'''
print("最终的结果为:")
print("此次迭代次数为:{}次,最终theta0的结果为:{},最终theta1的结果为:{}".format(count,theta0,theta1))
print("预测的最终回归函数为:y={}+{}x\n".format(theta0,theta1))
print("迭代图像绘制...")
plt.scatter(range(count),loss)
plt.show()
2. Стохастический градиентный спуск (SGD)
#引库
#引入matplotlib库,用于画图
import matplotlib.pyplot as plt
from math import pow
import numpy as np
#图片嵌入jupyter
%matplotlib inline
#为了便于取用数据,我们将数据分为x,y,在直角坐标系中(x,y)是点
x = [1,2,3,4,5,6]
y = [13,14,20,21,25,30]
print("打印初始数据图...")
plt.scatter(x,y)
plt.xlabel("X")
plt.ylabel("Y")
plt.show()
#超参数设定
alpha = 0.01#学习率/步长
theta0 = 0#θ0
theta1 = 0#θ1
epsilon = 0.001#误差
m = len(x)
count = 0
loss = []
for time in range(1000):
count += 1
diss = 0
#求偏导theta0和theta1的结果
temp0 = 0#J(θ)对θ0求导的结果
temp1 = 0#J(θ)对θ1求导的结果
for i in range(m):
temp0 += (theta0+theta1*x[i]-y[i])/m
temp1 += ((theta0+theta1*x[i]-y[i])/m)*x[i]
#更新theta0和theta1
for i in range(m):
theta0 = theta0 - alpha*((theta0+theta1*x[i]-y[i])/m)
theta1 = theta1 - alpha*((theta0+theta1*x[i]-y[i])/m)*x[i]
#求损失函数J(θ)
rand_i = np.random.randint(0,m)
diss += 0.5*(1/m)*pow((theta0+theta1*x[rand_i]-y[rand_i]),2)
loss.append(diss)
#看是否满足条件
'''
if diss<=epsilon:
break
else:
continue
'''
print("最终的结果为:")
print("此次迭代次数为:{}次,最终theta0的结果为:{},最终theta1的结果为:{}".format(count,theta0,theta1))
print("预测的最终回归函数为:y={}+{}x\n".format(theta0,theta1))
print("迭代图像绘制...")
plt.scatter(range(count),loss)
plt.show()
3. Мини-пакетный градиентный спуск (MBGD)
#引库
#引入matplotlib库,用于画图
import matplotlib.pyplot as plt
from math import pow
import numpy as np
#图片嵌入jupyter
%matplotlib inline
#为了便于取用数据,我们将数据分为x,y,在直角坐标系中(x,y)是点
x = [1,2,3,4,5,6]
y = [13,14,20,21,25,30]
print("打印初始数据图...")
plt.scatter(x,y)
plt.xlabel("X")
plt.ylabel("Y")
plt.show()
#超参数设定
alpha = 0.01#学习率/步长
theta0 = 0#θ0
theta1 = 0#θ1
epsilon = 0.001#误差
diss = 0#损失函数
m = len(x)
count = 0
loss = []
for time in range(1000):
count += 1
diss = 0
#求偏导theta0和theta1的结果
temp0 = 0#J(θ)对θ0求导的结果
temp1 = 0#J(θ)对θ1求导的结果
for i in range(m):
temp0 += (theta0+theta1*x[i]-y[i])/m
temp1 += ((theta0+theta1*x[i]-y[i])/m)*x[i]
#更新theta0和theta1
for i in range(m):
theta0 = theta0 - alpha*((theta0+theta1*x[i]-y[i])/m)
theta1 = theta1 - alpha*((theta0+theta1*x[i]-y[i])/m)*x[i]
#求损失函数J(θ)
result = []
for i in range(3):
rand_i = np.random.randint(0,m)
result.append(rand_i)
for j in result:
diss += 0.5*(1/m)*pow((theta0+theta1*x[j]-y[j]),2)
loss.append(diss)
#看是否满足条件
'''
if diss<=epsilon:
break
else:
continue
'''
print("最终的结果为:")
print("此次迭代次数为:{}次,最终theta0的结果为:{},最终theta1的结果为:{}".format(count,theta0,theta1))
print("预测的最终回归函数为:y={}+{}x\n".format(theta0,theta1))
print("迭代图像绘制...")
plt.scatter(range(count),loss)
plt.show()