Автоматическое дифференцирование: скрытый двигатель алгоритмов машинного обучения
Почему не подходят символьные и численные методы?
Для оптимизации сложных функций (например, при обучении глубоких нейронных сетей с миллиардами параметров) нам необходимо быстро и сверхточно вычислять градиенты. Классическая вычислительная математика исторически предлагала два подхода, но оба оказались непригодны для задач современных масштабов. Первый подход — символьное дифференцирование (которым занимаются системы компьютерной алгебры типа Mathematica). Программа аналитически применяет жесткие правила дифференцирования к исходной формуле. К сожалению, для сложных алгоритмов с циклами ветвления этот метод приводит к феномену «экспоненциального разбухания выражений», когда итоговая формула производной занимает гигабайты памяти. Второй подход — численное дифференцирование конечными разностями. Как мы обсуждали ранее, этот метод страдает от катастрофической потери точности из-за неизбежных ошибок округления и требует N+1 вызовов функции для функции от N переменных, что при миллионах переменных замедлит расчеты до бесконечности.
Третий, поистине революционный путь — это Автоматическое Дифференцирование (АД). Это не символьная аналитика и не численное приближение. АД основывается на том простом факте, что любая, даже самая сложная компьютерная программа в конечном итоге состоит из последовательности примитивных арифметических операций (сложение, умножение) и базовых функций (синус, экспонента). АД применяет цепное правило дифференцирования (chain rule) к этим элементарным шагам прямо в процессе выполнения программы, сохраняя идеальную машинную точность и не создавая раздутых математических формул.
Прямой проход и алгебра дуальных чисел
Автоматическое дифференцирование имеет два основных режима работы. Прямой режим (Forward mode) концептуально основан на использовании так называемых дуальных чисел — специальной алгебраической структуры вида a + b*epsilon, где число epsilon обладает уникальным свойством: его квадрат строго равен нулю (по аналогии с комплексной мнимой единицей, квадрат которой равен -1). Применяя арифметику дуальных чисел к коду программы, мы одновременно за один единственный вычислительный проход получаем и итоговое значение функции, и ее точную направленную производную. Прямой режим невероятно эффективен и быстр, если мы анализируем функцию с малым числом входов и огромным числом выходов.
Обратный проход (Reverse Mode) и алгоритм Backpropagation
Однако в машинном обучении ситуация строго обратная: функция потерь (Loss function) — это всего лишь одно единственное скалярное число (один выход), которое сложнейшим образом зависит от миллионов весовых коэффициентов (входов). Для решения таких задач прямой режим потребовал бы миллионов повторных проходов. Здесь на сцену выходит обратный режим АД (Reverse mode), который в индустрии искусственного интеллекта больше известен под термином «алгоритм обратного распространения ошибки» (Backpropagation).
Обратный режим АД работает в два математических этапа. Сначала выполняется обычный прямой проход, во время которого алгоритм строит в памяти гигантский направленный вычислительный граф и бережно запоминает промежуточные значения абсолютно всех переменных (что требует колоссального объема оперативной видеопамяти VRAM). Затем алгоритм начинает двигаться по этому графу в обратном направлении, от выхода к входам, передавая сигналы чувствительности (градиенты). Благодаря гениальному применению цепного правила с конца, обратный режим позволяет вычислить точный градиент функции сразу по всем миллионам параметров всего за один обратный проход графа! Без этого потрясающего вычислительного алгоритма современный бум генеративных нейронных сетей был бы абсолютно невозможен.