Быстрое дифференцирование

Материал из MachineLearning.

(Различия между версиями)
Перейти к: навигация, поиск
(Новая: А)
Строка 1: Строка 1:
-
А
+
{{well|Статья написана с использованием LLM '''ChatGPT, GPT-5.6 Thinking''' и проверена участником [[Участник:Vadim Iamaletdinov|Vadim Iamaletdinov]] 17:53, 18 июля 2026 (MSD)}}
 +
{{TOCright}}
 +
 
 +
'''Быстрое дифференцирование''' — совокупность алгоритмов вычисления производных сложной функции, заданной не одной формулой, а последовательностью элементарных операций. В современной терминологии основным воплощением этой идеи является [[Автоматическое дифференцирование|автоматическое, или алгоритмическое, дифференцирование]] (automatic differentiation, AD). Для скалярной функции многих переменных его обратный режим позволяет вычислить весь [[Градиент|градиент]] за один прямой и один обратный проход по вычислению функции. В [[Нейронная сеть|нейронных сетях]] тот же алгоритмический принцип известен как [[Метод обратного распространения ошибки|метод обратного распространения ошибки]] (backpropagation).
 +
 
 +
Слово «быстрое» относится прежде всего к асимптотике: стоимость вычисления градиента скалярной функции имеет тот же порядок, что и стоимость вычисления самой функции, и отличается от неё лишь постоянным множителем. Это делает дифференцирование моделей с миллионами и миллиардами параметров практически возможным. Быстрое дифференцирование лежит в основе [[Градиентный спуск|градиентного обучения]], дифференцируемого программирования, оптимального управления, обратных задач и многих методов научных вычислений.<ref name="Baydin2018">{{статья
 +
|автор = Baydin A. G., Pearlmutter B. A., Radul A. A., Siskind J. M.
 +
|заглавие = Automatic Differentiation in Machine Learning: a Survey
 +
|ссылка = https://www.jmlr.org/papers/v18/17-468.html
 +
|издание = Journal of Machine Learning Research
 +
|год = 2018
 +
|том = 18
 +
|номер = 153
 +
|страницы = 1—43
 +
}}</ref>
 +
 
 +
== Зачем нужно быстрое дифференцирование ==
 +
 
 +
Во многих задачах машинного обучения параметры <tex>w\in\mathbb R^n</tex> выбираются минимизацией функции потерь
 +
 
 +
:: <tex>L(w)=\frac{1}{\ell}\sum_{i=1}^{\ell}\mathcal L\bigl(a(x_i,w),y_i\bigr)+\lambda R(w),</tex>
 +
 
 +
где <tex>a(x_i,w)</tex> — прогноз модели, <tex>\mathcal L</tex> — функция потерь, <tex>R</tex> — регуляризатор. Градиентные методы требуют на каждой итерации вычислять
 +
 
 +
:: <tex>\nabla_w L(w)=\left(\frac{\partial L}{\partial w_1},\ldots,\frac{\partial L}{\partial w_n}\right).</tex>
 +
 
 +
Если находить каждую частную производную независимо, большая часть промежуточных вычислений повторяется. Например, конечные разности требуют порядка <tex>n</tex> запусков функции для одного градиента:
 +
 
 +
:: <tex>\frac{\partial L(w)}{\partial w_j}\approx
 +
\frac{L(w+h e_j)-L(w)}{h}.</tex>
 +
 
 +
Кроме высокой стоимости, этот подход содержит ошибку усечения и чувствителен к округлению: слишком большое <tex>h</tex> даёт грубую аппроксимацию, а слишком малое приводит к вычитанию близких чисел. Символьное дифференцирование даёт точную формулу, но может многократно дублировать одинаковые подвыражения и порождать громоздкие выражения.
 +
 
 +
Быстрое дифференцирование использует третий путь:
 +
 
 +
* разбивает программу на элементарные операции с известными производными;
 +
* сохраняет или восстанавливает нужные промежуточные значения;
 +
* применяет правило дифференцирования сложной функции локально;
 +
* повторно использует результаты общих подвычислений.
 +
 
 +
В результате вычисляется численное значение производной, а не развёрнутая символьная формула. Погрешность усечения отсутствует; остаются обычные ошибки машинной арифметики и ошибки, связанные с некорректно заданными локальными правилами дифференцирования.<ref name="Baydin2018"/>
 +
 
 +
== Формальная постановка ==
 +
 
 +
Пусть программа вычисляет отображение
 +
 
 +
:: <tex>F:\mathbb R^n\to\mathbb R^m,\qquad y=F(x).</tex>
 +
 
 +
Её выполнение представляется ориентированным ациклическим [[Вычислительный граф|вычислительным графом]]. Входные вершины содержат компоненты <tex>x_1,\ldots,x_n</tex>, а каждая последующая вершина вычисляет элементарную операцию
 +
 
 +
:: <tex>v_i=\varphi_i(v_{p_1},\ldots,v_{p_k}).</tex>
 +
 
 +
Функциями <tex>\varphi_i</tex> могут быть сложение, умножение, матричное произведение, экспонента, логарифм, функция активации и другие операции, для которых задано локальное правило производной. Выходные вершины содержат <tex>y_1,\ldots,y_m</tex>.
 +
 
 +
Полная производная <tex>F</tex> задаётся [[Матрица Якоби|матрицей Якоби]]
 +
 
 +
:: <tex>J_F(x)=
 +
\left[
 +
\frac{\partial y_i}{\partial x_j}
 +
\right]_{i=1,\ldots,m;\;j=1,\ldots,n}.</tex>
 +
 
 +
Автоматическое дифференцирование обычно не строит эту матрицу явно. Вместо этого оно эффективно вычисляет произведения <tex>J_F r</tex> или <tex>J_F^{\mathsf T}q</tex>. Выбор одного из этих произведений приводит соответственно к прямому и обратному режимам.
 +
 
 +
== Прямой режим ==
 +
 
 +
В прямом режиме вместе с каждым обычным значением <tex>v_i</tex>, называемым ''основным'' или ''прямым'', вычисляется касательная величина
 +
 
 +
