Digamos que temos a expressão e queremos encontrar derivadas e . O AD de modo reverso divide essa tarefa em 2 partes, a saber, passes para frente e para trás.z=x1x2+sin(x1)dzdx1dzdx2
Passar para a frente
Primeiro, decompomos nossa expressão complexa em um conjunto de expressões primitivas, ou seja, expressões que consistem em, no máximo, uma chamada de função. Observe que eu também renomeio variáveis de entrada e saída para obter consistência, embora não seja necessário:
w1=x1
w2=x2
w3=w1w2
w4=sin(w1)
w5=w3+w4
z=w5
A vantagem dessa representação é que as regras de diferenciação para cada expressão separada já são conhecidas. Por exemplo, sabemos que a derivada de é e, portanto, . Usaremos esse fato no passe inverso abaixo.sincosdw4dw1=cos(w1)
Essencialmente, o encaminhamento consiste em avaliar cada uma dessas expressões e salvar os resultados. Digamos, nossas entradas são: e . Então nós temos:x1=2x2=3
w1=x1=2
w2=x2=3
w3=w1w2=6
w4=sin(w1) =0.9
w5=w3+w4=6.9
z=w5=6.9
Passagem reversa
Aqui é onde a mágica começa, e começa com a regra da cadeia . Em sua forma básica, a regra da cadeia declara que, se você tiver a variável que depende de que, por sua vez, depende de , então:t(u(v))uv
dtdv=dtdududv
ou, se depende de através de vários caminhos / variáveis , por exemplo:tvui
u1=f(v)
u2=g(v)
t=h(u1,u2)
então (veja a prova aqui ):
dtdv=∑idtduiduidv
Em termos de gráfico de expressão, se temos um nó final e nós de entrada , e o caminho de para passa pelos nós intermediários (ou seja, onde ), podemos encontrar derivativos comozwizwiwpz=g(wp)wp=f(wi)dzdwi
dzdwi=∑p∈parents(i)dzdwpdwpdwi
Em outras palavras, para calcular a derivada da variável de saída qualquer variável intermediária ou de entrada , precisamos apenas conhecer as derivadas de seus pais e a fórmula para calcular a derivada da expressão primitiva .zwiwp=f(wi)
A passagem reversa começa no final (ou seja, ) e se propaga para trás para todas as dependências. Aqui temos (expressão para "semente"):dzdz
dzdz=1
Isso pode ser lido como "mudança em resulta exatamente na mesma mudança em ", o que é bastante óbvio.zz
Então sabemos que e assim:z=w5
dzdw5=1
w5 depende linearmente de e , então e . Usando a regra da cadeia, encontramos:w3w4dw5dw3=1dw5dw4=1
dzdw3=dzdw5dw5dw3=1×1=1
dzdw4=dzdw5dw5dw4=1×1=1
A partir da definição e das regras de derivadas parciais, descobrimos que . Portanto:w3=w1w2dw3dw2=w1
dzdw2=dzdw3dw3dw2=1×w1=w1
Que, como já sabemos do passe para frente, é:
dzdw2=w1=2
Finalmente, contribui para via e . Mais uma vez, pelas regras das derivadas parciais, sabemos que e . Portanto:w1zw3w4dw3dw1=w2dw4dw1=cos(w1)
dzdw1=dzdw3dw3dw1+dzdw4dw4dw1=w2+cos(w1)
E, novamente, dadas as entradas conhecidas, podemos calculá-lo:
dzdw1=w2+cos(w1)=3+cos(2) =2.58
Como e são apenas aliases para e , obtemos nossa resposta:w1w2x1x2
dzdx1=2.58
dzdx2=2
E é isso!
Esta descrição refere-se apenas a entradas escalares, ou seja, números, mas na verdade também pode ser aplicada a matrizes multidimensionais, como vetores e matrizes. Duas coisas que devemos ter em mente ao diferenciar expressões com esses objetos:
- Os derivados podem ter uma dimensionalidade muito maior do que as entradas ou saídas, por exemplo, derivada do vetor wrt vetor é uma matriz e derivada da matriz wrt é uma matriz quadridimensional (às vezes chamada de tensor). Em muitos casos, esses derivados são muito escassos.
- Cada componente na matriz de saída é uma função independente de 1 ou mais componentes da (s) matriz (s) de entrada. Por exemplo, se e ambos e são vectores, não depende , mas apenas no subconjunto de . Em particular, isso significa que encontrar a derivada resume a rastrear como depende de .y=f(x)xyyiyjxkdyidxjyixj
O poder da diferenciação automática é que ele pode lidar com estruturas complicadas de linguagens de programação como condições e loops. No entanto, se tudo o que você precisa são expressões algébricas e você possui uma estrutura boa o suficiente para trabalhar com representações simbólicas, é possível construir expressões totalmente simbólicas. De fato, neste exemplo, podemos produzir a expressão e calcular essa derivada para quaisquer entradas que desejemos.dzdw1=w2+cos(w1)=x2+cos(x1)