Концепции ИИ на Python

Оптимизаторы нейросетей: SGD, Momentum и Adam на Python

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

Суть простыми словами

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

Сравните обычный градиентный спуск, momentum и Adam, минимизируя одну и ту же функцию шаг за шагом.

Главные идеи

  • Momentum хранит скорость, поэтому прокатывается через плоские участки и мелкие неровности.
  • Adam хранит скользящие средние градиента и квадрата градиента.
  • Коррекция смещения (деление на 1 − βᵗ) исправляет эти средние на первых шагах.
  • Хорошая инициализация весов и мини-батчи тоже делают обучение быстрее и стабильнее.

Когда это использовать?

  • Понять, что происходит внутри нейронных сетей и библиотек ИИ.
  • Разобраться в идее до того, как реализовать её в соответствующих задачах.
  • Подготовиться к курсам по машинному обучению, собеседованиям и проектам.

Посмотрите в действии

Нажмите Запуск, и три оптимизатора наперегонки спустятся в одну и ту же неровную долину. Увеличьте скорость обучения, чтобы увидеть, как momentum проскакивает минимум.

Пример кода

Запустить код →
main.py
import math

# Minimise f(x) = (x - 3)² with three optimizers. The gradient is 2(x - 3).
grad = lambda x: 2 * (x - 3)

def sgd(steps, lr=0.1):
    x = 0.0
    for _ in range(steps):
        x -= lr * grad(x)
    return x

def momentum(steps, lr=0.1, beta=0.9):
    x, v = 0.0, 0.0
    for _ in range(steps):
        v = beta * v + grad(x)        # remember the direction we were going
        x -= lr * v
    return x

def adam(steps, lr=0.3, b1=0.9, b2=0.999, eps=1e-8):
    x, m, v = 0.0, 0.0, 0.0
    for t in range(1, steps + 1):
        g = grad(x)
        m = b1 * m + (1 - b1) * g     # running mean of gradients
        v = b2 * v + (1 - b2) * g * g # running mean of squared gradients
        m_hat, v_hat = m / (1 - b1 ** t), v / (1 - b2 ** t)
        x -= lr * m_hat / (math.sqrt(v_hat) + eps)
    return x

for steps in (5, 20, 50):
    print(f"{steps:>2} steps  sgd={sgd(steps):.3f}  momentum={momentum(steps):.3f}  adam={adam(steps):.3f}")

Ожидаемый результат

5 steps  sgd=2.017  momentum=4.741  adam=1.476
20 steps  sgd=2.965  momentum=4.048  adam=3.813
50 steps  sgd=3.000  momentum=3.091  adam=3.014

Как это работает

Все три минимизируют (x − 3)², самая низкая точка которой x = 3. SGD движется равномерно, momentum разгоняется и проскакивает цель, прежде чем успокоиться, а Adam масштабирует каждый шаг скользящими средними градиента и его квадрата. Через 50 шагов все три близки к 3.

Измените значения и запустите программу в онлайн-компиляторе Python CodeUtility без локальной установки Python.

Практические задания

Изменяйте входные данные и проверяйте граничные случаи перед работой с большими наборами.

  1. Измените входные данные или веса и предскажите результат до запуска.
  2. Выводите промежуточные значения, чтобы проследить каждый шаг вычислений.
  3. Решите задачи по ссылкам ниже, чтобы самостоятельно реализовать идею.
Запустить в Python IDE →

Попрактикуйтесь на задаче

Примените материал этого урока к реальной задаче. Каждая задача запускается в браузере, с мгновенными тестами и разбором от ИИ.

Все задачи