Derivando equações de retropropagação "nativamente" na forma de tensor


7

A imagem mostra uma camada típica em algum lugar da rede feed forward:

insira a descrição da imagem aqui

ai(k) é o valor de ativação do neurônio na camada .ithkth

Wij(k) é o peso que liga neurónio na camada para a neurónio na camada.ithkthjth(k+1)th

zj(k+1) é o valor da função de pré-ativação do neurônio na camada . Às vezes, isso é chamado de "logit", quando usado com funções logísticas.jth(k+1)th

As equações de avanço de alimentação são as seguintes:

zj(k+1)=∑iWij(k)ai(k)

aj(k+1)=f(zj(k+1))

Por uma questão de simplicidade, o viés é incluído como uma ativação fictícia de 1 e é implícito usado nas iterações sobre .i

Posso derivar as equações para propagação reversa em uma rede neural de feed-forward, usando regra de cadeia e identificando valores escalares individuais na rede (na verdade, geralmente faço isso como um exercício de papel apenas para a prática):

Dado como gradiente da função de erro em relação à saída de um neurônio.∇aj(k+1)=∂E∂aj(k+1)

1.∇zj(k+1)=∂E∂zj(k+1)=∂E∂aj(k+1)∂aj(k+1)∂zj(k+1)=∇aj(k+1)f′(zj(k+1))

2.∇ai(k)=∂E∂ai(k)=∑j∂E∂zj(k+1)∂zj(k+1)∂ai(k)=∑j∇zj(k+1)Wij(k)

3.∇Wij(k)=∂E∂Wij(k)=∂E∂zj(k+1)∂zj(k+1)∂Wij(k)=∇zj(k+1)ai(k)

Por enquanto, tudo bem. No entanto, geralmente é melhor recuperar essas equações usando matrizes e vetores para representar os elementos. Eu posso fazer isso, mas não sou capaz de descobrir a representação "nativa" da lógica equivalente no meio das derivações. Eu posso descobrir quais devem ser as formas finais consultando a versão escalar e verificando se as multiplicações têm dimensões corretas, mas não tenho idéia de por que devo colocar as equações nessas formas.

Existe realmente uma maneira de expressar a derivação baseada em tensor da propagação reversa, usando apenas operações vetoriais e matriciais, ou é uma questão de "ajustá-la" à derivação acima?

Usando vetores de coluna , , e matriz de pesos mais o vetor de viés , as operações de feed-forward são:a(k)z(k+1)a(k+1)W(k)b(k)

z(k+1)=W(k)a(k)+b(k)

a(k+1)=f(z(k+1))

Então minha tentativa de derivação é assim:

1.∇z(k+1)=∂E∂z(k+1)=???=∇a(k+1)⊙f′(z(k+1))

2.∇a(k)=∂E∂a(k)=???=W(k)T∇z(k+1)

3.∇W(k)=∂E∂W(k)=???=∇z(k+1)a(k)T

Onde representa multiplicação por elementos. Eu não me incomodei em mostrar a equação para o viés.⊙

Onde eu coloquei ??? Não tenho certeza do caminho correto a partir das operações de feed-forward e conhecimento de equações diferenciais lineares para estabelecer a forma correta das equações? Eu poderia escrever alguns termos derivativos parciais, mas não tenho idéia de por que alguns devem usar multiplicação por elementos, outros por multiplicação de matrizes e por que a ordem de multiplicação deve ser mostrada, a não ser que claramente dê o resultado correto no final .

Não tenho certeza se existe uma derivação puramente tensorial ou se é apenas uma "vetorização" do primeiro conjunto de equações. Mas minha álgebra não é tão boa e estou interessado em descobrir de uma maneira ou de outra. Eu acho que isso pode me ajudar a compreender bem o TensorFlow, por exemplo, se eu tivesse uma melhor compreensão nativa dessas operações, pensando mais com a álgebra de tensores.


Desculpe pela notação ad-hoc / incorreta. Agora entendo que está escrito de maneira mais apropriada graças à resposta de Ehsan. O que eu realmente queria que houvesse uma variável de referência curta para substituir nas equações, em oposição às derivadas parciais verbais.∇aj(k+1)∇aj(k+1)E


Para ser sincero, usar componentes é muito mais fácil do que usar a forma matriz / vetor das equações. Mas se você quiser derivar a forma de matriz, você pode querer olhar para en.wikipedia.org/wiki/Matrix_calculus
— J. O'Brien Antognini

@ J.O'BrienAntognini: Acho que é isso que quero ver, sim. Se isso acaba explorando a teoria, e não é muito útil para entender o trabalho de rotina com o TensorFlow, etc., acho que ainda o achará interessante.
— Neil Slater

Respostas:


3

A notação é importante! O problema começa em:

Dado∇aj(k+1)=∂E∂aj(k+1)

Eu não gosto da sua anotação! na verdade, está errado na notação matemática padrão. A notação correta é

∇aj(k+1)E=∂E∂aj(k+1)

Então, o gradiente do erro escreve um vetor é definido comoEa(k)

∇a(k)E=(∂E∂a1(k),⋯,∂E∂an(k))T(⋆)

( observação : transpomos devido à convenção de que representamos vetores como vetores de coluna; se você deseja representar como vetores de linha, as equações que você deseja provar mudarão uma transposição!)

portanto, com regra de cadeia,

∂E∂ai(k)=∑j∂E∂zj(k+1)∂zj(k+1)∂ai(k)=∑j∂E∂zj(k+1)Wij(k)

por causa deAgora, você pode expressar o acima como produto vetorial (interno)zj(k+1)=∑iWij(k)ai(k).

∂E∂ai(k)=(W:,i(k))T∇z(k+1)E
e empilhando-os em podemos expressar como produto de vetor de matriz(⋆),∇a(k)E

∇a(k)E=(W(k))T∇z(k+1)E.

Vou deixar o resto para você :)

Mais cálculo vetorial!

Vamos usar a convenção de vetores como vetores de coluna. Então ez(k+1)=(W(k))Ta(k)+b(k)

∇a(k)E=∂E∂a(k)=∂z(k+1)∂a(k)∂E∂z(k+1)=W(k)∂E∂z(k+1)

Porque

∂z(k+1)∂a(k)=∂((W(k))Ta(k)+b(k))∂a(k)=∂((W(k))Ta(k))∂a(k)+∂b(k)∂a(k)

e pois não depende de∂b(k)∂a(k)=0b(k)a(k).

portanto

∂((W(k))Ta(k))∂a(k)=∂a(k)∂a(k)W(k)=W(k).

por vetor por vetor (oito e sétima linha, identidades da última coluna, respectivamente)


@NeilSlater Adicionei mais. Espero que ajude agora.
— Ehsan M. Kermani 13/04

Obrigado. O link para en.wikipedia.org/wiki/… é um fator chave para mim.
— Neil Slater
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.