COMRAD404 / GLOSSARY

Backpropagation (обратное распространение)

Обратное распространение — способ быстро вычислять градиенты функции потерь по параметрам сети. Разбираем цепное правило, этапы расчёта и ограничения.

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

Простыми словами

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

На прямом проходе модель получает вход, считает промежуточные значения и выдаёт предсказание. Затем функция потерь превращает это предсказание в одно число, которое показывает качество ответа. На обратном проходе алгоритм отвечает на вопрос: если чуть изменить конкретный параметр, как изменится итоговая потеря?

Исторически встречается выражение обратное распространение ошибки, но технически речь не об «ошибке» в узком смысле, а о градиенте выбранной функции потерь. Это важное различие: алгоритм одинаково применим не только к классификации, но и к регрессии, языковым моделям, диффузионным моделям и многим другим задачам.

  • Что даёт backprop: градиенты по параметрам.
  • Чего не делает: не выбирает шаг обновления и не гарантирует сходимость.
  • С чем работает лучше всего: с дифференцируемыми вычислительными графами и скалярной функцией потерь.

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

Технически backprop — это применение цепного правила к вычислительному графу в обратном направлении. Если функция состоит из вложенных операций, производная всей функции равна произведению локальных производных этих операций. Вместо того чтобы выводить формулу вручную для всей сети, алгоритм разбивает задачу на маленькие шаги.

  1. Прямой проход. Модель последовательно вычисляет слои: линейные преобразования, активации, нормализации и так далее. Одновременно сохраняются промежуточные значения, которые понадобятся позже.
  2. Вычисление потерь. Предсказание сравнивается с целевым значением. Получается скаляр L.
  3. Обратный проход. Начиная с ∂L/∂L = 1, алгоритм идёт по графу назад и для каждого узла вычисляет локальный градиент. Например, если u = f(v), то нужен множитель ∂u/∂v.
  4. Агрегация вкладов. Если один и тот же узел влияет на результат по нескольким путям, все вклады суммируются. Это критично для графов с ветвлениями, остаточными связями и общими параметрами.
  5. Передача градиентов оптимизатору. Уже после backprop оптимизатор вроде SGD или Adam обновляет параметры по рассчитанным градиентам.

Ключевая идея выражается формулой ∂L/∂w = ∂L/∂z × ∂z/∂w, где w — параметр, z — промежуточный результат, а L — функция потерь. Для сети из многих слоёв эта цепочка просто становится длиннее.

Для слоя вида z = Wx + b и активации a = σ(z) обратный проход обычно выглядит так:

  • сначала считают градиент по выходу слоя, например ∂L/∂a;
  • затем переводят его в градиент по предактивации: ∂L/∂z = ∂L/∂a × σ'(z);
  • после этого получают градиенты по параметрам: ∂L/∂W и ∂L/∂b;
  • и, если нужно, градиент по входу слоя, чтобы передать его ещё дальше назад.

Современные фреймворки обычно реализуют это как reverse-mode automatic differentiation. Практическое преимущество в том, что при одной скалярной потере и миллионах параметров обратный режим намного эффективнее, чем наивное вычисление производных по каждому параметру отдельно.

Этап Что происходит Что важно на практике
Прямой проход Считаются активации и потеря Часть промежуточных значений нужно сохранить
Обратный проход Считаются градиенты по узлам и параметрам Возможны затухание, взрыв и численная нестабильность
Шаг оптимизации Параметры обновляются Это уже работа оптимизатора, а не backprop

Есть и важный инженерный нюанс: backprop обычно требует хранить активации прямого прохода до конца обратного. Поэтому обучение часто ограничено не только вычислительной мощностью, но и памятью. Отсюда появляются техники вроде gradient checkpointing, когда часть активаций не сохраняют, а пересчитывают заново.

Зачем нужно

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

  • Обучение нейросетей. Основной сценарий: классификация, регрессия, обработка текста, изображений и аудио.
  • Тонкая настройка готовых моделей. При fine-tuning градиенты считают только для части параметров или для адаптеров.
  • Анализ чувствительности. Градиенты помогают понять, какие признаки, токены или участки входа сильнее влияют на результат.
  • Оптимизация не только весов. Иногда по градиенту подбирают сами входы, промпты в непрерывном представлении или управляющие параметры симуляции.

