Eu tenho o seguinte CNN:
- Começo com uma imagem de entrada do tamanho 5x5
- Em seguida, aplico a convolução usando o kernel 2x2 e stride = 1, que produz um mapa de recursos do tamanho 4x4.
- Em seguida, aplico o pool máximo 2x2 com stride = 2, que reduz o mapa de recursos para o tamanho 2x2.
- Então aplico sigmóide logístico.
- Em seguida, uma camada totalmente conectada com 2 neurônios.
- E uma camada de saída.
Por uma questão de simplicidade, vamos assumir que eu já completei o passe para frente e calculei δH1 = 0,25 e δH2 = -0,15
Então, após a passagem para frente completa e para trás parcialmente concluída, minha rede fica assim:
Em seguida, calculo deltas para a camada não linear (sigmóide logística):
Em seguida, propago deltas para a camada 4x4 e defino todos os valores que foram filtrados pelo pool máximo para 0 e o mapa de gradiente se parece com o seguinte:
Como atualizo os pesos do kernel a partir daí? E se minha rede tiver outra camada convolucional anterior a 5x5, que valores devo usar para atualizar os pesos do kernel? E no geral, meu cálculo está correto?
machine-learning
convnet
backpropagation
cnn
kernel
koryakinp
fonte
fonte
Respostas:
Uma convolução emprega um princípio de compartilhamento de peso que complicará significativamente a matemática, mas vamos tentar superar as ervas daninhas. Estou tirando a maior parte da minha explicação dessa fonte .
Passar para a frente
Como você observou, a passagem direta da camada convolucional pode ser expressa como
Retropropagação
Supondo que você esteja usando o erro quadrático médio (MSE) definido como
nós queremos determinar
Isso itera por todo o espaço de saída, determina o erro que a saída está contribuindo e, em seguida, determina o fator de contribuição do peso do kernel em relação a essa saída.
Vamos chamar a contribuição para o erro do delta do espaço de saída por simplicidade e acompanhar o erro retropropagado,
A contribuição dos pesos
A convolução é definida como
portanto,
Então, de volta ao nosso termo de erro
Descida do gradiente estocástico
Vamos calcular alguns deles
Informe-me se houver erros na derivação.
Atualização: código corrigido
fonte
gradient = signal.convolve2d(np.rot90(np.rot90(d)), o, 'valid')