SGD и его вариации

Стохастический градиентный спуск (Stochastic Gradient Descent, SGD) является фундаментальным методом оптимизации в машинном обучении. В TensorFlow.js он реализован через объект tf.train.SGD, который позволяет обновлять веса модели на основе градиентов функции потерь. Основная идея SGD — обновление параметров модели после каждой мини-партии (batch) данных с целью минимизации функции потерь.

Основные принципы работы SGD

SGD обновляет параметры модели по формуле:

[ _{t+1} = t - L(_t)]

где:

  • (_t) — вектор параметров модели на шаге (t),
  • () — скорость обучения (learning rate),
  • (_L(_t)) — градиент функции потерь по параметрам.

В отличие от обычного градиентного спуска, который вычисляет градиенты на всем наборе данных, SGD использует отдельные примеры или небольшие мини-батчи. Это позволяет:

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

Создание оптимизатора в TensorFlow.js

const learningRate = 0.01;
const optimizer = tf.train.sgd(learningRate);

Метод optimizer.minimize() используется для автоматического вычисления градиентов и обновления параметров:

optimizer.minimize(() => {
  const predictions = model.predict(input);
  return tf.losses.meanSquaredError(labels, predictions);
});

Аргумент функции minimize — это функция потерь, возвращающая tf.Scalar. TensorFlow.js автоматически вычисляет градиенты по всем переменным, используемым внутри этой функции.

Моментум (Momentum)

Стандартный SGD часто может сталкиваться с медленным сходимостью, особенно при узких канавках функции потерь. Добавление моментума позволяет ускорить обучение за счет накопления предыдущих обновлений. Формула обновления с моментумом:

[ v_{t+1} = v_t + (1 - ) _L(_t)] [ _{t+1} = t - v{t+1}]

где (v_t) — скорость изменения параметров, () — коэффициент моментума (обычно 0.9). В TensorFlow.js реализуется через tf.train.momentum:

const learningRate = 0.01;
const momentum = 0.9;
const optimizer = tf.train.momentum(learningRate, momentum);

Адаптивные методы оптимизации

SGD можно комбинировать с адаптивными методами для улучшения сходимости.

Adagrad — подстраивает скорость обучения для каждого параметра на основе прошлых градиентов:

const optimizer = tf.train.adagrad(0.01);

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

RMSProp — улучшение Adagrad, удерживает экспоненциальное скользящее среднее градиентов:

const optimizer = tf.train.rmsprop(0.001, 0.9);

RMSProp особенно эффективен для рекуррентных нейросетей, стабилизируя обучение.

Adam — комбинирует моментум и RMSProp, один из наиболее популярных оптимизаторов:

const optimizer = tf.train.adam(0.001, 0.9, 0.999);

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

Настройка скорости обучения

Скорость обучения является ключевым параметром SGD. В TensorFlow.js можно реализовать динамическое изменение learning rate:

const initialLearningRate = 0.1;
const decayRate = 0.01;
let step = 0;

function getLearningRate() {
  return initialLearningRate / (1 + decayRate * step);
}

Такой подход позволяет уменьшать шаг по мере приближения к минимуму, предотвращая «прыжки» через оптимальное решение.

Мини-батчи и производительность

SGD чувствителен к размеру батча. В TensorFlow.js обучение на мини-батчах выглядит следующим образом:

const batchSize = 32;
for (let i = 0; i < numBatches; i++) {
  const batchX = dataX.slice(i * batchSize, (i + 1) * batchSize);
  const batchY = dataY.slice(i * batchSize, (i + 1) * batchSize);

  optimizer.minimize(() => {
    const predictions = model.predict(batchX);
    return tf.losses.meanSquaredError(batchY, predictions);
  });
}

Малые батчи повышают стохастичность, большие — стабильность градиентов. Практически выбирают размер, исходя из объема памяти и скорости сходимости.

Инициализация параметров и регуляризация

Эффективная работа SGD напрямую зависит от начальной инициализации весов модели. В TensorFlow.js доступны методы:

const weights = tf.variable(tf.randomNormal([inputSize, outputSize]));

Регуляризация, например L2, помогает предотвращать переобучение:

const l2Lambda = 0.01;
const loss = tf.losses.meanSquaredError(labels, predictions)
            .add(weights.square().sum().mul(l2Lambda));

SGD будет учитывать регуляризационный член при обновлении весов, улучшая обобщающую способность модели.

Практические рекомендации

  • Использовать небольшие learning rate при больших моделях.
  • Применять моментум или Adam для ускорения сходимости.
  • Настраивать batch size под объем данных и возможности устройства.
  • Использовать регуляризацию и нормализацию данных для стабильного обучения.
  • Периодически сохранять модель и проверять метрики на валидационном наборе, чтобы избегать переобучения.

SGD и его вариации обеспечивают гибкость и эффективность в обучении нейронных сетей на JavaScript. TensorFlow.js предоставляет готовые реализации оптимизаторов с богатым набором параметров, позволяя управлять скоростью обучения, моментумом и адаптивными корректировками градиентов, что делает возможным обучение как простых моделей, так и сложных глубоких сетей прямо в браузере или на Node.js.