:: <tex>\dot v_i=\frac{d v_i}{dt},</tex>
 +
 
 +
соответствующая возмущению входа <tex>x(t)=x+t r</tex>. Для вершины
 +
 
 +
:: <tex>v_i=\varphi_i(v_{p_1},\ldots,v_{p_k})</tex>
 +
 
 +
касательная распространяется по правилу
 +
 
 +
:: <tex>\dot v_i=
 +
\sum_{s=1}^{k}
 +
\frac{\partial\varphi_i}{\partial v_{p_s}}\dot v_{p_s}.</tex>
 +
 
 +
Если положить <tex>\dot x=r</tex>, на выходе получится
 +
 
 +
:: <tex>\dot y=J_F(x)r.</tex>
 +
 
 +
Таким образом, один прямой проход вычисляет произведение Якобиана на произвольный вектор, или JVP (Jacobian–vector product). При <tex>r=e_j</tex> получается <tex>j</tex>-й столбец Якобиана.
 +
 
 +
Прямой режим особенно выгоден, когда входов мало, а выходов много, например для отображения <tex>F:\mathbb R\to\mathbb R^m</tex>. Для построения полного Якобиана общего отображения требуется до <tex>n</tex> прямых проходов — по одному на каждый базисный вектор входного пространства.<ref name="Baydin2018"/>
 +
 
 +
=== Двойственные числа ===
 +
 
 +
Одна из реализаций прямого режима основана на [[Двойственные числа|двойственных числах]]
 +
 
 +
:: <tex>v+\dot v\varepsilon,\qquad \varepsilon^2=0.</tex>
 +
 
 +
Например,
 +
 
 +
:: <tex>(u+\dot u\varepsilon)(v+\dot v\varepsilon)
 +
=uv+(u\dot v+\dot u v)\varepsilon.</tex>
 +
 
 +
Коэффициент при <tex>\varepsilon</tex> автоматически воспроизводит правило производной произведения. Перегрузив элементарные операции для двойственных чисел, можно выполнять исходную программу и одновременно получать направленную производную.
 +
 
 +
== Обратный режим ==
 +
 
 +
Обратный режим ориентирован на функцию с небольшим числом выходов и большим числом входов. Именно такой случай типичен для машинного обучения: миллионы параметров отображаются в одно скалярное значение функции потерь.
 +
 
 +
Для скалярного результата <tex>L</tex> каждой промежуточной переменной сопоставляется сопряжённая величина
 +
 
 +
:: <tex>\bar v_i=\frac{\partial L}{\partial v_i}.</tex>
 +
 
 +
Алгоритм состоит из двух фаз.
 +
 
 +
# '''Прямой проход.''' Вычисляются все <tex>v_i</tex> и фиксируются зависимости между операциями.
 +
# '''Обратный проход.''' Устанавливается <tex>\bar L=1</tex>, после чего вершины обходятся в обратном топологическом порядке. Для каждого ребра <tex>v_j\to v_i</tex> выполняется накопление
 +
#:: <tex>\bar v_j\mathrel{+}=
 +
\bar v_i\frac{\partial v_i}{\partial v_j}.</tex>
 +
 
 +
Знак накопления принципиален: одна промежуточная переменная может влиять на результат несколькими путями, и её полная производная равна сумме вкладов всех этих путей.
 +
 
 +
Для векторного выхода и начального вектора <tex>q\in\mathbb R^m</tex> обратный проход вычисляет
 +
 
 +
:: <tex>J_F(x)^{\mathsf T}q,</tex>
 +
 
 +
то есть VJP (vector–Jacobian product). Если <tex>m=1</tex> и <tex>q=1</tex>, результатом является полный градиент <tex>\nabla F(x)</tex> за один обратный проход.<ref name="Baydin2018"/>
 +
 
 +
== Пример вычисления ==
 +
 
 +
Рассмотрим функцию
 +
 
 +
:: <tex>f(x_1,x_2)=\ln x_1+x_1x_2-\sin x_2.</tex>
 +
 
 +
Представим её как последовательность элементарных операций:
 +
 
 +
{| class="wikitable"
 +
! Номер
 +
! Операция
 +
! Значение при <tex>x_1=2,\;x_2=5</tex>
 +
|-
 +
| <tex>v_1</tex>
 +
| <tex>v_1=\ln x_1</tex>
 +
| <tex>\ln 2\approx 0{,}693</tex>
 +
|-
 +
| <tex>v_2</tex>
 +
| <tex>v_2=x_1x_2</tex>
 +
| <tex>10</tex>
 +
|-
 +
| <tex>v_3</tex>
 +
| <tex>v_3=\sin x_2</tex>
 +
| <tex>\sin 5\approx-0{,}959</tex>
 +
|-
 +
| <tex>v_4</tex>
 +
| <tex>v_4=v_1+v_2</tex>
 +
| <tex>10{,}693</tex>
 +
|-
 +
| <tex>f</tex>
 +
| <tex>f=v_4-v_3</tex>
 +
| <tex>11{,}652</tex>
 +
|}
 +
 
 +
Обратный проход начинается с <tex>\bar f=1</tex>. Локальные производные дают
 +
 
 +
:: <tex>\bar v_4=1,\qquad \bar v_3=-1,</tex>
 +
 
 +
:: <tex>\bar v_1=\bar v_4=1,\qquad \bar v_2=\bar v_4=1.</tex>
 +
 
 +
Далее накапливаются производные по входам:
 +
 
 +
:: <tex>\bar x_1=
 +
\bar v_1\frac{1}{x_1}+\bar v_2x_2
 +
=\frac{1}{2}+5=5{,}5,</tex>
 +
 
 +
:: <tex>\bar x_2=
 +
\bar v_2x_1+\bar v_3\cos x_2
 +
=2-\cos 5\approx1{,}716.</tex>
 +
 
 +
Итак,
 +
 
 +
:: <tex>\nabla f(2,5)\approx(5{,}5,\;1{,}716).</tex>
 +
 
 +
