Entendendo a retropropagação da rede neural
-
25-09-2019 - |
Pergunta
ATUALIZAÇÃO: Uma melhor formulação do problema.
Estou tentando entender o algoritmo de retropropagação com uma rede neural XOR como exemplo. Para este caso, existem 2 neurônios de entrada + 1 viés, 2 neurônios na camada oculta + 1 viés e 1 neurônio de saída.
A B A XOR B
1 1 -1
1 -1 1
-1 1 1
-1 -1 -1
(fonte: wikimedia.org)
estou a usar retropropagação estocástica.
Depois de ler um pouco mais, descobri que o erro da unidade de saída é propagado para as camadas ocultas ... inicialmente, isso foi confuso, porque quando você chega à camada de entrada da rede neural, cada neurônio recebe um ajuste de erro de ambos os neurônios na camada oculta. Em particular, a maneira como o erro é distribuído é difícil de entender no início.
Passo 1 Calcule a saída para cada instância de entrada.
Passo 2 Calcule o erro entre os neurônios de saída (no nosso caso, existe apenas um) e o (s) valor (s) alvo:
etapa 3 Usamos o erro da Etapa 2 para calcular o erro para cada unidade oculta H:
O 'peso kh' é o peso entre a unidade oculta H e a unidade de saída K, bem, isso é confuso porque a unidade de entrada não possui um peso direto associado à unidade de saída. Depois de olhar para a fórmula por algumas horas, comecei a pensar no que significa o somatório, e estou começando a chegar à conclusão de que cada peso de cada neurônio que se conecta aos neurônios da camada oculta é multiplicado pelo erro de saída e resumido . Esta é uma conclusão lógica, mas a fórmula parece um pouco confusa, pois diz claramente o 'peso kh' (entre a camada de saída K e a camada oculta H).
Estou entendendo tudo corretamente aqui? Alguém pode confirmar isso?
O que é O (h) da camada de entrada? Meu entendimento é que cada nó de entrada possui duas saídas: uma que entra no primeiro nó da camada oculta e uma que entra na segunda camada oculta do nó. Qual das duas saídas deve ser conectada ao O(h)*(1 - O(h))
parte da fórmula?
Solução
O tutorial que você postou aqui está realmente fazendo errado. Eu o verifiquei contra os dois livros padrão de Bishop e duas das minhas implementações de trabalho. Vou apontar abaixo onde exatamente.
Uma coisa importante a ter em mente é que você está sempre procurando derivadas da função de erro em relação a uma unidade ou peso. Os primeiros são os deltas, o último é o que você usa para atualizar seus pesos.
Se você deseja entender a retropacagação, precisa entender a regra da cadeia. É tudo sobre a regra da cadeia aqui. Se você não sabe como funciona exatamente, consulte a Wikipedia - não é tão difícil. Mas assim que você entende as derivações, tudo se encaixa. Promessa! :)
∂e/∂w pode ser composto em ∂e/∂o ∂o/∂w através da regra da corrente. ∂O/∂w é facilmente calculado, pois é apenas a derivada da ativação/saída de uma unidade em relação aos pesos. ∂e/∂o é na verdade o que chamamos de deltas. (Estou assumindo que E, O e W são vetores/matrizes aqui)
Nós os temos para as unidades de saída, pois é aí que podemos calcular o erro. (Principalmente, temos uma função de erro que se resume ao delta de (T_K - O_K), por exemplo, para função de erro quadrático no caso de saídas lineares e entropia cruzada no caso de saídas logísticas.)
A questão agora é: como obtemos os derivados para as unidades internas? Bem, sabemos que a saída de uma unidade é a soma de todas as unidades recebidas ponderadas por seus pesos e a aplicação de uma função de transferência posteriormente. Então O_K = F (SUM (W_KJ * O_J, para todos J)).
Então, o que fazemos é derivar O_K em relação a O_J. Desde delta_j = ∂e/∂o_j = ∂e/∂o_k ∂o_k/∂o_j = delta_k ∂o_k/o_j. Então, dado a delta_k, podemos calcular delta_j!
Vamos fazer isso. o_k = f (sum (w_kj * o_j, para todos j)) => ∂o_k/∂o_j = f '(sum (w_kj * o_j, para todos j)) * w_kj = f' (z_k) * w_kj.
Para o caso da função de transferência sigmoidal, isso se torna z_k (1 - z_k) * w_kj. (Aqui está o erro no tutorial, o autor diz O_K (1 - O_K) * W_KJ!)
Outras dicas
Não tenho certeza de qual é a sua pergunta, mas eu realmente passei por esse tutorial e posso garantir que, além de um erro de digitação óbvia, não há nada incorreto nisso.
Vou assumir que sua pergunta é porque você está confuso sobre como a retropropagação escondido Delta é derivado. Se essa é realmente a sua pergunta, considere
(fonte: pandamatak.com)
Você provavelmente está confuso sobre como o autor derivou esta equação. Esta é na verdade uma aplicação direta da regra da cadeia multivariada. Ou seja, (o que se segue é retirado de Wikipedia)
"Suponha que cada argumento de z = f (u, v) seja uma função de duas variáveis, de modo que u = h (x, y) e v = g (x, y) e que essas funções sejam todas diferenciáveis. Então o A regra da cadeia seria:
"
Agora imagine estender a regra da cadeia por um argumento de indução para
E (z '1, Z '2, .., Z 'n) onde z 'k é a saída da pré-ativação da camada de saída Kth e Z 'k(Wji) isto é, que E é uma função do Z 'e Z' em si é uma função de Wji (Se isso não fizer sentido para você a princípio acho com muito cuidado sobre como um NN é configurado.) Aplicando a regra da cadeia diretamente estendida a n variáveis:
ΔE (Z '1, Z '2, .., Z 'n)/ΔWji = Σk ΔE/ΔZ 'k ΔZ 'k/ΔWji
Essa é a etapa mais importante, o autor aplica a regra da cadeia novamente, desta vez dentro da soma para expandir o ΔZ 'k/ΔWji termo, isso é
ΔZ 'k/ΔWji = ΔZ 'k/ΔOj ΔOj/ΔZj ΔZj/ΔWji.
Se você tiver dificuldades em entender a regra da cadeia, pode ser necessário fazer um curso sobre cálculo multivariado ou ler essa seção em um livro.
Boa sorte.
O que li da equação da Etapa 3 é:
- O_H = Última saída desta unidade oculta (O_H na camada de entrada é o valor de entrada real)
- W_KH = Peso da conexão entre esta unidade oculta e uma unidade da próxima camada (em direção à saída)
- delta_k = erro da unidade da próxima camada (em direção à saída, a mesma unidade que a bala anterior)
Cada unidade possui apenas uma saída, mas cada link entre a saída e a próxima camada é ponderada. Portanto, a saída é a mesma, mas na extremidade de recebimento, cada unidade receberá um valor diferente se o peso dos links for diferente. O_H sempre refere -se ao valor desse neurônio para a última iteração. O erro não se aplica à camada de entrada, pois, por definição, a entrada não possui 'erro' em si.
O erro precisa ser calculado camada por camada, iniciando no lado da saída, pois precisamos dos valores de erro da camada n+1 para calcular a camada n. Você está certo, não há conexão direta entre entrada e saída na retropropagação.
Eu acredito que a equação está correta, se contra -intuitiva. O que provavelmente é confuso é que, na propagação direta para cada unidade, temos que considerar todas as unidades e links à esquerda da unidade (valores de entrada), mas para a propagação de erros (retropropagação) era ter que considerar as unidades à direita (saída valor) da unidade sendo processada.