# Как Александр Мадри объясняет математику обратного распространения ошибки и концепцию Software 2.0

Источник: https://www.youtube.com/watch?v=vidCX_dMCu0
Канал: MIT OpenCourseWare
Опубликовано: 11.02.2026

---

Вторая лекция специализированного курса от MIT OpenCourseWare посвящена фундаментальным принципам обучения нейронных сетей, начиная от классического градиентного спуска и заканчивая концепцией дифференцируемого программирования. Профессор MIT Александр Мадри подробно разбирает математический аппарат обратного распространения ошибки, особенности оптимизации сложных ландшафтов потерь и переход к парадигме «Программного обеспечения 2.0». Этот материал позволяет по-новому взглянуть на привычные инструменты глубокого обучения как на гибкие конструкторы для автоматизации программирования с помощью данных.

## 📉 Основы градиентного спуска и стохастическая оптимизация
[[JUMP:0:12]]

Процесс обучения нейронной сети можно охарактеризовать как последовательное изменение ее внутренних параметров с целью минимизации функции потерь. В классической схеме модель принимает входные данные $x$, пропускает их через цепочку слоев и вычисляет ошибку на основе разницы между предсказанием и истинной разметкой $y$. Профессор Александр Мадри лаконично описывает этот процесс как «шевеление» численных значений параметров в многомерном пространстве до тех пор, пока не будет достигнут оптимум.

Основным механизмом для этого выступает оптимизация функции стоимости $J(\theta)$, которая представляет собой сумму потерь по всем доступным точкам обучающего датасета. На практике для оценки функции используются методы оптимизации первого порядка, опирающиеся на линейную аппроксимацию градиента в текущей точке. Методы второго порядка, требующие вычисления матрицы Гессе (гессиана), в реальных задачах глубокого обучения практически не применяются из-за их колоксальной вычислительной сложности.

Градиентный спуск предполагает движение по ландшафту потерь в направлении наискорейшего убывания функции. На каждом шаге $k$ алгоритм обновляет параметры $\theta$, используя заданную скорость обучения (learning rate) $\eta$. Однако для современных масштабов данных вычисление полного градиента по всему датасету становится невозможным. Если на заре развития машинного обучения датасет ImageNet с 1 миллионом изображений считался огромным, то современные модели обучаются на миллиардах картинок и еще более масштабных текстовых корпусах.

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

* Размер батча, равный 1: обновление параметров происходит после каждого примера, что крайне неэффективно с вычислительной точки зрения.
* Размер батча, равный $N$ (весь датасет): классический градиентный спуск, который часто не помещается в память графического процессора (GPU) или оказывается нецелесообразно медленным.

По словам Александра Мадри, направление градиента на отдельном батче неизбежно является зашумленным. В реальных задачах, характеризующихся сильным дисбалансом классов, этот шум проявляется особенно ярко: модель может долго не видеть редкие категории, а затем их внезапное появление в батче резко смещает градиент и дестабилизирует процесс обучения. Тем не менее стохастическая природа SGD имеет важное преимущество: возникающий шум служит неявным регулярной организацией и помогает «выталкивать» оптимизатор из неоптимальных локальных минимумов.

## 🚀 Моментум и особенности рельефа функции потерь
[[JUMP:9:05]]

Для стабилизации траектории обучения и ускорения сходимости в SGD добавляется концепция моментума (импульса), заимствованная из физики. Тяжелый предмет, катящийся по склону, накапливает скорость; аналогично моментум заставляет шаг оптимизатора сохранять инерцию предыдущих обновлений. Сила этого эффекта регулируется гиперпараметром $\alpha$. Лектор упоминает Adam как один из наиболее популярных современных оптимизаторов, успешно использующих этот принцип на практике.

Мадри демонстрирует влияние моментума на примере оптимизации функции с очень острым минимумом: при нулевом импульсе движение к цели происходит стабильно, но медленно; коэффициент 0.5 позволяет достичь минимума вдвое быстрее, однако чрезмерно высокий моментум приводит к сильным осцилляциям вокруг целевой точки, замедляя оптимизацию.

