В математике и компьютерной алгебре, автоматическое дифференцирование (AD), также называемое алгоритмическое дифференцирование, вычислительное дифференцирование, автоматическое дифференцирование или просто autodiff, представляет собой набор методов для численной оценки производная функции, заданной компьютерной программой. AD использует тот факт, что каждая компьютерная программа, независимо от ее сложности, выполняет последовательность элементарных арифметических операций (сложение, вычитание, умножение, деление и т. Д.) И элементарных функций (exp, log, sin, cos и т. Д.). Путем многократного применения правила цепочки к этим операциям производные произвольного порядка могут быть вычислены автоматически с точностью до рабочей точности и с использованием не более небольшого постоянного множителя для большего числа арифметических операций, чем в исходной программе.
Рисунок 1: Как автоматическое дифференцирование связано с символическим дифференцированиемАвтоматическое дифференцирование отличается от символического дифференцирования и числового дифференцирования (метод конечных разностей). Символьное дифференцирование может привести к неэффективному коду и столкнуться с трудностями преобразования компьютерной программы в одно выражение, в то время как числовое дифференцирование может привести к ошибкам округления в процессе дискретизации и отмене. Оба классических метода имеют проблемы с вычислением высших производных, когда возрастает сложность и ошибки. Наконец, оба классических метода медленно вычисляют частные производные функции по многим входным данным, что необходимо для алгоритмов градиента оптимизации. Автоматическое дифференцирование решает все эти проблемы.
В основе AD лежит разложение дифференциалов, обеспечиваемое правилом цепочки. Для простой композиции
цепное правило дает
Обычно представлены два различных режима AD: прямое накопление (или прямой режим ) и обратное накопление (или реверсивный режим ). Прямое накопление указывает, что каждый проходит по правилу цепочки изнутри наружу (то есть сначала вычисляется , а затем и, наконец, ), а обратное накопление имеет обход снаружи внутрь (сначала вычисляем , а затем и, наконец, ). Более лаконично,
Как правило, как прямое, так и обратное накопление являются конкретными проявлениями применения оператора композиции программы, фиксирующего соответствующее одно из двух сопоставлений .
При прямом накоплении AD сначала фиксируется независимая переменная с помощью относительно которого выполняется дифференцирование, и вычисляет производную ive каждого под- выражения рекурсивно. При ручном вычислении это включает в себя многократную замену производной внутренних функций в цепном правиле:
Это можно обобщить на несколько переменных как матричное произведение якобианов.
По сравнению с обратным накоплением, прямое накопление является естественным и легко реализуемым, поскольку поток производной информации совпадает с t Порядок оценки. Каждая переменная w дополняется ее производной ẇ (сохраняется как числовое значение, а не как символическое выражение),
как обозначено точкой. Затем производные вычисляются синхронно с этапами оценки и комбинируются с другими производными с помощью цепного правила.
В качестве примера рассмотрим функцию:
Для ясности, отдельные подвыражения были помечены переменными w i.
. Выбор независимой переменной, для которой выполняется дифференцирование, влияет на начальные значения ẇ 1 и ẇ 2. Учитывая интерес к производной этой функции по x 1, начальные значения должны быть установлены на:
После установки начальных значений значения распространяются с использованием цепного правила, как показано. На рис. 2 показано графическое изображение этого процесса в виде вычислительного графа.
Чтобы вычислить градиент этой функции примера, которая требует производных от f по отношению не только для x 1, но также для x 2, дополнительное сканирование выполняется по вычислительному графу с использованием начальных значений .
вычислительная сложность единицы развертка прямого накопления пропорциональна сложности исходного кода.
Прямое накопление более эффективно, чем обратное накопление для функций f: ℝ → ℝ с m ≫ n, поскольку необходимы только n разверток по сравнению с m развертками для обратного накопления.
При обратном накоплении AD зависимая переменная, подлежащая дифференцированию, фиксируется, а производная вычисляется по каждому под- выражение рекурсивно. При вычислении на бумаге производная внешних функций многократно подставляется в цепное правило:
При обратном накоплении интересующая нас величина - сопряженная, обозначенная чертой (w̄); это производная выбранной зависимой переменной относительно подвыражения w:
Обратное накопление проходит по правилу цепочки извне внутрь или, в случае вычислительного графа на рисунке 3, сверху вниз. В примере функции используется скалярное значение, поэтому для вычисления производной используется только одно начальное значение, а для вычисления (двухкомпонентного) градиента требуется только одно сканирование вычислительного графа. Это только половина работы по сравнению с прямым накоплением, но обратное накопление требует хранения промежуточных переменных w i, а также инструкций, которые их создали в структуре данных, известной как список Венгерта (или «лента»), который может потреблять значительный объем памяти, если вычислительный граф большой. Это можно смягчить до некоторой степени, сохраняя только подмножество промежуточных переменных, а затем восстанавливая необходимые рабочие переменные путем повторения оценок, метод, известный как рематериализация. Контрольная точка также используется для сохранения промежуточных состояний.
Операции по вычислению производной с использованием обратного накопления показаны в таблице ниже (обратите внимание на обратный порядок):
Графом потока данных вычисления можно управлять, чтобы вычислить градиент исходного вычисления. Это делается путем добавления сопряженного узла для каждого основного узла, соединенного смежными ребрами, которые параллельны основным ребрам, но текут в противоположном направлении. Узлы сопряженного графа представляют собой умножение на производные функций, вычисленных узлами в прямом. Например, сложение в основных причинах разветвления в смежных; разветвление в первичных причинах сложение в смежных; унарная функция y = f (x) в прямых причинах x̄ = ȳ f ′ (x) в сопряженном; и т.д.
Обратное накопление более эффективно, чем прямое накопление для функций f: ℝ → ℝ с m ≪ n, поскольку необходимы только m разверток, по сравнению с n развертками для прямого накопления.
Обратный режим AD был впервые опубликован в 1976 году Сеппо Линнаинмаа.
Обратное распространение ошибок в многослойных перцептронах, метод, используемый в машинном обучении, является особым случаем. обратного режима AD.
Прямое и обратное накопление - это всего лишь два (крайних) способа обхода правила цепочки. Задача вычисления полного якобиана f: ℝ → ℝ с минимальным числом арифметических операций известна как задача оптимального якобиана накопления (OJA), которая является NP-полной. Центральным в этом доказательстве является идея о том, что между локальными частичными элементами, которые маркируют ребра графа, могут существовать алгебраические зависимости. В частности, две или более метки края могут быть признаны равными. Сложность проблемы остается открытой, если предположить, что все метки ребер уникальны и алгебраически независимы.
Автоматическое дифференцирование в прямом режиме выполняется путем увеличения алгебры действительных чисел и получения новой арифметической . К каждому числу добавляется дополнительный компонент, чтобы представить производную функции по этому числу, и все арифметические операторы расширяются для расширенной алгебры. Расширенная алгебра - это алгебра двойных чисел.
. Замените каждое число числом , где - действительное число, но - абстрактное число со свойством (бесконечно малое ; см. Гладкий анализ бесконечно малых ). Используя только это, обычная арифметика дает
и аналогично для вычитания и деления.
Теперь многочлены могут быть вычислены в этой расширенной арифметике. Если , тогда
где обозначает производную от относительно своего первого аргумента, и , называемый начальным значением, можно выбрать произвольно.
Новая арифметика состоит из упорядоченных пар, элементов, записанных , с обычной арифметикой для первого компонента и арифметикой дифференцирования первого порядка для второго компонента, как описано выше. Распространение приведенных выше результатов о полиномах на аналитические функции дает список основных арифметических и некоторых стандартных функций для новой арифметики:
и в целом для примитивной функции ,
где и являются производными от по его первому и второму аргументам соответственно.
Когда к смешанным аргументам применяется базовая двоичная арифметическая операция - пара и действительное number - действительное число сначала поднимается до . Производная функции в точке теперь находится путем вычисления с использованием вышеуказанная арифметика, которая дает как результат.
Функции с несколькими переменными могут обрабатываться с той же эффективностью и механизмами, что и функции с одной переменной, путем принятия оператора производной по направлению. То есть, если достаточно вычислить , производную по направлению из в в направлении , это может быть вычислено как используя ту же арифметику, что и выше. Если все элементы требуются, то требуются оценки функции . Обратите внимание, что во многих оптимизационных приложениях действительно достаточно производной по направлению.
Вышеупомянутая арифметика может быть обобщена для вычисления производных второго и более высокого порядка функций многих переменных. Однако арифметические правила быстро усложняются: сложность квадратична в высшей производной степени. Вместо этого может использоваться усеченная алгебра полиномов Тейлора. Результирующая арифметика, определенная для обобщенных двойных чисел, позволяет выполнять эффективные вычисления с использованием функций, как если бы они были типом данных. Как только полином Тейлора функции известен, производные легко извлекаются.
AD прямого режима реализуется с помощью программы, в которой действительные числа заменяются двойными числами, константы повышаются до двойных чисел с нулевым эпсилон-коэффициентом и числовыми примитивами подняты для работы с двойными числами. Эта нестандартная интерпретация обычно реализуется с использованием одной из двух стратегий: преобразование исходного кода или перегрузка оператора.
Исходный код для функции заменяется автоматически сгенерированным исходным кодом, который включает инструкции для вычисления производных чередующиеся с оригинальными инструкциями.
Преобразование исходного кода может быть реализовано для всех языков программирования, а также компилятору проще выполнять оптимизацию времени компиляции. Однако реализация самого инструмента AD сложнее.
Перегрузка оператора - это возможность для исходного кода, написанного на поддерживающем его языке. Объекты для действительных чисел и элементарных математических операций должны быть перегружены для обслуживания расширенной арифметики, изображенной выше. Это не требует изменения формы или последовательности операций в исходном исходном коде для дифференциации функции, но часто требует изменений в базовых типах данных для чисел и векторов для поддержки перегрузки, а также часто включает в себя вставку специальных операций маркировки.
Перегрузка оператора для прямого накопления легко реализуется, а также возможна для обратного накопления. Однако современные компиляторы отстают в оптимизации кода по сравнению с прямым накоплением.
Перегрузка операторов как для прямого, так и для обратного накопления может хорошо подходить для приложений, где объекты являются векторами действительных чисел, а не скалярами. Это потому, что лента содержит векторные операции; это может облегчить вычислительно эффективные реализации, в которых каждая векторная операция выполняет множество скалярных операций. Методы векторного сопряженного алгоритмического дифференцирования (векторного AAD) могут использоваться, например, для дифференцирования значений, вычисленных с помощью моделирования Монте-Карло.
Примерами реализаций автоматического дифференцирования с перегрузкой операторов в C ++ являются библиотеки Adept и Stan.
.