Обе компоненты получены совместно: промежуточные значения прямого прохода были использованы повторно, а одинаковые участки вычислительного графа не дифференцировались заново.
 +
 
 +
== Обратное распространение ошибки ==
 +
 
 +
[[Метод обратного распространения ошибки|Обратное распространение ошибки]] — частный случай обратного режима для слоистой нейронной сети. Пусть
 +
 
 +
:: <tex>h^{(0)}=x,</tex>
 +
 
 +
:: <tex>z^{(l)}=W^{(l)}h^{(l-1)}+b^{(l)},\qquad
 +
h^{(l)}=\sigma_l\bigl(z^{(l)}\bigr),\quad l=1,\ldots,L,</tex>
 +
 
 +
а скалярная функция потерь равна <tex>\mathcal L(h^{(L)},y)</tex>. Введём ошибки слоёв
 +
 
 +
:: <tex>\delta^{(l)}=\frac{\partial\mathcal L}{\partial z^{(l)}}.</tex>
 +
 
 +
Для выходного слоя <tex>\delta^{(L)}</tex> определяется производной функции потерь и активации. Для внутренних слоёв правило цепочки даёт рекурсию
 +
 
 +
:: <tex>\delta^{(l)}=
 +
\left(W^{(l+1)}\right)^{\mathsf T}\delta^{(l+1)}
 +
\odot\sigma_l'\bigl(z^{(l)}\bigr),</tex>
 +
 
 +
где <tex>\odot</tex> обозначает покомпонентное произведение. Градиенты параметров имеют вид
 +
 
 +
:: <tex>\frac{\partial\mathcal L}{\partial W^{(l)}}=
 +
\delta^{(l)}\left(h^{(l-1)}\right)^{\mathsf T},\qquad
 +
\frac{\partial\mathcal L}{\partial b^{(l)}}=\delta^{(l)}.</tex>
 +
 
 +
Эти формулы не являются отдельным принципом дифференцирования: они получаются применением обратного режима к конкретному вычислительному графу. Поэтому автоматическое дифференцирование применимо не только к последовательным нейронным сетям, но и к сетям с ветвлениями, остаточными связями, свёртками, механизмами внимания и повторным использованием параметров.
 +
 
 +
Публикация Д. Румельхарта, Дж. Хинтона и Р. Уильямса 1986 года сделала backpropagation широко известным как метод обучения многослойных сетей,<ref name="Rumelhart1986">{{статья
 +
|автор = Rumelhart D. E., Hinton G. E., Williams R. J.
 +
|заглавие = Learning representations by back-propagating errors
 +
|ссылка = https://doi.org/10.1038/323533a0
 +
|издание = Nature
 +
|год = 1986
 +
|том = 323
 +
|номер = 6088
 +
|страницы = 533—536
 +
|doi = 10.1038/323533a0
 +
}}</ref> однако обратный режим автоматического дифференцирования был сформулирован раньше и имеет более широкую область применения.
 +
 
 +
== Вычислительная сложность ==
 +
 
 +
Пусть <tex>\operatorname{ops}(F)</tex> — число элементарных арифметических операций, необходимых для вычисления <tex>F:\mathbb R^n\to\mathbb R^m</tex>. Один проход автоматического дифференцирования требует порядка
 +
 
 +
:: <tex>c\,\operatorname{ops}(F)</tex>
 +
 
 +
операций, где <tex>c</tex> — небольшая константа. Для стандартных моделей вычисления приводится теоретическая граница <tex>c<6</tex>, а в типичных реализациях арифметическая работа часто возрастает примерно в 2—3 раза.<ref name="Baydin2018"/>
 +
 
 +
Полный Якобиан можно получить:
 +
 
 +
* прямым режимом примерно за <tex>n</tex> проходов;
 +
* обратным режимом примерно за <tex>m</tex> проходов.
 +
 
 +
Отсюда практическое правило:
 +
 
 +
* при <tex>n\ll m</tex> предпочтителен прямой режим;
 +
* при <tex>m\ll n</tex> предпочтителен обратный режим;
 +
* при сопоставимых <tex>n</tex> и <tex>m</tex> выбор зависит от структуры вычислений, разреженности и доступной памяти.
 +
 
 +
Для скалярной функции <tex>F:\mathbb R^n\to\mathbb R</tex> обратный режим вычисляет весь градиент за один прямой и один обратный проход. Теорема Баура—Штрассена формализует фундаментальный факт: для функции, вычисляемой арифметической прямолинейной программой, все первые частные производные можно вычислить с арифметической сложностью, отличающейся от сложности исходной функции лишь постоянным множителем.<ref name="BaurStrassen1983">{{статья
 +
|автор = Baur W., Strassen V.
 +
|заглавие = The Complexity of Partial Derivatives
 +
|ссылка = https://doi.org/10.1016/0304-3975(83)90110-X
 +
|издание = Theoretical Computer Science
 +
|год = 1983
 +
|том = 22
 +
|номер = 3
 +
|страницы = 317—330
 +
|doi = 10.1016/0304-3975(83)90110-X
 +
}}</ref>
 +
 
 +
=== Время и память ===
 +
 
 +
Прямой режим может вычислять значение и касательную одновременно, поэтому обычно требует умеренной дополнительной памяти. Обратному режиму нужны промежуточные значения прямого прохода. В худшем случае объём памяти растёт пропорционально числу операций вычислительного графа.
 +
 
 +
Основной способ уменьшения памяти — ''контрольные точки'' (checkpointing, rematerialization). Сохраняется лишь часть промежуточных состояний, а остальные повторно вычисляются во время обратного прохода. Это создаёт управляемый компромисс: меньше памяти ценой дополнительного времени. Современные системы также освобождают ненужные буферы, объединяют операции, используют статический анализ времени жизни и задаваемые пользователем правила повторного вычисления.
 +
 
 +
