# Обратное распространение ошибки

> Backprop простыми словами: цепное правило, градиенты по весам за один проход и почему без него нет обучения нейросетей и LLM.

Раздел: [Нейронные сети](https://ml-book.com/s/neural-nets/) · Страница темы: https://ml-book.com/t/backprop/ · Обновлено: 2026-09-16 · Источник: ml-book.com, учебник делается сообществом

## Интуиция

Обучение сводится к вопросу: «если чуть-чуть подкрутить вот этот вес, насколько изменится ошибка?» Ответ на него для каждого веса — это и есть градиент. Считать его «в лоб», шевеля каждый вес по отдельности и перезапуская сеть, безумно дорого: миллиард весов — миллиард прогонов. Обратное распространение ошибки (backpropagation) делает то же самое за *один* обратный проход, аккуратно применяя правило цепочки (chain rule).

Chain rule на пальцах: если L зависит от ŷ, а ŷ — от w, то чувствительности перемножаются:

`∂L/∂w = (∂L/∂ŷ) × (∂ŷ/∂w)`

Сеть — длинная цепочка простых операций, и у каждой операции есть простая локальная производная. Идём от лосса назад к входам и на каждом узле домножаем «входящую» чувствительность на локальную производную. Как эстафета: лосс передаёт назад сигнал «я хочу уменьшиться», и каждый узел переводит этот сигнал на язык своих входов.

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

Алгоритм состоит из двух проходов:

- **Прямой проход (forward pass)**: вычисляем выход сети слева направо и *сохраняем все промежуточные значения* (активации). Они понадобятся: локальные производные считаются именно в этих точках. Отсюда, кстати, и расход памяти при обучении.
- **Обратный проход (backward pass)**: начинаем с ∂L/∂L = 1 и идём справа налево. Для каждого узла градиент по входу = градиент по выходу × локальная производная. Когда узел — умножение на вес, попутно получаем градиент и по весу.

Например, для узла z = w·x локальные производные — ∂z/∂w = x и ∂z/∂x = w: градиент по весу пропорционален входу, который через него прошёл. Для ReLU локальная производная — 1 или 0: отрицательный вход просто «перекрывает кран» градиенту.

> **💡 Ключевая мысль**
>
> Backprop — это не оптимизатор. Он только вычисляет градиенты ∂L/∂w; шаг по ним делает оптимизатор (SGD, Adam). «Backprop обновляет веса» — типичная ошибка на собеседовании.

> 🎛 Интерактивная визуализация — на странице темы: https://ml-book.com/t/backprop/

## Затухающие и взрывающиеся градиенты

Обратный проход — это цепочка умножений. Если множители в среднем меньше единицы, градиент к ранним слоям затухает экспоненциально (vanishing gradients): нижние слои перестают учиться. Классическая причина — сигмоидные активации, у которых производная не превышает 0.25. Если множители больше единицы — градиент взрывается (exploding gradients), лосс скачет или уходит в NaN; лечится это обрезкой градиента (gradient clipping).

Именно затухание градиентов десятилетиями мешало учить по-настоящему глубокие сети. Ключевые лекарства: ReLU-подобные [активации](https://ml-book.com/t/activations/) (производная 1 в рабочей зоне), грамотная инициализация, нормализация слоёв и остаточные связи (residual connections) — прямые «обходные пути» y = x + F(x), по которым градиент течёт к ранним слоям с множителем 1, минуя цепочку. Без residual-связей не было бы ни ResNet на 152 слоя, ни трансформеров.

## Backprop в цикле обучения

Полный шаг обучения выглядит так: forward → лосс → backward → шаг [оптимизатора](https://ml-book.com/t/optimizers/) → обнуление градиентов. Разделение ролей здесь принципиально: backprop одинаков для любой архитектуры и любого лосса (современные фреймворки строят вычислительный граф и дифференцируют его автоматически — это называется autodiff), а стратегия шага — целиком забота оптимизатора. Полезно помнить и цену: backward стоит примерно как два forward, поэтому обучение всегда в разы дороже инференса.

> **⚠️ Подводный камень**
>
> Forward pass обязан хранить промежуточные активации до конца backward — поэтому память при обучении растёт с глубиной и длиной последовательности, и её съедают именно активации, а не только веса. Отсюда трюки вроде gradient checkpointing: не хранить часть активаций, а пересчитывать их на обратном проходе.

> **🎤 На собеседовании**
>
> - «Объясни backprop одним предложением» — рекурсивное применение chain rule от лосса к весам с переиспользованием промежуточных значений; один backward стоит примерно как два forward.
> - «Чем backprop отличается от SGD?» — backprop считает градиенты, оптимизатор делает шаг. Это два разных этапа цикла обучения.
> - «Почему глубокие сети было трудно учить и что помогло?» — vanishing gradients; помогли ReLU, нормализация, инициализация и residual connections.
> - «Зачем zero_grad() в PyTorch?» — градиенты по умолчанию накапливаются между вызовами backward, их нужно обнулять перед новым шагом.

## Связанные темы

- [Градиентный спуск](https://ml-book.com/t/gradient-descent/)
- [От нейрона к многослойному перцептрону](https://ml-book.com/t/perceptron-mlp/)
- [Функции активации](https://ml-book.com/t/activations/)
- [Оптимизаторы: SGD, Momentum, Adam](https://ml-book.com/t/optimizers/)

---

Интерактив, тест из 12 вопросов и карточки терминов — на странице темы: https://ml-book.com/t/backprop/
Весь учебник в markdown: https://ml-book.com/llms-full.txt · Оглавление для агентов: https://ml-book.com/llms.txt
