Метод инерции Поляка

Материал из MachineLearning.

(Различия между версиями)
Перейти к: навигация, поиск
(Новая: {{well|СТАТЬЯ В РАЗРАБОТКЕ: Этот материал сейчас находится в процессе активного редактирования и дорабо...)
Строка 1: Строка 1:
-
{{well|СТАТЬЯ В РАЗРАБОТКЕ: Этот материал сейчас находится в процессе активного редактирования и доработки участником Polina Khadralinova. Просьба не оценивать статью до снятия этой пометки.}}
+
{{well|Статья написана с использованием LLM '''Gemini 3.1 Pro Preview''' и проверена участником [[Участник:Polina Khadralinova|Polina Khadralinova]]}}
Промпт приводится полностью в [[Обсуждение:Метод инерции Поляка]]
Промпт приводится полностью в [[Обсуждение:Метод инерции Поляка]]
-
== Введение ==
+
== Метод инерции Поляка (Momentum) ==
-
'''Метод инерции''' (широко известный в машинном обучении как метод ''Momentum'') — это алгоритм градиентной оптимизации, предложенный советским математиком Борисом Теодоровичем Поляком в 1964 году. Данный метод является развитием классического градиентного спуска и предназначен для ускорения сходимости за счёт накопления информации о предыдущих направлениях движения.
+
'''Метод инерции Поляка''' (также известный как ''Heavy Ball method'' или ''Momentum'') — это популярная модификация алгоритма градиентного спуска, предложенная советским математиком Борисом Теодоровичем Поляком в 1964 году. Этот метод значительно ускоряет сходимость при обучении моделей машинного обучения (включая глубокие нейронные сети), решая фундаментальные проблемы классического градиентного спуска.
-
Концепцию метода Поляка легче всего понять через интуитивную физическую аналогию, известную как метод «тяжёлого шарика». Представьте, что процесс минимизации функции — это скатывание шарика по холмистому ландшафту в самую глубокую впадину. В этой аналогии каждый элемент физического мира имеет строгий математический эквивалент в задаче машинного обучения:
+
== Физическая интуиция: Тяжёлый шарик в овраге ==
-
* '''Положение шарика на холме''' — это текущий вектор весов (параметров) модели <tex>w</tex>.
+
-
* '''Высота холма (рельеф ландшафта)''' — это значение функции потерь (эмпирического риска) <tex>\mathcal{L}</tex>. Чем ниже шарик, тем меньше ошибка модели.
+
-
* '''Сила тяжести, толкающая шарик вниз''' — это антиградиент <tex>-\nabla \mathcal{L}</tex> (направление наискорейшего спуска в текущей точке).
+
-
* '''Масса шарика''' — это инерция (накапливаемая скорость). В обычном стохастическом градиентном спуске (SGD) шарик условно «невесомый» (пушинка): он движется строго туда, куда указывает локальный уклон, и останавливается мгновенно, как только поверхность становится горизонтальной. В методе Поляка шарик тяжёлый. Набрав скорость на крутом склоне, он по инерции катится дальше, даже если локальный уклон временно исчез.
+
-
* '''Трение среды (сопротивление воздуха или вязкость жидкости)''' — это коэффициент затухания скорости <tex>\gamma</tex>, который не даёт шарику бесконечно проскакивать минимум и плавно тормозит его на дне, рассеивая кинетическую энергию.
+
-
== Математический аппарат и свойства ==
+
Чтобы понять суть метода, давайте отвлечёмся от строгой математики и представим себе физическую картину.
-
Математически метод инерции реализуется путём введения дополнительного вектора — вектора скорости <tex>v</tex>, который накапливает экспоненциальное скользящее среднее (ЭСС) градиентов прошлых итераций.
+
Обычный градиентный спуск можно сравнить с человеком, который спускается с горы в густом тумане с завязанными глазами. На каждом шаге он просто нащупывает ногой, где уклон максимален, и делает шаг туда. У него нет памяти: каждый новый шаг не зависит от предыдущего. Из-за этого на сложном ландшафте его путь будет очень дёрганым.
-
На каждом шаге <tex>t</tex> для случайного объекта обучающей выборки <tex>x_i</tex> происходит пересчёт скорости и обновление параметров:
+
Метод Поляка меняет правила игры. Представьте себе '''тяжёлый металлический шарик''', который мы отпускаем катиться на дно оврага.
-
::<tex>v = \gamma v + (1 - \gamma) \nabla \mathcal{L}(w, x_i)</tex>
+
* '''Ландшафт''' — это поверхность нашей функции потерь <tex>\mathcal{L}</tex> (или эмпирического риска <tex>Q</tex>).
 +
* '''Уклон ландшафта''' в данной точке — это градиент <tex>\nabla \mathcal{L}</tex>, который создаёт силу, тянущую шарик вниз.
 +
* '''Масса шарика''' задаёт его '''инерцию'''. Если шарик уже разогнался в определённом направлении, он продолжит двигаться по инерции, даже если локальный уклон вдруг изменится.
 +
 
 +
Благодаря этой массе шарик плавно сглаживает неровности рельефа и стремительно несётся к глобальному минимуму, накапливая скорость на затяжных спусках.
 +
 
 +
== Математическая формулировка ==
 +
 
 +
В классическом градиентном спуске вектор весов <tex>w</tex> обновляется только на основе текущего антиградиента с темпом обучения (шагом) <tex>h</tex>:
 +
::<tex>w = w - h \nabla \mathcal{L}(w)</tex>
 +
 
 +
В методе Momentum мы вводим новую переменную — вектор скорости <tex>v</tex> (вектор импульса). Теперь градиент не меняет напрямую веса <tex>w</tex>, он лишь изменяет скорость <tex>v</tex>, а уже скорость двигает веса.
 +
 
 +
Математически шаг оптимизатора записывается следующей системой уравнений (в форме экспоненциального скользящего среднего):
 +
::<tex>v = \gamma v + (1 - \gamma) \nabla \mathcal{L}(w)</tex>
::<tex>w = w - h v</tex>
::<tex>w = w - h v</tex>
-
В данных формулах используются два ключевых гиперпараметра:
+
Где:
-
* <tex>h</tex> — градиентный шаг (или темп обучения, learning rate). Определяет масштаб изменения весов на одной итерации.
+
* <tex>w</tex> — параметры (веса) модели.
-
* <tex>\gamma</tex> — коэффициент инерции (сохранения скорости). Это число в полуинтервале <tex>[0, 1)</tex>, обычно принимающее значения <tex>0.9</tex> или <tex>0.99</tex>.
+
* <tex>v</tex> — накопленная скорость (импульс).
 +
* <tex>\nabla \mathcal{L}(w)</tex> — вектор градиента функции потерь в текущей точке.
 +
* <tex>h</tex> — размер шага (learning rate).
 +
* <tex>\gamma</tex> — коэффициент инерции (momentum decay, обычно берётся равным <tex>0.9</tex>). Он играет роль силы трения: если бы <tex>\gamma = 1</tex>, наш шарик катился бы вечно, никогда не останавливаясь. При <tex>\gamma < 1</tex> шарик теряет часть энергии и в итоге оседает на дне.
-
Применение коэффициентов <tex>\gamma</tex> и <tex>(1 - \gamma)</tex> означает, что текущая скорость является взвешенной суммой всех предыдущих градиентов. Благодаря свойствам экспоненциального сглаживания, вклад старых градиентов убывает геометрически. Строго говоря, вектор <tex>v</tex> представляет собой усреднение градиента примерно по <tex>\frac{1}{1 - \gamma}</tex> последним итерациям. Например, при <tex>\gamma = 0.9</tex> метод фактически усредняет градиенты за последние <tex>10</tex> шагов, что сглаживает шум (в случае стохастического градиента) и делает направление движения более устойчивым.
+
== Преимущества метода ==
-
== Борьба с препятствиями оптимизации ==
+
=== 1. Преодоление «оврагов» ===
 +
Функции потерь часто имеют форму узких оврагов (когда по одной оси градиент огромный, а по другой — почти нулевой). Классический градиентный спуск начинает метаться от стенки к стенке (зигзаги), продвигаясь вдоль дна оврага мучительно медленно. Метод Поляка решает эту проблему: поперечные градиенты имеют разные знаки и при сложении (в векторе <tex>v</tex>) гасят друг друга, а продольные градиенты имеют одинаковый знак и накапливаются. Шарик перестаёт биться о стены и устремляется вперёд.
-
Введение инерции изящно решает несколько фундаментальных проблем классического SGD.
+
=== 2. Выход из седловых точек ===
 +
В седловых точках градиент <tex>\nabla \mathcal{L} = 0</tex>. Обычный алгоритм здесь навсегда остановится. Но наш шарик, имея накопленную скорость <tex>v</tex>, просто пролетит это плоское место по инерции и покатится дальше вниз.
-
'''Проблема «оврагов» (патологическая кривизна)'''
+
=== 3. Важное свойство: Немонотонность ===
-
Часто функция потерь имеет форму вытянутого оврага: вдоль одного направления (поперёк оврага) градиент очень велик, а вдоль другого (по дну оврага к глобальному минимуму) — очень мал. Обычный SGD в такой ситуации совершает неэффективные поперечные колебания («зигзаги») от одной стенки к другой, крайне медленно продвигаясь к цели. Метод инерции решает эту проблему: градиенты, направленные к противоположным стенкам оврага, имеют разные знаки и при усреднении в векторе <tex>v</tex> взаимно гасят друг друга. Поперечные колебания исчезают. В то же время, малые градиенты, указывающие вдоль дна оврага, имеют одинаковый знак и накапливаются, многократно ускоряя движение в правильном направлении.
+
Следует понимать критическое отличие инерционных методов от базовых. Из-за массы шарик может разогнаться так сильно, что '''проскочит''' дно локального минимума и начнёт закатываться на противоположный склон. Поэтому метод является '''немонотонным''': значение ошибки <tex>\mathcal{L}(w)</tex> в процессе обучения может временно возрастать. Однако именно это свойство позволяет выпрыгивать из мелких локальных минимумов и находить более оптимальные решения.
-
'''Проблема локальных экстремумов и седловых точек'''
+
== Сравнение с Ускоренным градиентом Нестерова (NAG) ==
-
В невыпуклых задачах оптимизации (например, при обучении глубоких нейросетей) поверхность функции потерь изобилует мелкими локальными минимумами и плоскими участками (седловыми точками). Обычный градиентный спуск застревает в них, так как локальный градиент там равен нулю. Метод Поляка, обладая «тяжёлым шариком», накапливает достаточную кинетическую энергию на предшествующих уклонах, что даёт ему возможность по инерции перекатываться через небольшие локальные возвышенности и быстро пролетать плоские плато, где локальный антиградиент не может обеспечить движение.
+
-
== Развитие метода: Ускоренный градиент Нестерова (NAG) ==
+
В 1983 году Юрий Евгеньевич Нестеров предложил развитие метода Поляка — Nesterov Accelerated Gradient (NAG). Если метод Поляка — это просто тяжёлый шарик, то метод Нестерова — это шарик с зачатками интеллекта.
-
В 1983 году выдающийся математик Юрий Евгеньевич Нестеров предложил модификацию метода Поляка, которая получила название Nesterov Accelerated Gradient (NAG). Идея Нестерова заключалась в том, чтобы сделать инерцию более «дальновидной».
+
Разница кроется в точке вычисления градиента. В методе Поляка мы:
 +
1. Считаем градиент <tex>\nabla \mathcal{L}</tex> в текущей точке <tex>w</tex>.
 +
2. Добавляем его к вектору скорости.
 +
3. Делаем шаг.
-
В классическом методе Поляка мы сначала вычисляем градиент в текущей точке <tex>w</tex>, а затем сдвигаемся по направлению вектора скорости. Однако мы уже знаем, что из-за инерции мы совершенно точно сместимся на вектор <tex>-h \gamma v</tex>. Логично вычислять градиент не в текущей точке <tex>w</tex>, а «заглядывая вперёд» — в той точке <tex>w - h \gamma v</tex>, куда нас отнесёт инерция.
+
Но ведь благодаря инерции мы уже заранее знаем, что нас в любом случае снесёт в направлении вектора <tex>-h \gamma v</tex>! Логика Нестерова: давайте сделаем '''заглядывание вперёд''' (lookahead). Мы сначала «виртуально» прыгнем туда, куда нас несёт инерция (в точку <tex>w - h \gamma v</tex>), и посчитаем градиент уже там.
-
Формулы метода Нестерова (NAG) принимают вид:
+
Формулы NAG:
-
::<tex>v = \gamma v + (1 - \gamma) \nabla \mathcal{L}(w - h \gamma v, x_i)</tex>
+
::<tex>v = \gamma v + (1 - \gamma) \nabla \mathcal{L}(w - h \gamma v)</tex>
::<tex>w = w - h v</tex>
::<tex>w = w - h v</tex>
-
За счёт вычисления градиента «по ходу движения» метод Нестерова получает возможность вовремя заметить подъём (дно минимума) и начать тормозить ещё до того, как шарик проскочит оптимум. Это существенно снижает нежелательные осцилляции в окрестности точки минимума и обеспечивает доказанное теоретическое ускорение сходимости для выпуклых задач.
+
Это позволяет алгоритму «затормозить» до того, как он начнёт закатываться на крутой холм. Если в будущей точке уклон идёт вверх, градиент сменит знак и погасит скорость <tex>v</tex> превентивно, уменьшая осцилляции.
-
== Практическая реализация на Python ==
+
== Реализация на Python ==
-
Ниже приведена лаконичная и эффективная реализация метода Поляка на языке Python с использованием библиотеки NumPy. Оптимизатор оформлен в виде класса для сохранения внутреннего состояния (вектора скорости <tex>v</tex>) между вызовами.
+
Ниже представлена лаконичная, но полностью рабочая реализация метода инерции Поляка с использованием библиотеки NumPy. Этот код можно интегрировать в кастомные циклы обучения.
<source lang="python">
<source lang="python">
import numpy as np
import numpy as np
-
class PolyakMomentumOptimizer:
+
class PolyakMomentum:
-
def __init__(self, learning_rate=0.01, gamma=0.9):
+
def __init__(self, learning_rate: float = 0.01, gamma: float = 0.9):
-
# Инициализация параметров оптимизатора
+
"""
-
self.h = learning_rate
+
Инициализация оптимизатора.
 +
lr: размер шага (h).
 +
gamma: коэффициент инерции.
 +
"""
 +
self.lr = learning_rate
self.gamma = gamma
self.gamma = gamma
-
# Вектор скорости (инерции) изначально не задан
+
self.v = None # Вектор скорости инициализируется нулями при первом шаге
-
self.v = None
+
-
def step(self, w, grad):
+
def step(self, w: np.ndarray, grad: np.ndarray) -> np.ndarray:
-
# Инициализация вектора скорости нулями при первом вызове функции
+
"""
 +
Делает один шаг оптимизации.
 +
w: текущие веса.
 +
grad: градиент функции потерь в точке w.
 +
Возвращает обновленные веса w_new.
 +
"""
 +
# Ленивая инициализация вектора скорости
if self.v is None:
if self.v is None:
self.v = np.zeros_like(w)
self.v = np.zeros_like(w)
-
# Шаг 1: обновление вектора скорости (учёт инерции и нового градиента)
+
# Формула обновления скорости v через экспоненциальное скользящее среднее
-
# Соответствует: v = gamma * v + (1 - gamma) * grad
+
self.v = self.gamma * self.v + (1 - self.gamma) * grad
self.v = self.gamma * self.v + (1 - self.gamma) * grad
-
# Шаг 2: шаг против градиента (обновление весов модели)
+
# Обновление весов w
-
# Соответствует: w = w - h * v
+
w_new = w - self.lr * self.v
-
w = w - self.h * self.v
+
-
return w
+
return w_new
</source>
</source>

Версия 20:01, 6 июля 2026

Статья написана с использованием LLM Gemini 3.1 Pro Preview и проверена участником Polina Khadralinova


Промпт приводится полностью в Обсуждение:Метод инерции Поляка

Содержание

Метод инерции Поляка (Momentum)

Метод инерции Поляка (также известный как Heavy Ball method или Momentum) — это популярная модификация алгоритма градиентного спуска, предложенная советским математиком Борисом Теодоровичем Поляком в 1964 году. Этот метод значительно ускоряет сходимость при обучении моделей машинного обучения (включая глубокие нейронные сети), решая фундаментальные проблемы классического градиентного спуска.

Физическая интуиция: Тяжёлый шарик в овраге

Чтобы понять суть метода, давайте отвлечёмся от строгой математики и представим себе физическую картину.

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

Метод Поляка меняет правила игры. Представьте себе тяжёлый металлический шарик, который мы отпускаем катиться на дно оврага.

  • Ландшафт — это поверхность нашей функции потерь \mathcal{L} (или эмпирического риска Q).
  • Уклон ландшафта в данной точке — это градиент \nabla \mathcal{L}, который создаёт силу, тянущую шарик вниз.
  • Масса шарика задаёт его инерцию. Если шарик уже разогнался в определённом направлении, он продолжит двигаться по инерции, даже если локальный уклон вдруг изменится.

Благодаря этой массе шарик плавно сглаживает неровности рельефа и стремительно несётся к глобальному минимуму, накапливая скорость на затяжных спусках.

Математическая формулировка

В классическом градиентном спуске вектор весов w обновляется только на основе текущего антиградиента с темпом обучения (шагом) h:

w = w - h \nabla \mathcal{L}(w)

В методе Momentum мы вводим новую переменную — вектор скорости v (вектор импульса). Теперь градиент не меняет напрямую веса w, он лишь изменяет скорость v, а уже скорость двигает веса.

Математически шаг оптимизатора записывается следующей системой уравнений (в форме экспоненциального скользящего среднего):

v = \gamma v + (1 - \gamma) \nabla \mathcal{L}(w)
w = w - h v

Где:

  • w — параметры (веса) модели.
  • v — накопленная скорость (импульс).
  • \nabla \mathcal{L}(w) — вектор градиента функции потерь в текущей точке.
  • h — размер шага (learning rate).
  • \gamma — коэффициент инерции (momentum decay, обычно берётся равным 0.9). Он играет роль силы трения: если бы \gamma = 1, наш шарик катился бы вечно, никогда не останавливаясь. При \gamma < 1 шарик теряет часть энергии и в итоге оседает на дне.

Преимущества метода

1. Преодоление «оврагов»

Функции потерь часто имеют форму узких оврагов (когда по одной оси градиент огромный, а по другой — почти нулевой). Классический градиентный спуск начинает метаться от стенки к стенке (зигзаги), продвигаясь вдоль дна оврага мучительно медленно. Метод Поляка решает эту проблему: поперечные градиенты имеют разные знаки и при сложении (в векторе v) гасят друг друга, а продольные градиенты имеют одинаковый знак и накапливаются. Шарик перестаёт биться о стены и устремляется вперёд.

2. Выход из седловых точек

В седловых точках градиент \nabla \mathcal{L} = 0. Обычный алгоритм здесь навсегда остановится. Но наш шарик, имея накопленную скорость v, просто пролетит это плоское место по инерции и покатится дальше вниз.

3. Важное свойство: Немонотонность

Следует понимать критическое отличие инерционных методов от базовых. Из-за массы шарик может разогнаться так сильно, что проскочит дно локального минимума и начнёт закатываться на противоположный склон. Поэтому метод является немонотонным: значение ошибки \mathcal{L}(w) в процессе обучения может временно возрастать. Однако именно это свойство позволяет выпрыгивать из мелких локальных минимумов и находить более оптимальные решения.

Сравнение с Ускоренным градиентом Нестерова (NAG)

В 1983 году Юрий Евгеньевич Нестеров предложил развитие метода Поляка — Nesterov Accelerated Gradient (NAG). Если метод Поляка — это просто тяжёлый шарик, то метод Нестерова — это шарик с зачатками интеллекта.

Разница кроется в точке вычисления градиента. В методе Поляка мы: 1. Считаем градиент \nabla \mathcal{L} в текущей точке w. 2. Добавляем его к вектору скорости. 3. Делаем шаг.

Но ведь благодаря инерции мы уже заранее знаем, что нас в любом случае снесёт в направлении вектора -h \gamma v! Логика Нестерова: давайте сделаем заглядывание вперёд (lookahead). Мы сначала «виртуально» прыгнем туда, куда нас несёт инерция (в точку w - h \gamma v), и посчитаем градиент уже там.

Формулы NAG:

v = \gamma v + (1 - \gamma) \nabla \mathcal{L}(w - h \gamma v)
w = w - h v

Это позволяет алгоритму «затормозить» до того, как он начнёт закатываться на крутой холм. Если в будущей точке уклон идёт вверх, градиент сменит знак и погасит скорость v превентивно, уменьшая осцилляции.

Реализация на Python

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

import numpy as np
 
class PolyakMomentum:
    def __init__(self, learning_rate: float = 0.01, gamma: float = 0.9):
        """
        Инициализация оптимизатора.
        lr: размер шага (h).
        gamma: коэффициент инерции.
        """
        self.lr = learning_rate
        self.gamma = gamma
        self.v = None  # Вектор скорости инициализируется нулями при первом шаге
 
    def step(self, w: np.ndarray, grad: np.ndarray) -> np.ndarray:
        """
        Делает один шаг оптимизации.
        w: текущие веса.
        grad: градиент функции потерь в точке w.
        Возвращает обновленные веса w_new.
        """
        # Ленивая инициализация вектора скорости
        if self.v is None:
            self.v = np.zeros_like(w)
 
        # Формула обновления скорости v через экспоненциальное скользящее среднее
        self.v = self.gamma * self.v + (1 - self.gamma) * grad
 
        # Обновление весов w
        w_new = w - self.lr * self.v
 
        return w_new

См. также

Литература

  • Поляк Б. Т. Некоторые способы ускорения сходимости итерационных методов. — М.: Журнал вычислительной математики и математической физики, 1964. — T. 4. — С. 791–803.
  • Нестеров Ю. Е. Метод минимизации выпуклых функций со скоростью сходимости O(1/k^2). — М.: Доклады АН СССР, 1983. — T. 269. — С. 543–547.
Личные инструменты