== Сравнение способов вычисления производных ==
 +
 
 +
{| class="wikitable"
 +
! Метод
 +
! Точность
 +
! Стоимость градиента скалярной функции
 +
! Основные ограничения
 +
|-
 +
| Ручное дифференцирование
 +
| С точностью машинной арифметики
 +
| Может быть оптимальной
 +
| Трудоёмкость, риск ошибок, сложность сопровождения
 +
|-
 +
| Конечные разности
 +
| Приближённая
 +
| Обычно <tex>O(n)</tex> вычислений функции
 +
| Выбор шага, ошибки усечения и округления
 +
|-
 +
| Символьное дифференцирование
 +
| Формально точная
 +
| Зависит от размера полученной формулы
 +
| Разрастание выражений, трудности с обычным программным управлением
 +
|-
 +
| Прямой режим AD
 +
| С точностью машинной арифметики
 +
| <tex>n</tex> проходов для полного градиента
 +
| Невыгоден при очень большом числе входов
 +
|-
 +
| Обратный режим AD
 +
| С точностью машинной арифметики
 +
| Один обратный проход
 +
| Хранение или повторное вычисление промежуточных значений
 +
|}
 +
 
 +
Автоматическое дифференцирование не следует называть ни численным, ни символьным в обычном смысле. Оно использует аналитические правила производных элементарных операций, но распространяет численные значения производных по фактически выполненной программе.<ref name="Wengert1964">{{статья
 +
|автор = Wengert R. E.
 +
|заглавие = A Simple Automatic Derivative Evaluation Program
 +
|ссылка = https://doi.org/10.1145/355586.364791
 +
|издание = Communications of the ACM
 +
|год = 1964
 +
|том = 7
 +
|номер = 8
 +
|страницы = 463—464
 +
|doi = 10.1145/355586.364791
 +
}}</ref>
 +
 
 +
== Производные высших порядков ==
 +
 
 +
Режимы можно вкладывать друг в друга. Например:
 +
 
 +
* прямой режим поверх обратного вычисляет произведение [[Матрица Гессе|матрицы Гессе]] на вектор;
 +
* обратный режим поверх прямого может вычислять другие комбинации производных;
 +
* повторное дифференцирование позволяет получать Гессианы и производные более высоких порядков.
 +
 
 +
Для дважды дифференцируемой скалярной функции <tex>f:\mathbb R^n\to\mathbb R</tex> и вектора <tex>r</tex> произведение
 +
 
 +
:: <tex>H_f(x)r=\nabla^2 f(x)r</tex>
 +
 
 +
можно вычислить без формирования матрицы <tex>n\times n</tex>. Метод Пирлмуттера применяет направленное дифференцирование к программе обратного прохода и получает точное, с учётом машинной арифметики, произведение Гессиана на вектор со стоимостью того же порядка, что и вычисление градиента.<ref name="Pearlmutter1994">{{статья
 +
|автор = Pearlmutter B. A.
 +
|заглавие = Fast Exact Multiplication by the Hessian
 +
|ссылка = https://doi.org/10.1162/neco.1994.6.1.147
 +
|издание = Neural Computation
 +
|год = 1994
 +
|том = 6
 +
|номер = 1
 +
|страницы = 147—160
 +
|doi = 10.1162/neco.1994.6.1.147
 +
}}</ref>
 +
 
 +
Матрично-свободные произведения <tex>Hr</tex> применяются в методах Ньютона—Крылова, оценивании кривизны, анализе чувствительности и вычислении гиперградиентов. Полный Гессиан часто не строят, поскольку его хранение требует <tex>O(n^2)</tex> памяти.
 +
 
 +
== Реализация в программных системах ==
 +
 
 +
Существуют два основных подхода.
 +
 
 +
=== Перегрузка операций ===
 +
 
 +
Числовые объекты заменяются объектами, которые вместе со значением хранят касательную информацию или записывают операцию на ''ленту'' (tape). Программа исполняется обычным образом, а граф производной формируется динамически. Подход удобен для интерактивного программирования и сложного управления потоком.
 +
 
 +
=== Преобразование программы ===
 +
 
 +
Исходная программа или промежуточное представление компилятора преобразуется в новую программу, вычисляющую значения и производные. Такой подход позволяет заранее оптимизировать граф: удалять общие подвыражения, объединять операции, планировать память и компилировать вычисления для процессоров и ускорителей.
 +
 
 +
На практике используются гибридные системы. Например:
 +
 
 +
* `torch.autograd` в PyTorch записывает граф операций и реализует прежде всего обратный режим;<ref name="PyTorchAutograd">{{cite web
 +
|url = https://docs.pytorch.org/docs/stable/notes/autograd
 +
|title = Autograd mechanics
 +
|website = PyTorch documentation
 +
|accessdate = 2026-07-18
 +
}}</ref>
 +
* JAX предоставляет преобразования `grad`, `jvp`, `vjp`, а также их композиции;<ref name="JAXAutodiff">{{cite web
 +
|url = https://docs.jax.dev/en/latest/jacobian-vector-products.html
 +
|title = Forward- and reverse-mode autodiff in JAX
 +
|website = JAX documentation
 +
|accessdate = 2026-07-18
 +
}}</ref>
 +
* TensorFlow записывает операции в `tf.GradientTape` и затем проходит их в обратном порядке.<ref name="TensorFlowAutodiff">{{cite web
 +
|url = https://www.tensorflow.org/guide/autodiff
 +
|title = Introduction to gradients and automatic differentiation
 +
|website = TensorFlow Core
 +
|accessdate = 2026-07-18
 +
}}</ref>
 +
 
 +
Для новой элементарной операции необходимо определить корректное локальное правило JVP или VJP. Пользовательские правила особенно важны для численно устойчивых реализаций, неявно заданных функций, итерационных решателей и операций, у которых дифференцирование внутренней реализации не соответствует нужной математической производной.
 +
 
 +
== Ограничения и типичные ошибки ==
 +
 
 +
=== Негладкие функции ===
 +
 
 +
