Passei um tempo insano depurando gradientes explosivos e comportamento semelhante. Sua resposta dependerá da função de perda, dados, arquitetura etc. Existem centenas de razões. Vou citar alguns.
- Dependente de perda. As perdas de probabilidade de log precisam ser cortadas; caso contrário, elas podem ser avaliadas próximas
log(0)
a previsões / discrepâncias ruins no conjunto de dados, causando gradientes explosivos. A maioria dos pacotes (tocha, fluxo tensor etc.) implementa o recorte por padrão para suas perdas.
- Outliers no conjunto de dados.
- ϵy= ( x - u ) / ( s + ϵ )sϵy
- O lote final em uma época pode ser pequeno se o conjunto de dados não puder ser dividido pelo tamanho do lote. No carregador de dados da tocha, há uma bandeira
drop_last
. Tamanho pequeno do lote = alta variação
Agora, por que você vê isso com Adam e não com a SGD? Claramente, você alcançou uma perda menor com Adam. Como observado anteriormente, se 99,9% do conjunto de dados tiver ótimos em um ponto, exceto algumas observações, pode ser que a observação grite "NÃO" e salte dos mínimos locais quando selecionados aleatoriamente para um lote. Se você dataset_size//batch_size+1
vir a cada passo, provavelmente é devido ao tamanho final do lote ser pequeno. Aposto que você também verá o pico da SGD se você permitir que ela atinja uma perda menor.
Bônus: Sua diminuição muito rápida com o otimizador de momento (Adam) pode significar que alguma camada (camada de entrada? Camada de saída?) É inicializada fora da escala (para pesos grandes / pequenos).