Не уверен, принадлежит ли этот вопрос здесь, но он тесно связан с градиентными методами в оптимизации, которая, кажется, здесь уместна. В любом случае, не стесняйтесь мигрировать, если считаете, что какое-то другое сообщество обладает большим опытом в этой теме.
Короче говоря, я ищу пошаговый пример автоматического дифференцирования в обратном режиме . Существует не так много литературы по этой теме, и существующую реализацию (такую как в TensorFlow ) трудно понять, не зная теории, стоящей за ней. Таким образом, я был бы очень благодарен, если бы кто-то мог подробно показать, что мы передаем , как мы это обрабатываем и что мы берем из вычислительного графа.
Пара вопросов, с которыми у меня больше всего проблем:
- семена - зачем они вообще нужны?
- правила обратной дифференциации - я знаю, как сделать прямую дифференциацию, но как мы пойдем назад? Например, в примере из этого раздела , откуда мы знаем, что ?
- мы работаем только с символами или передаем фактические значения ? Например, в этом же примере символы или значения являются и ?
Ответы:
Допустим, у нас есть выражение и мы хотим найти производные и . В обратном режиме AD эта задача разбивается на 2 части: прямой и обратный проходы.z=x1x2+sin(x1) dzdx1 dzdx2
Прямой проход
Во-первых, мы разлагаем наше сложное выражение на множество примитивных, то есть выражений, состоящих не более чем из одного вызова функции. Обратите внимание, что я также переименовываю входные и выходные переменные для согласованности, хотя это и не обязательно:
Преимущество этого представления в том, что правила дифференцирования для каждого отдельного выражения уже известны. Например, мы знаем, что производная от есть , и поэтому . Мы будем использовать этот факт в обратном порядке ниже.грех соз dвес4dвес1= cos( ш1)
По сути, прямой проход состоит из оценки каждого из этих выражений и сохранения результатов. Скажем, наши входные данные: и . Тогда мы имеем:Икс1= 2 Икс2= 3
Обратный проход
Это волшебство начинается, и оно начинается с правила цепочки . В своей основной форме правило цепочки утверждает, что если у вас есть переменная которая зависит от которая, в свою очередь, зависит от , то:t ( u ( v ) ) U v
или, если зависит от через несколько путей / переменных , например:T v Uя
тогда (см. доказательство здесь ):
В терминах графа выражений, если у нас есть конечный узел и входные узлы , а путь от до проходит через промежуточные узлы (т.е. где ), мы можем найти производную какZ веся Z веся весп Z= г( шп) весп= ф( шя) dZdвеся
Другими словами, чтобы вычислить производную выходной переменной любой промежуточной или входной переменной , нам нужно знать только производные ее родителей и формулу для вычисления производной примитивного выражения .Z веся весп= ф( шя)
Обратный проход начинается в конце (то есть ) и распространяется обратно на все зависимости. Здесь мы имеем (выражение для «семян»):dZdZ
Это может быть прочитано как «изменение в приводит к точно такому же изменению в », что совершенно очевидно.Z Z
Тогда мы знаем, что и так:Z= ш5
Из определения и правил частных производных мы находим, что . Таким образом:вес3= ш1вес2 dвес3dвес2= ш1
Который, как мы уже знаем из прямого прохода, является:
Наконец, вносит вклад в через и . Еще раз, из правил частных производных мы знаем, что и . Таким образом:вес1 Z вес3 вес4 dвес3dвес1знак равнош2 dвес4dвес1знак равно cos( ш1)
И снова, учитывая известные входные данные, мы можем рассчитать это:
Поскольку и являются просто псевдонимами для и , мы получаем наш ответ:вес1 вес2 Икс1 Икс2
Вот и все!
Это описание касается только скалярных входных данных, то есть чисел, но на самом деле оно также может применяться к многомерным массивам, таким как векторы и матрицы. При различении выражений с такими объектами следует учитывать две вещи:
Сила автоматического дифференцирования заключается в том, что он может работать со сложными структурами из языков программирования, такими как условия и циклы. Однако, если все, что вам нужно, это алгебраические выражения, и у вас есть достаточно хорошая структура для работы с символическими представлениями, можно построить полностью символические выражения. Фактически, в этом примере мы могли бы создать выражение и вычислить эту производную для любых входных данных, которые мы хотим.dZdвес1= ш2+ cos( ш1) = х2+ cos( х1)
источник