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

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

(Различия между версиями)
Перейти к: навигация, поиск
 
(1 промежуточная версия не показана)
Строка 74: Строка 74:
class PolyakMomentum:
class PolyakMomentum:
def __init__(self, learning_rate: float = 0.01, gamma: float = 0.9):
def __init__(self, learning_rate: float = 0.01, gamma: float = 0.9):
-
"""
+
# Инициализация оптимизатора.
-
Инициализация оптимизатора.
+
# lr: размер шага (h).
-
lr: размер шага (h).
+
# gamma: коэффициент инерции.
-
gamma: коэффициент инерции.
+
-
"""
+
self.lr = learning_rate
self.lr = learning_rate
self.gamma = gamma
self.gamma = gamma
Строка 84: Строка 82:
def step(self, w: np.ndarray, grad: np.ndarray) -> np.ndarray:
def step(self, w: np.ndarray, grad: np.ndarray) -> np.ndarray:
-
"""
+
# Делает один шаг оптимизации.
-
Делает один шаг оптимизации.
+
# w: текущие веса.
-
w: текущие веса.
+
# grad: градиент функции потерь в точке w.
-
grad: градиент функции потерь в точке w.
+
# Возвращает обновленные веса w_new.
-
Возвращает обновленные веса w_new.
+
-
"""
+
# Ленивая инициализация вектора скорости
# Ленивая инициализация вектора скорости
if self.v is None:
if self.v is None:
Строка 108: Строка 105:
== Литература ==
== Литература ==
-
* {{книга | автор=Поляк Б. Т. | заглавие=Некоторые способы ускорения сходимости итерационных методов | место=М. | издательство=Журнал вычислительной математики и математической физики | год=1964 | том=4 | номер=5 | страницы=791–803}}
+
* {{статья | автор = Поляк Б. Т. | заглавие = Некоторые способы ускорения сходимости итерационных методов | издание = Журнал вычислительной математики и математической физики | год = 1964 | том = 4 | номер = 5 | страницы = 791–803 }}
-
* {{книга | автор=Нестеров Ю. Е. | заглавие=Метод минимизации выпуклых функций со скоростью сходимости O(1/k^2) | место=М. | издательство=Доклады АН СССР | год=1983 | том=269 | номер=3 | страницы=543–547}}
+
* {{статья | автор = Нестеров Ю. Е. | заглавие = Метод минимизации выпуклых функций со скоростью сходимости <tex>O(1/k^2)</tex> | издание = Доклады АН СССР | год = 1983 | том = 269 | номер = 3 | страницы = 543–547 }}
[[Категория:Машинное обучение]]
[[Категория:Машинное обучение]]
-
[[Категория:Математические методы]]
+
[[Категория:Машинное обучение]]
-
[[Категория:Методы оптимизации]]
+
[[Категория:Оптимизация]]

Текущая версия

Статья написана с использованием 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. — Т. 4. — № 5. — С. 791–803.
  • Нестеров Ю. Е. Метод минимизации выпуклых функций со скоростью сходимости O(1/k^2) // Доклады АН СССР. — 1983. — Т. 269. — № 3. — С. 543–547.
Личные инструменты