Особый интерес вызывает анализ различных типов ландшафтов потерь и их пригодности для обучения с помощью фреймворков вроде PyTorch. Благодаря механизму автоматического дифференцирования (autograd), PyTorch способен вычислять градиенты практически для любых функций, включая разрывные. Тем не менее, по мнению профессора, далеко не все ландшафты легко оптимизировать:

* Ландшафты с множеством локальных минимумов: итоговый результат критически зависит от начальной инициализации весов, что заставляет инженеров тестировать множество случайных начальных чисел (random seeds).
* Плоские ландшафты: вызывают проблему затухающих градиентов (vanishing gradients), когда сигнал для обновления параметров становится настолько слабым, что шум батчей полностью его подавляет.
* Ландшафты с нулевым градиентом: полностью лишены информативного сигнала, что делает невозможным продвижение к низким потерям.
* Крутые ландшафты вблизи минимума: приводят к взрывающимся градиентам (exploding gradients), когда алгоритм делает слишком большой шаг и перелетает оптимальное решение.

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

Александр Мадри отмечает, что идеальная функция активации или потерь должна быть непрерывной, дифференцируемой и гладкой во всех точках. Популярная функция ReLU непрерывна и почти везде дифференцируема, но имеет излом. Современные тренды в сообществе, по наблюдениям лектора, смещаются в сторону использования GeLU (Gaussian Error Linear Unit), которая за счет интеграции функции распределения Гаусса удовлетворяет всем трем критериям идеальности и упрощает оптимизацию сложных сетей.

## 📊 Вычислительные графы и матричное исчисление
[[JUMP:27:09]]

Современный взгляд на глубокое обучение строится вокруг понятия вычислительного графа — структуры, состоящей из узлов (функциональных преобразований) и ребер, отражающих поток данных. В этой парадигме даже сложнейшие архитектуры представляются как направленные ациклические графы (DAG), где информация движется строго в одном направлении, циклы отсутствуют, а каждый узел является дифференцируемым. Простой многослойный перцептрон (MLP) наглядно укладывается в эту схему: вход $x$ последовательно трансформируется линейным слоем, функцией активации и вторым линейным слоем для получения выхода $y$.

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

* Если выход $y$ — скаляр, а вход $x$ — вектор размера $n \times 1$, то производная представляет собой горизонтальный вектор-строку размера $1 \times n$, содержащий частные производные по каждому элементу.
* Если и выход $y$ (размер $m \times 1$), и вход $x$ (размер $n \times 1$) являются векторами, то их производная выражается через матрицу Якоби (якобиан) размером $m \times n$.
* Если выход $y$ — скаляр, а вход $x$ — матрица размером $n \times m$ (например, изображение), то частная производная будет матрицей размером $m \times n$, то есть транспонированной относительно входа.

Связующим звеном, позволяющим вычислять производные через всю цепочку графа, является классическое правило дифференцирования сложной функции (chain rule). Производная финального результата по исходному входу рассчитывается как последовательное произведение матриц Якоби каждого промежуточного этапа.

## 🔄 Алгоритм обратного распространения ошибки (Backpropagation)
[[JUMP:37:20]]

Главный секрет эффективности обучения нейросетей заключается в алгоритме обратного распространения ошибки (backpropagation). Если вычислять производные для каждого слоя изолированно, это потребует колоссального объема избыточных вычислений. Однако благодаря цепному правилу, значительная часть промежуточных слагаемых для разных слоев совпадает. По определению Александра Мадри, backpropagation — это изящный и простой алгоритм для эффективного распределения этих общих термов по всему вычислительному графу, делающий обучение огромных моделей технически реализуемым.

В ходе обучения этот процесс разделен на две асимметричные фазы:

1.  Прямой проход (forward pass): данные пропускаются через граф от входов к выходам для расчета предсказаний и итоговой функции потерь.
2.  Обратный проход (backward pass): сигнал ошибки в виде градиентов распространяется в противоположном направлении — от функции потерь обратно к параметрам и входам.

Для каждого универсального слоя алгоритм оперирует двумя массивами производных: матрицей $L$ (градиент выходов слоя по его входам) и вектором-строкой $g$ (градиент стоимости по активациям). Обновление параметров происходит через простое перемножение этих составляющих, скорректированное на шаг обучения $\eta$. При работе с батчами градиент общей стоимости рассчитывается как среднее арифметическое градиентов по каждому отдельному объекту, поскольку операция дифференцирования линейна и легко вносится под знак суммы.

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

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

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

## 🌳 Особенности работы с произвольными графами (DAG)
[[JUMP:54:49]]

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

* Слияние путей (Merging): когда несколько потоков объединяются (например, через сложение или конкатенацию), градиент при обратном проходе корректно распределяется и отслеживается по соответствующим исходным переменным.
* Разветвление путей (Branching): когда один поток данных разделяется или дублируется на несколько направлений, при обратном проходе приходящие с этих направлений градиенты просто суммируются.

Эта простота позволяет легко реализовывать концепцию совместного использования параметров (parameter sharing). Если веса предобученной модели используются в разных частях сети, этот узел с точки зрения градиентов рассматривается как обычное разветвление, и для итогового обновления параметров градиенты из всех ветвей просто складываются.

## 🛠️ Дифференцируемое программирование и «Программное обеспечение 2.0»
[[JUMP:57:30]]

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

Лектор цитирует известных ученых, чтобы подчеркнуть масштаб этого сдвига. Так, Ян ЛеКун заявлял, что термин «глубокое обучение» устарел, и на смену ему пришло дифференцируемое программирование. Ученый Том Диттерих отмечал, что индустрия сейчас пытается нащупать базовые многоразовые конструкции в этом новом стиле программирования, такими конструкциями уже стали свертки, пулинг, блоки LSTM и слои GAN.

По словам Мадри, это перекликается со знаменитой концепцией Андрея Карпати «Программное обеспечение 2.0» (Software 2.0). В традиционном Software 1.0 человек пишет код инструкция за инструкцией, создавая жесткие правила. В Software 2.0 человек лишь описывает пространство возможных программных систем (архитектуру графа) и задает целевую функцию (метрику потерь), а оптимизатор с помощью обратного распространения ошибки сам находит нужную конфигурацию внутри этого пространства на основе данных.

При этом система не обязана быть полностью автоматической. В ней могут гармонично сосуществовать блоки, жестко запрограммированные человеком (например, фиксированные параметры нормализации изображений или стандартные синтаксические парсеры), и блоки, обучаемые на данных. Как отмечает Мадри, исторически индустрия долгое время полагалась на ручное создание признаков (feature engineering), выстраивая жесткие бутылочные горлышки для данных. Однако практика показала, что лучшие экспертные идеи уступают крупным сквозным (end-to-end) моделям, способным настраивать внутренние связи самостоятельно.

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

* Оптимизация параметров (классический подход): изменение внутренних весов сети для снижения общей стоимости на датасете.
* Оптимизация входных данных: фиксация весов модели и изменение пикселей входного изображения для максимизации определенного отклика.

Второй подход лег в основу методов визуализации признаков (feature visualization), позволяющих заглянуть внутрь «черного ящика» и увидеть, что конкретно слой нейросети считает наиболее похожим на кошку. Эта же механика управляет алгоритмами генерации психоделических изображений DeepDream и работой современных мультимодальных моделей вроде CLIP от OpenAI. Объединяя фиксированные текстовые и визуальные энкодеры CLIP с генеративно-состязательными сетями (GAN), можно оптимизировать скрытый параметр на входе генератора так, чтобы получаемое изображение идеально соответствовало текстовому описанию. Возможность свободно соединять дифференцируемые модуми между собой открывает безграничные перспективы для создания сложнейших интеллектуальных систем.