Градиентный спуск: скатываемся в минимум

Урок напоминает, как градиентный спуск шаг за шагом ведёт параметры к минимуму потери.

Градиент — это вектор частных производных функции потерь по каждому весу; он указывает направление наискорейшего роста потери.

Идея спуска

Если градиент показывает, куда потеря растёт быстрее всего, то противоположное направление ведёт вниз — к минимуму. Поэтому правило простое: сдвигаем вес против градиента. Для одного веса: w = w - lr * dL/dw, где dL/dw — производная потери по этому весу, а lr — скорость обучения (размер шага).

Аналогия: вы в тумане на склоне холма и хотите спуститься. Вы щупаете ногой, в какую сторону спуск круче всего, и делаете шаг в обратную (вниз) сторону. Повторяете, пока не окажетесь в низине.

Спуск своими руками

Минимизируем простую функцию f(w) = (w - 3)^2. Её производная — 2*(w - 3). Стартуем с w = 0 и наблюдаем, как параметр приближается к 3.

def f(w):
    return (w - 3) ** 2

def grad(w):
    return 2 * (w - 3)

w = 0.0
lr = 0.1
for step in range(1, 21):
    g = grad(w)
    w = w - lr * g            # шаг против градиента
    if step % 4 == 0 or step == 1:
        print(f"шаг {step:>2}: w = {w:.4f}, f(w) = {f(w):.4f}")
print("Параметр сошёлся почти к w = 3 — минимуму функции.")

Вывод:

шаг  1: w = 0.6000, f(w) = 5.7600
шаг  4: w = 1.7712, f(w) = 1.5099
шаг  8: w = 2.4967, f(w) = 0.2533
шаг 12: w = 2.7938, f(w) = 0.0425
шаг 16: w = 2.9156, f(w) = 0.0071
шаг 20: w = 2.9654, f(w) = 0.0012
Параметр сошёлся почти к w = 3 — минимуму функции.

Шаги крупные вдали от минимума (там градиент большой) и мельчают у дна (градиент стремится к нулю). Это естественное «торможение» — приятное свойство градиентного спуска.

Скорость обучения решает всё

  • Слишком маленький lr — спуск идёт верно, но мучительно долго.
  • Слишком большой lr — шаги перелетают минимум, потеря скачет или вовсе расходится в бесконечность.
  • В самый раз — быстрая и стабильная сходимость. На практике lr подбирают экспериментально.

От одного веса к миллионам

В реальной сети потеря зависит от всех весов сразу. Градиент — это вектор: своя производная по каждому весу. Правило не меняется — каждый вес сдвигается против своей производной. Вопрос лишь в том, как эффективно вычислить производную по каждому из миллионов весов. Ответ — обратное распространение, тема следующего раздела.

Итог

  • Градиент указывает направление роста потери; спускаемся против него.
  • Правило шага: w = w - lr * dL/dw.
  • Шаги естественно мельчают у минимума; lr критически важен.
Проверьте себя
1. В какую сторону градиентный спуск сдвигает вес?
AПо направлению градиента
BПротив градиента — туда, где потеря убывает
CВ случайную сторону
DВсегда в сторону нуля
2. Что происходит с размером шагов по мере приближения к минимуму?
AОни растут
BОни уменьшаются, потому что градиент стремится к нулю
CОстаются постоянными
DШаги прекращаются мгновенно
3. Чем грозит слишком большая скорость обучения?
AОбучение станет идеально точным
BШаги перелетают минимум, потеря скачет или расходится
CГрадиент станет нулевым
DСеть потеряет слои
Поддержать проект