Математика глубокого обучения: как устроен алгоритм обратного распространения ошибки

Stanford Online 31,9 тыс. 1 ч 13 мин 8 мин 04.03.2025
Главное

В третьей лекции знаменитого курса Стэнфордского университета CS224N (весна 2024 года) подробно разбираются математические основы глубокого обучения — алгоритм обратного распространения ошибки и устройство нейронных сетей. Преподаватель объясняет, почему современные ИИ-модели невозможно построить без нелинейных функций активации и как сложные вычисления оптимизируются с помощью матричного исчисления. Материал призван приоткрыть завесу над «черным ящиком» нейросетей, чтобы будущие специалисты могли эффективно отлаживать сложные архитектуры.

🎓 Организационные моменты и старт курса 0:05

Лектор начинает занятие с напоминания о дедлайнах: завершилась работа над первым домашним заданием, которое традиционно служит «плавным въездом» в курс. Студентам настоятельно не рекомендуется тратить на него штрафные дни («late days»).

В этот же день публикуется второе задание (Assignment 2), преследующее три цели:

Для помощи студентам анонсирован специализированный воркшоп по PyTorch, запланированный на пятницу в 15:30 в аудитории Gates B01 с трансляцией в записи. Также слушателям рекомендуется изучить краткие туториалы по матричному исчислению и линейной алгебре из предложенного списка литературы. Профессор отмечает, что четверг будет полностью посвящен лингвистике, которая для многих оказывается сложнее математики.

🧠 Архитектура нейросетей: от логистической регрессии к матрицам 3:16

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

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

Для ускорения вычислений хаотично связанные нейроны упаковываются в регулярную структуру слоев. Выходные сигналы одного слоя умножаются на веса, к ним добавляется смещение (bias), после чего результат пропускается через нелинейную функцию. В векторном виде это превращается в элегантную матричную операцию: промежуточное значение рассчитывается по формуле $z = Wx + b$, а значения следующего слоя определяются как $h = f(z)$. В качестве сквозного примера лектор использует задачу определения, является ли центральное слово в текстовом окне именованной сущностью (локацией).

⚡ Зачем нужны нелинейности: эволюция функций активации 7:00

Зачем вообще нужны нелинейные функции активации $f$? Профессор углубляется в историю вопроса, напоминая, что в первых реализациях нейронов 1940-х годов использовалась жесткая пороговая функция: если активация превышала значение $\theta$, на выходе была $1$, иначе — $0$. Однако у такого порога график абсолютно плоский, а значит, градиент равен нулю, что делает обучение невозможным.

Вся современная индустрия построена на градиентном обучении (gradient-based learning). Лектор приводит яркую аналогию: процесс оптимизации похож на весеннее катание на лыжах в горах — вы ищете, где склон круче, и быстро спускаетесь по нему вниз.

Позже на смену порогам пришел логистический сигмоид, отображающий числа в вероятности. Его недостатком лектор считает исключительно неотрицательные выходы, что смещает вычисления в сторону больших чисел. Из-за этого долгое время доминировал гиперболический тангенс ($\tanh$). Математически $\tanh$ — это просто масштабированный и смещенный сигмоид:

$$\tanh(x) = 2 \cdot \sigma(2x) - 1$$

Однако вычисление экспонент в $\tanh$ замедляет компьютеры. Это привело к созданию «жесткого тангенса» (Hard Tanh), а затем — к тотальному доминированию ReLU (Rectified Linear Unit), которая равна $0$ в отрицательной области и $y = x$ в положительной.

С точки зрения градиентного обучения ReLU кажется лектору несколько специфичной архитектурой, ведь в отрицательной зоне нейрон полностью «умирает». Но в положительной зоне градиент всегда равен $1$, что обеспечивает идеальный обратный поток сигналов. В итоге ReLU на годы стала стандартом индустрии.

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

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

📐 Матричное исчисление: «Мантра» многомерного анализа 16:54

Основой градиентного спуска является вычисление направления наискорейшего спуска с помощью вектора частных производных функции потерь. Профессор шутит, что для студентов Стэнфорда, прошедших курс Math 51 (линейная алгебра и многомерный анализ), вся эта математика хорошо знакома, и они могут ближайшие 35 минут полистать Instagram. В самом конце учебника Math 51, в приложении G на странице 697, как раз описывается многомерное цепное правило для нейросетей, хотя до этой страницы, по мнению лектора, мало кто доходит.

Главная мантра многомерного исчисления звучит так:

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

Производная функции с $n$ входами дает вектор градиента того же размера. Если же у функции $n$ входов и $m$ выходов (как у слоя нейросети), то матрица всех частных производных называется якобианом (Jacobian), названным в честь немецкого математика Карла Якоби. Обучение многослойной сети сводится к перемножению таких матриц Якоби по цепному правилу (chain rule).

Лектор разбирает базовые якобианы:

🔗 Пошаговый расчет градиентов и соглашение о форме 31:36

Чтобы рассчитать изменение итоговой оценки сети $s$ по отношению к параметрам, применяется многомерное цепное правило. Для вектора смещения $b$ формула раскрывается как произведение трех производных:

$$\frac{\partial s}{\partial b} = \frac{\partial s}{\partial h} \frac{\partial h}{\partial z} \frac{\partial z}{\partial b}$$

Подставляя базовые производные, мы получаем выражение, включающее транспонированный вектор весов верхнего уровня $u^T$ и диагональную матрицу активаций. В вычислениях нейросетей это преобразуется через так называемое произведение Адамара (Hadamard product) — поэлементное умножение векторов, обозначаемое специальным символом. Результатом становится вектор той же размерности.