Для <tex>|x|</tex>, ReLU, максимума и других негладких операций классическая производная в некоторых точках не существует. Система обычно выбирает условное значение, например одну из односторонних производных или элемент [[Субдифференциал|субдифференциала]]. Это соглашение должно быть известно пользователю: автоматически полученное число не превращает негладкую функцию в дифференцируемую.
 +
 
 +
=== Ветвления и циклы ===
 +
 
 +
При динамическом графе дифференцируется фактически выполненная ветвь программы. Если малое изменение входа меняет ветвь, производная трассы может не описывать поведение всей кусочно заданной функции в точке переключения.
 +
 
 +
Циклы допустимы, если число итераций конечно, однако длинная развёртка увеличивает время и память. В рекуррентных сетях многократное умножение локальных Якобианов может приводить к [[Проблема исчезающего градиента|исчезающим]] или [[Проблема взрыва градиента|взрывающимся градиентам]]. Это свойство модели и её Якобианов, а не ошибка алгоритма дифференцирования.
 +
 
 +
=== Дискретные операции ===
 +
 
 +
Выбор индекса, сравнение, случайная дискретная выборка и изменение структуры данных обычно не имеют обычной производной. Для обучения применяют непрерывные релаксации, стохастические оценки градиента, прямые оцениватели или специальные неявные формулы. Эти методы не следует смешивать с точным автоматическим дифференцированием гладкой программы.
 +
 
 +
=== Численная устойчивость ===
 +
 
 +
AD точно дифференцирует реализованный алгоритм, но сам алгоритм может быть численно неустойчив. Например, программная формула для `softmax` без вычитания максимума способна переполниться; её автоматически полученный градиент также будет испорчен. Полезный принцип: сначала выбрать устойчивый способ вычисления функции, затем дифференцировать его.
 +
 
 +
=== Дифференцирование приближения ===
 +
 
 +
Если точная функция заменена конечным числом итераций численного метода, AD вычислит производную именно конечной программы. Она не обязана совпадать с производной предельного решения. Возможны три разных объекта:
 +
 
 +
* производная усечённого алгоритма;
 +
* производная точного решения неявной задачи;
 +
* приближение нужной производной.
 +
 
 +
Различие существенно при оптимизации через численные решатели, дифференциальные уравнения и задачи с внутренним циклом оптимизации.
 +
 
 +
=== Проверка градиента ===
 +
 
 +
Даже при использовании AD полезно выполнять тесты:
 +
 
 +
* сравнивать несколько случайных направленных производных с центральными разностями;
 +
* проверять скалярное тождество сопряжённости
 +
:: <tex>q^{\mathsf T}(J_Fr)=(J_F^{\mathsf T}q)^{\mathsf T}r;</tex>
 +
* тестировать крайние значения и точки смены ветвей;
 +
* контролировать `NaN`, бесконечности и масштабы градиентов;
 +
* отдельно проверять пользовательские правила производных.
 +
 
 +
Конечные разности здесь используются не как основной способ обучения, а как независимая диагностическая проверка.
 +
 
 +
== Применения ==
 +
 
 +
Быстрое дифференцирование применяется в следующих задачах:
 +
 
 +
* обучение нейронных сетей и других параметрических моделей;
 +
* [[Градиентный спуск]], квазиньютоновские и матрично-свободные методы второго порядка;
 +
* [[Оптимальное управление]] и вычисление сопряжённых переменных;
 +
* решение обратных коэффициентных задач;
 +
* дифференцируемые физические симуляторы;
 +
* вероятностное программирование и вариационный вывод;
 +
* метаобучение, подбор гиперпараметров и гиперградиенты;
 +
* анализ чувствительности и неопределённости;
 +
* дифференцируемая визуализация, рендеринг и обработка сигналов.
 +
 
 +
В русскоязычной литературе выражение ''быстрое автоматическое дифференцирование'' также используется для методов вычисления точных градиентов многошаговых процессов, особенно в задачах оптимального управления и обратных задачах. Экспериментальные работы показывают, что преимущество определяется не магическим сокращением числа элементарных операций, а устранением повторных вычислений, повторным использованием промежуточных величин и систематическим построением сопряжённого прохода.<ref name="Albu2023">{{статья
 +
|автор = Албу А. Ф., Горчаков А. Ю., Зубов В. И.
 +
|заглавие = БАД-методология и дифференцирование сложной функции
 +
|ссылка = https://doi.org/10.31857/S0044466923010039
 +
|издание = Журнал вычислительной математики и математической физики
 +
|год = 2023
 +
|том = 63
 +
|номер = 1
 +
|страницы = 61—73
 +
|doi = 10.31857/S0044466923010039
 +
}}</ref>
 +
 
 +
== История ==
 +
 
 +
Идеи автоматического вычисления производных развивались вместе с программированием численных алгоритмов. Р. Венгерт в 1964 году описал разложение функции на последовательность элементарных присваиваний и автоматическое распространение производных по этой последовательности.<ref name="Wengert1964"/> С. Линнайнмаа сформулировал ранний вариант обратного накопления при анализе распространения ошибок округления.<ref name="Linnainmaa1976">{{статья
 +
|автор = Linnainmaa S.
 +
|заглавие = Taylor expansion of the accumulated rounding error
 +
|ссылка = https://doi.org/10.1007/BF01931367
 +
|издание = BIT Numerical Mathematics
 +
|год = 1976
 +
|том = 16
 +
|номер = 2
 +
|страницы = 146—160
 +
|doi = 10.1007/BF01931367
 +
}}</ref> В 1980-х годах теория сложности и программные реализации установили обратный режим как общий метод, а популяризация backpropagation связала его с обучением многослойных нейронных сетей.<ref name="BaurStrassen1983"/><ref name="Rumelhart1986"/>
 +
 
 +
Современное понятие автоматического дифференцирования шире backpropagation. Backpropagation обычно обозначает применение обратного режима к функции потерь нейронной сети, тогда как AD охватывает прямой и обратный режимы, векторные функции, производные высших порядков и произвольные дифференцируемые программы.
 +
 
 +
== См. также ==
 +
 
 +
