Vamos supor que estamos usando um tamanho de lote de 100 amostras para aprender.
Assim, em cada lote, o peso de cada neurônio (e viés, etc.) está sendo atualizado adicionando menos a taxa de aprendizado * o valor médio de erro que encontramos usando as 100 amostras * a derivada da função de erro com relação a o peso atual do neurônio que está sendo atualizado.
Agora, quando usamos uma camada Max Pool, como podemos calcular a derivada nessa camada? Em cada amostra que alimentamos para a frente, um pixel diferente (digamos) é escolhido como o máximo, portanto, quando retropropagamos mais de 100 amostras nas quais cada vez que um caminho diferente era escolhido, como podemos fazê-lo? Uma solução que tenho em mente é lembrar todos os pixels escolhidos como o máximo e, talvez, dividir a derivada por todos os pixels máximos. É isso que está sendo feito?
Respostas:
Quando uma rede neural processa um lote, todos os valores de ativação para cada camada são calculados para cada exemplo (talvez em paralelo, por exemplo, se a biblioteca e o hardware suportarem). Esses valores são armazenados para possível uso posterior - ou seja, um valor por ativação por exemplo no lote, eles não são agregados de forma alguma
Durante a propagação de retorno, esses valores de ativação são usados como uma das fontes numéricas para calcular os gradientes, juntamente com os gradientes calculados até agora trabalhando para trás e os pesos de conexão. Como a propagação direta, a propagação reversa é aplicada por exemplo, não funciona com valores médios ou somados. Somente quando todos os exemplos foram processados, você trabalha com os gradientes somados ou médios do lote.
Isso se aplica igualmente às camadas máximas do pool. Você não apenas sabe qual foi a saída da camada de pool para cada exemplo no lote, mas também pode olhar para a camada anterior e determinar qual entrada no pool foi a máxima.
Matematicamente, e evitando a necessidade de definir índices para camadas e neurônios NN, a regra pode ser expressa assim
A função de avanço ém=max(a,b)
Nós sabemos∂J∂m para alguma função de destino J (na rede neural que será a função de perda que queremos minimizar e estamos assumindo que já retropropagamos para esse ponto)
Nós queremos saber∂J∂a e ∂J∂b
E sea>b
Localmente , *m=a . assim∂J∂a=∂J∂m
Localmente , *m não depende de b . assim∂J∂b=0
Portanto∂J∂a=∂J∂m E se a>b , outro ∂J∂a=0
e∂J∂b=∂J∂m E se b>a , outro ∂J∂b=0
Quando a propagação de retorno passa por uma camada de pool máximo, o gradiente é processado por exemplo e atribuído apenas à entrada da camada anterior que era o máximo. Outras entradas obtêm gradiente zero. Quando isso é feito em lote, não é diferente, é apenas processado por exemplo, talvez em paralelo. Em todo um lote, isso pode significar que mais de uma, talvez todas, as ativações de entrada no pool máximo recebem uma parte do gradiente - cada uma de um subconjunto diferente de exemplos no lote.
* Localmente -> ao fazer apenas alterações infinitesimais emm .
** Tecnicamente, sea=b exatamente então temos uma descontinuidade, mas na prática podemos ignorá-la sem problemas ao treinar uma rede neural.
fonte
Eu tenho a mesma pergunta, mas provavelmente descobri analisando o código fonte do Caffe.
Por favor, veja o código fonte do Caffe:
linha 620 e 631 deste código.
Ele calcula a derivada de cada parâmetro adicionando a derivada (deste parâmetro) de cada entrada e depois dividindo-a pelo tamanho do lote.
Veja também a linha 137 deste código, ele simplesmente escala a derivada para 1 / iter_size, exatamente igual à média.
Podemos ver que NÃO há tratamento especial para a camada Max Pooling quando a BP.
Quanto à derivada do Max Pooling, vamos ver o código-fonte do Caffe novamente:
linha 272 deste código. Obviamente, apenas a derivada do maior elemento é a derivada dos
1*top_diff
outros0*top_diff
.fonte