При расчете производной по матрице весов $\frac{\partial s}{\partial W}$ выясняется, что первые два компонента цепного правила полностью совпадают с расчетом для смещения $b$. Чтобы избежать дублирования вычислений, этот общий вектор называют «ошибкой» или «восходящим градиентом» (upstream gradient) и обозначают как $\delta$.

Расчет $\delta$ производится единожды, после чего для смещения $b$ ответ равен просто $\delta$, а для весов $W$ берется внешнее произведение (outer product) вектора $\delta^T$ на транспонированный вектор входа $x^T$. Это дает матрицу нужного размера, описывающую вклад каждой отдельной связи между нейронами.

Здесь возникает конфликт между строгой математической формой Якоби (где производные вытягиваются в длинные векторы-строки) и инженерным удобством. В компьютерных науках принято использовать соглашение о форме (shape convention): градиент параметра должен иметь точно такую же размерность и форму, как и сам параметр, чтобы их можно было легко вычитать друг из друга при обновлении весов по формуле градиентного спуска. В домашних заданиях от студентов требуют строгого соблюдения именно инженерного соглашения о форме.

📊 Графы вычислений и алгоритм обратного распространения 44:52

Профессор резюмирует, что великий алгоритм обратного распространения (backpropagation) состоит всего из двух столпов: цепного правила исчисления и сохранения промежуточных результатов в памяти во избежание повторной работы. Любую нейросеть можно представить в виде направленного ациклического графа (DAG), где исходные данные и параметры — это истоки, узлы — математические операции, а ребра передают результаты вычислений.

Проход слева направо называется прямым (forward pass) и последовательно вычисляет значение функции потерь. Обратный проход (backward pass) идет справа налево, начиная с базового градиента $\frac{\partial s}{\partial s} = 1$, и поочередно рассчитывает градиенты нижележащих узлов путем умножения входящего градиента на локальный градиент текущего узла.

Лектор демонстрирует это на игрушечном примере функции $f(x,y,z) = (x + y) \cdot \max(y, z)$ при стартовых значениях $x=1, y=2, z=0$. В ходе прямого шага граф последовательно вычисляет промежуточные значения: узел максимума выдает $2$, узел сложения — $3$, а финальный узел умножения возвращает результат $6$. При обратном ходе проявляются базовые правила распределения градиентов:

Важной особенностью графа является обработка разветвлений. Переменная $y$ участвует сразу в двух операциях, поэтому при обратном проходе градиенты, пришедшие от обеих ветвей (значения 2 и 3), суммируются, давая итоговое значение частной производной $\frac{\partial f}{\partial y} = 5$.

🛠️ Эволюция фреймворков и практическая отладка 59:46

В общем случае алгоритм строит топологическую сортировку графа вычислений, выстраивая узлы так, чтобы каждый зависел только от предыдущих. Вычисление градиентов на обратном проходе имеет ту же вычислительную сложность по Big $\mathcal{O}$, что и прямой расчет. Если обратный проход работает медленнее, значит, архитектура спроектирована неэффективно и вычисления дублируются.

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

Современные библиотеки вроде PyTorch пошли по компромиссному пути: они берут на себя управление графом и связывание узлов, но требуют от программиста вручную прописывать локальные производные внутри кастомных слоев через методы forward и backward. Для корректной работы метода backward применяется стандартный трюк: на этапе прямого прохода функция сохраняет («кэширует») значения своих входов в локальных переменных класса, чтобы использовать их при обратном расчете градиентов.

Для проверки корректности математических формул в кастомных слоях лектор рекомендует использовать метод численной проверки градиента (gradient checking). Для этого берется малое приращение $h$ (обычно около $10^{-4}$ для нейросетей) и рассчитывается центральная (двусторонняя) разность:

$$\frac{f(x+h) - f(x-h)}{2h}$$

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

В заключение профессор отмечает, что современные фреймворки настолько упростили сборку моделей из готовых блоков, словно это конструктор LEGO, что сегодня даже школьники могут собирать проекты для научных ярмарок. Однако без глубокого понимания математических процессов под капотом невозможно разобраться, почему сеть не обучается, и как бороться с фундаментальными проблемами затухания или взрыва градиентов (vanishing and exploding gradients) в более сложных архитектурах.

💬 Цитаты

«Многомерное исчисление полностью аналогично одномерному, просто вместо чисел используются матрицы»

Лектор курса 20:17

«Если вы делаете больше работы на обратном проходе, чем на прямом, значит, вы повторно вычисляете результаты»

👥 Спикер
📚 Упомянутые книги
🔗 Упомянутые сайты и проекты
📖 Термины
Якобиан
Матрица, состоящая из всех частных производных функции первого порядка.
Произведение Адамара
Математическая операция поэлементного умножения двух матриц или векторов одинаковой размерности.
ReLU
Популярная функция активации, возвращающая ноль для отрицательных аргументов и само число для положительных.
📊 Цифры
🗓 Хронология
  1. 1940-е Появление первых искусственных нейронов с жесткой пороговой функцией активации.
  2. Ранний этап ИИ Разработка фреймворка Theano в Университете Монреаля с автоматическим символьным дифференцированием.
  3. 2024 Проведение весеннего курса CS224N в Стэнфордском университете с использованием фреймворка PyTorch.
⚖️ Другая сторона
Искусственный интеллект CS224N PyTorch обратное распространение функция активации градиентный спуск