* [[Автоматическое дифференцирование]]
 +
* [[Метод обратного распространения ошибки]]
 +
* [[Вычислительный граф]]
 +
* [[Градиент]]
 +
* [[Градиентный спуск]]
 +
* [[Матрица Якоби]]
 +
* [[Матрица Гессе]]
 +
* [[Нейронная сеть]]
 +
* [[Функция потерь]]
 +
* [[Оптимальное управление]]
 +
 
 +
== Примечания ==
 +
 
 +
<references/>
 +
 
 +
== Литература ==
 +
 
 +
* {{книга
 +
|автор = Griewank A., Walther A.
 +
|заглавие = Evaluating Derivatives: Principles and Techniques of Algorithmic Differentiation
 +
|издание = 2-е изд.
 +
|место = Philadelphia
 +
|издательство = SIAM
 +
|год = 2008
 +
|страниц = 438
 +
|isbn = 978-0-89871-659-7
 +
|ссылка = https://doi.org/10.1137/1.9780898717761
 +
}}
 +
* {{статья
 +
|автор = Baydin A. G., Pearlmutter B. A., Radul A. A., Siskind J. M.
 +
|заглавие = Automatic Differentiation in Machine Learning: a Survey
 +
|ссылка = https://www.jmlr.org/papers/v18/17-468.html
 +
|издание = Journal of Machine Learning Research
 +
|год = 2018
 +
|том = 18
 +
|номер = 153
 +
|страницы = 1—43
 +
}}
 +
* {{статья
 +
|автор = Baur W., Strassen V.
 +
|заглавие = The Complexity of Partial Derivatives
 +
|ссылка = https://doi.org/10.1016/0304-3975(83)90110-X
 +
|издание = Theoretical Computer Science
 +
|год = 1983
 +
|том = 22
 +
|номер = 3
 +
|страницы = 317—330
 +
}}
 +
* {{статья
 +
|автор = Pearlmutter B. A.
 +
|заглавие = Fast Exact Multiplication by the Hessian
 +
|ссылка = https://doi.org/10.1162/neco.1994.6.1.147
 +
|издание = Neural Computation
 +
|год = 1994
 +
|том = 6
 +
|номер = 1
 +
|страницы = 147—160
 +
}}
 +
* {{книга
 +
|автор = Евтушенко Ю. Г.
 +
|заглавие = Оптимизация и быстрое автоматическое дифференцирование
 +
|место = М.
 +
|издательство = ВЦ им. А. А. Дородницына РАН
 +
|год = 2013
 +
|страниц = 144
 +
}}
 +
 
 +
[[Категория:Машинное обучение]]
 +
[[Категория:Нейронные сети]]
 +
[[Категория:Методы оптимизации]]
 +
[[Категория:Энциклопедия анализа данных]]

Версия 13:53, 18 июля 2026

Статья написана с использованием LLM ChatGPT, GPT-5.6 Thinking и проверена участником Vadim Iamaletdinov 17:53, 18 июля 2026 (MSD)


Содержание

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

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

Зачем нужно быстрое дифференцирование

Во многих задачах машинного обучения параметры w\in\mathbb R^n выбираются минимизацией функции потерь

L(w)=\frac{1}{\ell}\sum_{i=1}^{\ell}\mathcal L\bigl(a(x_i,w),y_i\bigr)+\lambda R(w),

где a(x_i,w) — прогноз модели, \mathcal L — функция потерь, R — регуляризатор. Градиентные методы требуют на каждой итерации вычислять

\nabla_w L(w)=\left(\frac{\partial L}{\partial w_1},\ldots,\frac{\partial L}{\partial w_n}\right).

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

\frac{\partial L(w)}{\partial w_j}\approx
\frac{L(w+h e_j)-L(w)}{h}.

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

Быстрое дифференцирование использует третий путь:

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

В результате вычисляется численное значение производной, а не развёрнутая символьная формула. Погрешность усечения отсутствует; остаются обычные ошибки машинной арифметики и ошибки, связанные с некорректно заданными локальными правилами дифференцирования.[1]

Формальная постановка

Пусть программа вычисляет отображение

F:\mathbb R^n\to\mathbb R^m,\qquad y=F(x).

Её выполнение представляется ориентированным ациклическим вычислительным графом. Входные вершины содержат компоненты x_1,\ldots,x_n, а каждая последующая вершина вычисляет элементарную операцию

v_i=\varphi_i(v_{p_1},\ldots,v_{p_k}).

Функциями \varphi_i могут быть сложение, умножение, матричное произведение, экспонента, логарифм, функция активации и другие операции, для которых задано локальное правило производной. Выходные вершины содержат y_1,\ldots,y_m.

Полная производная F задаётся матрицей Якоби

J_F(x)=
\left[
\frac{\partial y_i}{\partial x_j}
\right]_{i=1,\ldots,m;\;j=1,\ldots,n}.

Автоматическое дифференцирование обычно не строит эту матрицу явно. Вместо этого оно эффективно вычисляет произведения J_F r или J_F^{\mathsf T}q. Выбор одного из этих произведений приводит соответственно к прямому и обратному режимам.

Прямой режим

В прямом режиме вместе с каждым обычным значением v_i, называемым основным или прямым, вычисляется касательная величина

\dot v_i=\frac{d v_i}{dt},

соответствующая возмущению входа x(t)=x+t r. Для вершины

v_i=\varphi_i(v_{p_1},\ldots,v_{p_k})

касательная распространяется по правилу

\dot v_i=
\sum_{s=1}^{k}
\frac{\partial\varphi_i}{\partial v_{p_s}}\dot v_{p_s}.

Если положить \dot x=r, на выходе получится

\dot y=J_F(x)r.

Таким образом, один прямой проход вычисляет произведение Якобиана на произвольный вектор, или JVP (Jacobian–vector product). При r=e_j получается j-й столбец Якобиана.

Прямой режим особенно выгоден, когда входов мало, а выходов много, например для отображения F:\mathbb R\to\mathbb R^m. Для построения полного Якобиана общего отображения требуется до n прямых проходов — по одному на каждый базисный вектор входного пространства.[1]

