Pergunta

Alguém pode recomendar um site ou me dar um resumo de como a retropropagação é implementada em uma NN?Entendo o conceito básico, mas não tenho certeza de como escrever o código.

Muitas das fontes que encontrei simplesmente mostram equações sem dar qualquer explicação do motivo pelo qual estão fazendo isso, e os nomes das variáveis ​​dificultam a descoberta.

Exemplo:

void bpnn_output_error(delta, target, output, nj, err)
double *delta, *target, *output, *err;
int nj;
{
  int j;
  double o, t, errsum;

  errsum = 0.0;
  for (j = 1; j <= nj; j++) {
    o = output[j];
    t = target[j];
    delta[j] = o * (1.0 - o) * (t - o);
    errsum += ABS(delta[j]);
  }
  *err = errsum;

}

Nesse exemplo, alguém pode explicar o propósito de

delta[j] = o * (1.0 - o) * (t - o);

Obrigado.

Foi útil?

Solução

O propósito de

delta[j] = o * (1,0 - o) * (t - o);

é encontrar o erro de um nó de saída em uma rede de retropropagação.

o representa a saída do nó, t é o valor esperado da saída do nó.

O termo, (o * (1,0 - o), é a derivada de uma função de transferência comum usada, a função sigmóide.(Outras funções de transferência não são incomuns e exigiriam uma reescrita do código que possui a primeira derivada sigmóide.Uma incompatibilidade entre função e derivada provavelmente significaria que o treinamento não convergiria.) O nó possui um valor de "ativação" que é alimentado por meio de uma função de transferência para obter a saída o, como

o = f (ativação)

O principal é que a retropropagação usa gradiente descendente e o erro é propagado para trás pela aplicação da Regra da Cadeia.O problema é a atribuição de crédito, ou culpa, se preferir, pelos nós ocultos cuja saída não é diretamente comparável ao valor esperado.Começamos com o que é conhecido e comparável, os nós de saída.O erro é considerado proporcional à primeira derivada da saída vezes o valor bruto do erro entre a saída esperada e a saída real.

Então, de forma mais simbólica, escreveríamos essa linha como

delta[j] = f'(ativação_j) * (t_j - o_j)

onde f é sua função de transferência e f' é sua primeira derivada.

Mais atrás, nas camadas ocultas, o erro em um nó é a sua contribuição estimada para os erros encontrados na próxima camada.Assim, os deltas da camada seguinte são multiplicados pelos pesos de conexão e esses produtos são somados.Essa soma é multiplicada pela primeira derivada da ativação do nó oculto para obter o delta de um nó oculto, ou

delta[j] = f'(ativação_j) * Soma(delta[k] * w_jk)

onde j agora faz referência a um nó oculto e k a um nó em uma camada seguinte.

Outras dicas

(t-o) é o erro na saída da rede já que t é a saída alvo e o é a saída real.Ele está sendo armazenado de forma normalizada no delta variedade.O método usado para normalizar depende da implementação e do o * ( 1.0 - o ) parece estar fazendo isso (posso estar errado sobre essa suposição).

Este erro normalizado é acumulado para todo o conjunto de treinamento para avaliar quando o treinamento está completo:geralmente quando errsum está abaixo de algum limite alvo.

Na verdade, se você conhece a teoria, os programas devem ser fáceis de entender.Você pode ler o livro e fazer alguns exemplos simples usando um lápis para descobrir o etapas exatas de propagação.Este é um princípio geral para implementação de programas numéricos; você deve conhecer os detalhes em casos pequenos.

Se você conhece o Matlab, sugiro que leia algum código-fonte do Matlab (por exemplo, aqui), que é mais fácil de entender do que C.

Para o código da sua pergunta, os nomes são bastante autoexplicativos, a saída pode ser a matriz da sua previsão, o alvo pode ser a matriz de rótulos de treinamento, o delta é o erro entre a previsão e os valores verdadeiros, também serve como valor para ser atualizado no vetor de peso.

Essencialmente, o que o backprop faz é executar a rede nos dados de treinamento, observar a saída e, em seguida, ajustar os valores dos nós, indo dos nós de saída de volta aos nós de entrada iterativamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top