Джулия: Пользовательское обратное распространение на Zygote

искусственный интеллект

Zygote — это пакет в Julia, который реализует автоматическую дифференциацию и автоматическую деривацию.@adjointМакросы являются важной частью интерфейса Zygote. использовать@adjointОбратное распространение функций можно настроить.

Pullbacks

понять@adjointВо-первых, разберитесь с функциями нижнего уровняpullback.gradientфактическиpullbackсинтаксический сахар для .

julia> y, back = Zygote.pullback(sin, 0.5)
(0.479425538604203, Zygote.var"#41#42"{Zygote.ZBack{ChainRules.var"#sin_pullback#1430"{Float64}}}(Zygote.ZBack{ChainRules.var"#sin_pullback#1430"{Float64}}(ChainRules.var"#sin_pullback#1430"{Float64}(0.8775825618903728))))

julia> y
0.479425538604203

даватьpullbackВведите два параметраsinи0.5Представьте функцию, которую нужно вывести, и значение, которое нужно вывести, соответственно, и будут получены два выхода: результат данной функцииsin(0.5)иpullback, который является кодом вышеbackПеременная.backпарная функцияsinДля вычисления градиента ~~ принимает вывод и создает новую переменную. ~~ С математической точки зрения это реализация векторно-якобианского произведения. вy=f(x)y=f(x)и градиентlx\frac{\partial{l}}{\partial{x}}написано какxˉ\bar{x}, откатBy\mathcal{B}_yРассчитайте следующим образом:

xˉ=lx=lyyx=By(yˉ)\bar{x}=\frac{\partial l}{\partial x}=\frac{\partial l}{\partial y} \frac{\partial y}{\partial x}=\mathcal{B}_{y}(\bar{y})

В частности, на примере приведенного выше кода функцияy=sin(x)y=\sin(x). yx=cos(x)\frac{\partial y}{\partial x}=\cos (x), так что откат естьyˉcos(x)\bar{y}\cos(x)yˉ=ly\bar{y}=\frac{\partial l}{\partial y}. другими словами,pullback(sin, x)иdsin(x) = (sin(x), ȳ -> (ȳ * cos(x),))эквивалентность.

gradientсредняя функцияl=f(x)l=f(x)и предположимlˉ=ll=1\bar{l}=\frac{\partial l}{\partial l}=1, и подайте его в откат. существуетsinВ примере

julia> dsin(x) = (sin, ȳ -> (ȳ * cos(x),))
dsin (generic function with 1 method)

julia> function gradsin(x)
           _, back = dsin(x)
           back(1)
       end
gradsin (generic function with 1 method)

julia> gradsin(0.5)
(0.8775825618903728,)

julia> cos(0.5)
0.8775825618903728
                
julia> back(1)
(0.8775825618903728,)

Личное понимание, зачем добавлять элемент перед нимly\frac{\partial l}{\partial y}, который должен реализовать цепное правило. Например, предположим, что окончательный убыток равенll, функцияy(x)y(x), чтобы получить функцию потерьllпарный параметрxxДифференциацияlx\frac{\partial l}{\partial x}, согласно цепному правилу, функция потерь есть функцияyyПроизводная от умноженной на функцию по параметруxxдифференциалlyyx\frac{\partial l}{\partial y} \frac{\partial y}{\partial x}. функцияyyизpullbackпарная функция функции потерьyyДифференциация (сyˉ\bar{y}означает), умноженное на пару функцийxxдифференциал.

Для приведенного выше примераpullbackПервый результат, возвращаемый функцией: Предположим, что функцияy=sin(x)y=\sin(x)функция потерьllчас,x=0.5x=0.5результат, когдаcos(0.5)\cos(0.5), и возвращаетсяbackоколоly\frac{\partial l}{\partial y}функцию, ее можно рассматривать какB(ly)=lycos(0.5)\mathcal{B}(\frac{\partial l}{\partial y})=\frac{\partial l}{\partial y}\cos(0.5).

еслиl=0.5y=0.5sin(x)l=0.5y=0.5\sin(x), мы можем получитьly=0.5\frac{\partial l}{\partial y}=0.5,Такlx=B(ly)=B(0.5)\frac{\partial l}{\partial x}=\mathcal{B}(\frac{\partial l}{\partial y})=\mathcal{B}(0.5).


Ссылаться на:

[1] Пользовательские сопряжения • Зигота