Двойственные числа

Одна из реализаций прямого режима основана на двойственных числах

v+\dot v\varepsilon,\qquad \varepsilon^2=0.

Например,

(u+\dot u\varepsilon)(v+\dot v\varepsilon)
=uv+(u\dot v+\dot u v)\varepsilon.

Коэффициент при \varepsilon автоматически воспроизводит правило производной произведения. Перегрузив элементарные операции для двойственных чисел, можно выполнять исходную программу и одновременно получать направленную производную.

Обратный режим

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

Для скалярного результата L каждой промежуточной переменной сопоставляется сопряжённая величина

\bar v_i=\frac{\partial L}{\partial v_i}.

Алгоритм состоит из двух фаз.

  1. Прямой проход. Вычисляются все v_i и фиксируются зависимости между операциями.
  2. Обратный проход. Устанавливается \bar L=1, после чего вершины обходятся в обратном топологическом порядке. Для каждого ребра v_j\to v_i выполняется накопление
    \bar v_j\mathrel{+}=
\bar v_i\frac{\partial v_i}{\partial v_j}.

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

    Для векторного выхода и начального вектора q\in\mathbb R^m обратный проход вычисляет

    J_F(x)^{\mathsf T}q,

    то есть VJP (vector–Jacobian product). Если m=1 и q=1, результатом является полный градиент \nabla F(x) за один обратный проход.[1]

    Пример вычисления

    Рассмотрим функцию

    f(x_1,x_2)=\ln x_1+x_1x_2-\sin x_2.

    Представим её как последовательность элементарных операций:

    Номер Операция Значение при x_1=2,\;x_2=5
    v_1 v_1=\ln x_1 \ln 2\approx 0{,}693
    v_2 v_2=x_1x_2 10
    v_3 v_3=\sin x_2 \sin 5\approx-0{,}959
    v_4 v_4=v_1+v_2 10{,}693
    f f=v_4-v_3 11{,}652

    Обратный проход начинается с \bar f=1. Локальные производные дают

    \bar v_4=1,\qquad \bar v_3=-1,
    \bar v_1=\bar v_4=1,\qquad \bar v_2=\bar v_4=1.

    Далее накапливаются производные по входам:

    \bar x_1=
\bar v_1\frac{1}{x_1}+\bar v_2x_2
=\frac{1}{2}+5=5{,}5,

    \bar x_2=
\bar v_2x_1+\bar v_3\cos x_2
=2-\cos 5\approx1{,}716.

    Итак,

    \nabla f(2,5)\approx(5{,}5,\;1{,}716).

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

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

    Обратное распространение ошибки — частный случай обратного режима для слоистой нейронной сети. Пусть

    h^{(0)}=x,
    z^{(l)}=W^{(l)}h^{(l-1)}+b^{(l)},\qquad
h^{(l)}=\sigma_l\bigl(z^{(l)}\bigr),\quad l=1,\ldots,L,

    а скалярная функция потерь равна \mathcal L(h^{(L)},y). Введём ошибки слоёв

    \delta^{(l)}=\frac{\partial\mathcal L}{\partial z^{(l)}}.

    Для выходного слоя \delta^{(L)} определяется производной функции потерь и активации. Для внутренних слоёв правило цепочки даёт рекурсию

    \delta^{(l)}=
\left(W^{(l+1)}\right)^{\mathsf T}\delta^{(l+1)}
\odot\sigma_l'\bigl(z^{(l)}\bigr),

    где \odot обозначает покомпонентное произведение. Градиенты параметров имеют вид

    \frac{\partial\mathcal L}{\partial W^{(l)}}=