Важно понимать, что ценность backprop не в «магии обучения», а в вычислительной эффективности. Он превращает задачу оценки миллионов частных производных в систематический проход по графу, стоимость которого сравнима с несколькими прямыми проходами.

Пример

Возьмём один нейрон для бинарной классификации. Пусть вход x = [1, 2], веса w = [0.3, -0.2], смещение b = 0.1, целевая метка y = 1.

Прямой проход:

  • z = 0.3×1 + (-0.2)×2 + 0.1 = 0
  • a = sigmoid(z) = 0.5
  • потеря бинарной кросс-энтропии: L = -log(0.5) ≈ 0.693

Теперь обратный проход. Для связки sigmoid + binary cross-entropy градиент по предактивации удобно записывается как ∂L/∂z = a - y. Здесь это 0.5 - 1 = -0.5.

Дальше градиенты по параметрам:

  • ∂L/∂w1 = (a - y) × x1 = -0.5 × 1 = -0.5
  • ∂L/∂w2 = (a - y) × x2 = -0.5 × 2 = -1.0
  • ∂L/∂b = a - y = -0.5

Если взять шаг обучения 0.1, обновление SGD будет таким:

  • w1 = 0.3 - 0.1×(-0.5) = 0.35
  • w2 = -0.2 - 0.1×(-1.0) = -0.1
  • b = 0.1 - 0.1×(-0.5) = 0.15

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

Заблуждения и ограничения

  • «Backprop и есть обучение». Нет. Он лишь считает градиенты. За обновление параметров отвечает оптимизатор, а за качество обучения — ещё и архитектура, данные, масштабирование, регуляризация и настройка гиперпараметров.
  • «Метод работает только в нейросетях». Нет. Он применим к любому дифференцируемому вычислительному графу: от логистической регрессии до физических симуляций с обучаемыми параметрами.
  • «Если функция где-то недифференцируема, всё ломается». Не всегда. Для ReLU используют субградиенты, но для жёстких дискретных операций вроде argmax, семплирования категориальных переменных или индексного выбора градиент может отсутствовать или быть бесполезным. Тогда нужны surrogate-градиенты, reparameterization trick, policy gradients или другие специальные методы.
  • «Глубина не влияет на качество градиента». На практике влияет. В очень глубоких или рекуррентных сетях градиенты могут затухать или взрываться. Поэтому применяют нормализации, остаточные связи, clipping, грамотную инициализацию и подходящие функции активации.
  • «Главное ограничение — время вычисления». Часто не только. Обратный проход потребляет память из-за сохранённых активаций. Для больших моделей это ограничение бывает жёстче, чем FLOPS.
  • «Backprop всегда лучший способ получить все производные». Он особенно выгоден, когда выход — скалярная потеря, а параметров много. Если нужна полная матрица Якоби или режим с очень многими выходами и немногими входами, выгоднее могут быть другие техники дифференцирования.

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

Частые вопросы

Чем обратное распространение отличается от градиентного спуска?

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

Это то же самое, что automatic differentiation?

В современной практике backprop обычно реализован именно как обратный режим автоматического дифференцирования. Но термин automatic differentiation шире: он включает и прямой режим, и разные способы построения вычислительного графа.

Почему на обучении нужно хранить активации, а на инференсе нет?

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

Что делать, если градиенты исчезают или взрываются?

Проверять инициализацию, нормализацию, функцию активации и масштаб learning rate. Практические инструменты — residual connections, gradient clipping, LayerNorm/BatchNorm, более короткие зависимости во времени и архитектуры, устойчивые к глубине.

Можно ли применять backprop к дискретным решениям и выборкам?

Не напрямую во всех случаях. Если в графе есть недифференцируемые или стохастические узлы, применяют специальные оценки градиента: reparameterization trick, straight-through estimators, REINFORCE и другие методы в зависимости от задачи.

Связанные понятия

  • Цепное правило. Базовый математический принцип, на котором строится обратный проход.
  • Automatic differentiation. Система автоматического вычисления производных по вычислительному графу.
  • Градиентный спуск. Семейство методов обновления параметров по рассчитанным градиентам.
  • Функция потерь. Скаляр, который задаёт, что именно модель должна минимизировать.
  • Затухающие и взрывающиеся градиенты. Типичные проблемы глубоких и рекуррентных сетей при обратном проходе.
  • BPTT. Backpropagation Through Time — вариант обратного распространения для рекуррентных вычислений по временной оси.

Читайте также

LINKS