Вопрос или проблема
Говорят, что обратное распространение ошибки с градиентным спуском стремится минимизировать функцию затрат, используя формулу:
$$ W_{new} = W_{old} – learningRate \cdot \frac{\partial E}{\partial W} $$
Мой вопрос: если производная указывает, в каком направлении функция (график ошибки относительно весов) уменьшается, то почему вычитается из уже отрицательного градиента?
Почему бы не позволить текущему направлению градиента (отрицательному, предположим) быть движущей силой для обновления весов:
$$ W_{new} = W_{old} + learningRate \cdot (-gradient) $$
Рассмотрим простой пример, где функция затрат представляет собой параболу $y=x^2$, которая является выпуклой (идеальный случай) с одним глобальным минимумом при $x=0$
Здесь $y$ – это независимая переменная, а $x$ – зависимая переменная, аналогичная весам модели, которую вы пытаетесь обучить.
Вот как это будет выглядеть.
Давайте применим градиентный спуск к этой конкретной функции затрат (параболе), чтобы найти ее минимум.
Из математического анализа ясно, что $dy/dx = 2*x$. Это означает, что градиенты положительны в $1^{st}$ квадранте и отрицательны во $2^{nd}$. Это значит, что на каждый положительный небольшой шаг в x, который мы делаем, мы уходим от начала координат в $1^{st}$ квадранте и движемся к началу координат во $2^{nd}$ квадранте (шаг все еще положительный).
В правиле обновления градиентного спуска знак ‘-‘ в основном аннулирует градиент, и таким образом всегда движется к локальному минимуму.
- $1^{st}$ квадрант -> градиент положительный, но если вы используете его так, как есть, вы уходит от начала координат или минимума. Поэтому отрицательный знак полезен здесь.
- $2^{nd}$ квадрант -> градиент отрицательный, но если вы используете его так, как есть, вы уходит от начала координат или минимума (сложение двух отрицательных значений). Поэтому отрицательный знак полезен здесь.
Вот небольшой код на Python, чтобы прояснить ситуацию-
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-4, 4, 200)
y = x**2
plt.xlabel('x')
plt.ylabel('y = x^2')
plt.plot(x, y)
# скорость обучения
lr = 0.1
np.random.seed(20)
x_start = np.random.normal(0, 2, 1)
dy_dx_old = 2 * x_start
dy_dx_new = 0
tolerance = 1e-2
# останавливаемся, как только значение схожилось
while abs(dy_dx_new - dy_dx_old) > tolerance:
dy_dx_old = dy_dx_new
x_start = x_start - lr * dy_dx_old
dy_dx_new = 2 * x_start
plt.scatter(x_start, x_start**2)
plt.pause(0.5)
plt.show()
Пусть $F : \mathbb{R}^{n} \rightarrow \mathbb{R}$ будет непрерывно дифференцируемой функцией, а $d \in \mathbb{R}^{n}$. Тогда $d$ называется направлением спуска в точке $p \in \mathbb{R}^{n}$, если существует $R > 0 $, такое что $F(p+rd) < F(p)$ для всех $r \in (0,R)$.
Проще говоря: если мы переместим $p$ в направлении $d$, мы можем уменьшить значение $F$.
Теперь $d$ является направлением спуска в $p$, если $\nabla F(p)^T rd < 0 $, поскольку по определению градиента $F(p+rd) – F(p) = \nabla F(p)^Trd$ и для того, чтобы уменьшить значение функции, нам нужно, чтобы $\nabla F(p)^T rd < 0 $:
Для $f(r):= F(p+rd)$ мы имеем $f'(t) = \nabla F(p+rd)^T d$. По предположению, $f'(0) < 0$ верно.
Поскольку $f'(0) = \lim_{h \rightarrow 0} \frac{f(h)-f(0)}{h}$, мы приходим к выводу, что $d$ должно быть направлением спуска.
Таким образом, задавая $d := -\nabla F(p)$, мы имеем $\nabla F(p)^T (-\nabla F(p)) = – ||\nabla F(p)||_{2}^{2} < 0 $, если $p$ не является стационарной точкой.
В частности, мы можем выбрать $p’ = p + r’d$ с $F(p’) < F(p)$.
Это показывает, что использование отрицательного градиента имеет смысл.
Градиент указывает, в каком направлении функция увеличивается, а не уменьшается, как продемонстрировал @sai.
Рассмотрим функцию потерь
$$ L(x) = x^2 $$
В точке (1, 1) производная (наклон) положительна, что означает, что функция стремится увеличиваться в этой точке на это значение.
Если вы хотите минимизировать потери, вам необходимо контролировать независимую переменную x (представляющую параметры модели), чтобы уменьшить потери. Контроль здесь означает “увеличить” или “уменьшить” значение параметра. Так как можно понять лучшее значение? Фокус заключается в том, чтобы смотреть на градиенты, то есть производную функции потерь относительно параметров.
- Если градиент положительный, вам необходимо уменьшить значение параметра, стремясь снизить потери.
- Если градиент отрицательный, вам необходимо увеличить значение параметра, стремясь снизить потери.
$$ w_i = w_i – \alpha \frac{\delta L}{\delta w_i}$$
Фактор $\alpha$, называемый скоростью обучения, предназначен для того, чтобы брать только небольшую долю этого градиента для обновления параметра.
Вычисление градиента показывает направление, в котором функция увеличивается больше всего. Рассмотрим f: x -> x^2 , градиент в x=1 равен 2, если вы хотите минимизировать функцию, вам необходимо двигаться в направлении -2, то же самое с x=-1, так как градиент равен -2.
И поскольку градиенты обычно являются векторами, я не знаю, что будет положительным или отрицательным градиентом, если градиент что-то вроде (-1, 1).
Ответ или решение
Вопрос о том, почему мы движемся в отрицательном направлении градиента в методе градиентного спуска, является ключевым для понимания этой важной концепции в оптимизации и машинном обучении. Чтобы ответить на этот вопрос, давайте разберем основные моменты.
### Что такое градиент?
Градиент функции — это вектор, который указывает направление наибольшего возрастания функции. Когда мы говорим о функции потерь (или стоимости), градиент указывает, как изменяется значение функции потерь по отношению к изменению ее переменной, например, весов модели. Проще говоря, если градиент положителен, то увеличение веса приведет к увеличению функции потерь, и наоборот.
### Зачем двигаться в отрицательном направлении градиента?
Учитывая, что градиент указывает направление наибольшего возрастания функции, для минимизации функции потерь мы должны двигаться в противоположном направлении — в сторону, где значение функции потерь уменьшается. Таким образом, если у нас есть градиент, обозначаемый как \(\nabla E\):
– Если \(\nabla E > 0\) (функция ошибки увеличивается), это значит, что для уменьшения ошибки мы должны уменьшить значения весов.
– Если \(\nabla E < 0\) (функция ошибки уменьшается), нам нужно увеличить веса, чтобы продолжить движение к минимуму.
Формально это можно записать следующим образом:
\[
W_{\text{new}} = W_{\text{old}} - \text{learningRate} \cdot \nabla E
\]
### Пример: Функция потерь
Рассмотрим простую функцию, такую как \(L(x) = x^2\), которая имеет один минимум в точке \(x=0\). Градиент этой функции равен \(2x\). Исходя из нашей интерпретации:
1. Если \(x > 0\) (где градиент положительный \(2x\)), нам нужно уменьшить \(x\), чтобы уменьшить значение функции.
2. Если \(x < 0\) (где градиент отрицательный), это говорит о том, что увеличение \(x\) приведет к уменьшению функции потерь.
Таким образом, правило обновления весов:
\[
W_{\text{new}} = W_{\text{old}} - \text{learningRate} \cdot \nabla E
\]
позволяет нам двигаться всегда к минимуму функции.
### Объяснение правоты правила обновления
Если следовать вашему варианту обновления весов:
\[
W_{\text{new}} = W_{\text{old}} + \text{learningRate} \cdot (-\nabla E)
\]
это по сути не изменяет суть решения, так как вы все еще используете отрицательный знак для направления движения. Однако стандартное выражение с использованием отрицательного градиента более лаконично и соответствует общепринятой нотации в математической оптимизации.
### Итог
Таким образом, метод градиентного спуска использует информацию о градиенте функции потерь для определения направления, в котором необходимо обновить веса модели, чтобы минимизировать ошибку. Движение в противоположном направлении от градиента гарантирует, что мы движемся в сторону уменьшения функции потерь, что и является основной целью оптимизации в машинном обучении. Используя обоснование и математические формулировки, мы можем понять, что движение в отрицательном направлении градиента — это необходимая стратегия для достижения оптимальных значений весов модели.