\delta^{(l)}\left(h^{(l-1)}\right)^{\mathsf T},\qquad
\frac{\partial\mathcal L}{\partial b^{(l)}}=\delta^{(l)}.

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

    Публикация Д. Румельхарта, Дж. Хинтона и Р. Уильямса 1986 года сделала backpropagation широко известным как метод обучения многослойных сетей,[1] однако обратный режим автоматического дифференцирования был сформулирован раньше и имеет более широкую область применения.

    Вычислительная сложность

    Пусть \operatorname{ops}(F) — число элементарных арифметических операций, необходимых для вычисления F:\mathbb R^n\to\mathbb R^m. Один проход автоматического дифференцирования требует порядка

    c\,\operatorname{ops}(F)

    операций, где c — небольшая константа. Для стандартных моделей вычисления приводится теоретическая граница c<6, а в типичных реализациях арифметическая работа часто возрастает примерно в 2—3 раза.[1]

    Полный Якобиан можно получить:

    • прямым режимом примерно за n проходов;
    • обратным режимом примерно за m проходов.

    Отсюда практическое правило:

    • при n\ll m предпочтителен прямой режим;
    • при m\ll n предпочтителен обратный режим;
    • при сопоставимых n и m выбор зависит от структуры вычислений, разреженности и доступной памяти.

    Для скалярной функции F:\mathbb R^n\to\mathbb R обратный режим вычисляет весь градиент за один прямой и один обратный проход. Теорема Баура—Штрассена формализует фундаментальный факт: для функции, вычисляемой арифметической прямолинейной программой, все первые частные производные можно вычислить с арифметической сложностью, отличающейся от сложности исходной функции лишь постоянным множителем.[1]

    Время и память

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

    Основной способ уменьшения памяти — контрольные точки (checkpointing, rematerialization). Сохраняется лишь часть промежуточных состояний, а остальные повторно вычисляются во время обратного прохода. Это создаёт управляемый компромисс: меньше памяти ценой дополнительного времени. Современные системы также освобождают ненужные буферы, объединяют операции, используют статический анализ времени жизни и задаваемые пользователем правила повторного вычисления.

    Сравнение способов вычисления производных

    Метод Точность Стоимость градиента скалярной функции Основные ограничения
    Ручное дифференцирование С точностью машинной арифметики Может быть оптимальной Трудоёмкость, риск ошибок, сложность сопровождения
    Конечные разности Приближённая Обычно O(n) вычислений функции Выбор шага, ошибки усечения и округления
    Символьное дифференцирование Формально точная Зависит от размера полученной формулы Разрастание выражений, трудности с обычным программным управлением
    Прямой режим AD С точностью машинной арифметики n проходов для полного градиента Невыгоден при очень большом числе входов
    Обратный режим AD С точностью машинной арифметики Один обратный проход Хранение или повторное вычисление промежуточных значений

    Автоматическое дифференцирование не следует называть ни численным, ни символьным в обычном смысле. Оно использует аналитические правила производных элементарных операций, но распространяет численные значения производных по фактически выполненной программе.[1]

    Производные высших порядков

    Режимы можно вкладывать друг в друга. Например:

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

    Для дважды дифференцируемой скалярной функции f:\mathbb R^n\to\mathbb R и вектора r произведение

    H_f(x)r=\nabla^2 f(x)r

    можно вычислить без формирования матрицы n\times n. Метод Пирлмуттера применяет направленное дифференцирование к программе обратного прохода и получает точное, с учётом машинной арифметики, произведение Гессиана на вектор со стоимостью того же порядка, что и вычисление градиента.[1]

    Матрично-свободные произведения Hr применяются в методах Ньютона—Крылова, оценивании кривизны, анализе чувствительности и вычислении гиперградиентов. Полный Гессиан часто не строят, поскольку его хранение требует O(n^2) памяти.

    Реализация в программных системах

    Существуют два основных подхода.

    Перегрузка операций

    Числовые объекты заменяются объектами, которые вместе со значением хранят касательную информацию или записывают операцию на ленту (tape). Программа исполняется обычным образом, а граф производной формируется динамически. Подход удобен для интерактивного программирования и сложного управления потоком.

    Преобразование программы

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

    На практике используются гибридные системы. Например:

    • `torch.autograd` в PyTorch записывает граф операций и реализует прежде всего обратный режим;[1]
    • JAX предоставляет преобразования `grad`, `jvp`, `vjp`, а также их композиции;[1]
    • TensorFlow записывает операции в `tf.GradientTape` и затем проходит их в обратном порядке.[1]

    Для новой элементарной операции необходимо определить корректное локальное правило JVP или VJP. Пользовательские правила особенно важны для численно устойчивых реализаций, неявно заданных функций, итерационных решателей и операций, у которых дифференцирование внутренней реализации не соответствует нужной математической производной.

    Ограничения и типичные ошибки

    Негладкие функции

    Для |x|, ReLU, максимума и других негладких операций классическая производная в некоторых точках не существует. Система обычно выбирает условное значение, например одну из односторонних производных или элемент субдифференциала. Это соглашение должно быть известно пользователю: автоматически полученное число не превращает негладкую функцию в дифференцируемую.

    Ветвления и циклы

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

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

    Дискретные операции

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

    Численная устойчивость

    AD точно дифференцирует реализованный алгоритм, но сам алгоритм может быть численно неустойчив. Например, программная формула для `softmax` без вычитания максимума способна переполниться; её автоматически полученный градиент также будет испорчен. Полезный принцип: сначала выбрать устойчивый способ вычисления функции, затем дифференцировать его.

    Дифференцирование приближения

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

    • производная усечённого алгоритма;
    • производная точного решения неявной задачи;
    • приближение нужной производной.

    Различие существенно при оптимизации через численные решатели, дифференциальные уравнения и задачи с внутренним циклом оптимизации.

    Проверка градиента

    Даже при использовании AD полезно выполнять тесты:

    • сравнивать несколько случайных направленных производных с центральными разностями;
    • проверять скалярное тождество сопряжённости
    q^{\mathsf T}(J_Fr)=(J_F^{\mathsf T}q)^{\mathsf T}r;
    • тестировать крайние значения и точки смены ветвей;
    • контролировать `NaN`, бесконечности и масштабы градиентов;
    • отдельно проверять пользовательские правила производных.

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

    Применения

    Быстрое дифференцирование применяется в следующих задачах:

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

    В русскоязычной литературе выражение быстрое автоматическое дифференцирование также используется для методов вычисления точных градиентов многошаговых процессов, особенно в задачах оптимального управления и обратных задачах. Экспериментальные работы показывают, что преимущество определяется не магическим сокращением числа элементарных операций, а устранением повторных вычислений, повторным использованием промежуточных величин и систематическим построением сопряжённого прохода.[1]

    История

    Идеи автоматического вычисления производных развивались вместе с программированием численных алгоритмов. Р. Венгерт в 1964 году описал разложение функции на последовательность элементарных присваиваний и автоматическое распространение производных по этой последовательности.[1] С. Линнайнмаа сформулировал ранний вариант обратного накопления при анализе распространения ошибок округления.[1] В 1980-х годах теория сложности и программные реализации установили обратный режим как общий метод, а популяризация backpropagation связала его с обучением многослойных нейронных сетей.[1][1]

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

    См. также

    Примечания


    Литература

    • Griewank A., Walther A. Evaluating Derivatives: Principles and Techniques of Algorithmic Differentiation. — 2-е изд.. — Philadelphia: SIAM, 2008. — 438 с. — ISBN 978-0-89871-659-7
    • Baydin A. G., Pearlmutter B. A., Radul A. A., Siskind J. M. Automatic Differentiation in Machine Learning: a Survey // Journal of Machine Learning Research. — 2018. — Т. 18. — № 153. — С. 1—43.
    • Baur W., Strassen V. The Complexity of Partial Derivatives // Theoretical Computer Science. — 1983. — Т. 22. — № 3. — С. 317—330.
    • Pearlmutter B. A. Fast Exact Multiplication by the Hessian // Neural Computation. — 1994. — Т. 6. — № 1. — С. 147—160.
    • Евтушенко Ю. Г. Оптимизация и быстрое автоматическое дифференцирование. — М.: ВЦ им. А. А. Дородницына РАН, 2013. — 144 с.
Личные инструменты