He pasado una cantidad insana de tiempo depurando gradientes explosivos y comportamientos similares. La respuesta dependerá de la función de pérdida, los datos, la arquitectura, etc. Hay cientos de razones. Voy a nombrar algunas.
- Depende de la pérdida. Las pérdidas de Loglikelihood necesitan ser recortadas, si no, puede evaluar cerca de
log(0)
para las malas predicciones / valores atípicos en el conjunto de datos, causando la explosión de los gradientes. La mayoría de los paquetes (torch, tensorflow, etc.) implementan el recorte por defecto para sus pérdidas.
- Valores atípicos en el conjunto de datos.
- BatchNorm con un tamaño de lote pequeño y un épsilon grande $\epsilon$ (hiperparámetro). Con batchnorm como $y=(x-u)/(s+\epsilon)$ y, a continuación, con una pequeña $s$ y $\epsilon$ se pueden obtener altas magnitudes de $y$
- El último lote de una época puede ser pequeño si el conjunto de datos no es divisible por el tamaño del lote. En el cargador de datos de Torch hay una bandera
drop_last
. Pequeño tamaño de lote = alta varianza
¿Ahora por qué lo ves con Adam y no con SGD? Está claro que con Adán has llegado a una pérdida menor. Como se señaló antes, si el 99,9% del conjunto de datos tiene óptimos en un punto excepto alguna observación, esto puede ser que la observación gritando "NO" y saltando fuera de los mínimos locales cuando se selecciona al azar a un lote. Si se ve cada dataset_size//batch_size+1
-pasos, probablemente se deba a que el tamaño del lote final es pequeño. Apuesto a que verás el pico de SGD también si dejas que alcance una pérdida menor.
Bonificación: Su disminución realmente rápida con el optimizador de impulso (Adam) podría significar que alguna capa (¿capa de entrada? ¿capa de salida?) está inicializada muy fuera de escala (con pesos grandes/pequeños).