Comportamiento extraño con Adam Optimizer cuando se entrena durante demasiado tiempo

11

Estoy tratando de entrenar un solo perceptrón (1000 unidades de entrada, 1 salida, sin capas ocultas) en 64 puntos de datos generados aleatoriamente. Estoy usando Pytorch usando el optimizador Adam:

import torch
from torch.autograd import Variable

torch.manual_seed(545345)
N, D_in, D_out = 64, 1000, 1

x = Variable(torch.randn(N, D_in))
y = Variable(torch.randn(N, D_out))

model = torch.nn.Linear(D_in, D_out)
loss_fn = torch.nn.MSELoss(size_average=False)

optimizer = torch.optim.Adam(model.parameters())
for t in xrange(5000):
  y_pred = model(x)
  loss = loss_fn(y_pred, y)

  print(t, loss.data[0])

  optimizer.zero_grad()
  loss.backward()
  optimizer.step()

Inicialmente, la pérdida disminuye rápidamente, como se esperaba:

(0, 91.74887084960938)
(1, 76.85824584960938)
(2, 63.434078216552734)
(3, 51.46927261352539)
(4, 40.942893981933594)
(5, 31.819372177124023)

Alrededor de 300 iteraciones, el error llega a casi cero:

(300, 2.1734419819452455e-12)
(301, 1.90354676465887e-12)
(302, 2.3347573874232808e-12)

Esto continúa por unos pocos miles de iteraciones. Sin embargo, después de entrenar durante demasiado tiempo, el error comienza a aumentar nuevamente:

(4997, 0.002102422062307596)
(4998, 0.0020302983466535807)
(4999, 0.0017039275262504816)

¿Por qué está pasando esto?

Bai Li
fuente
No creo que el sobreajuste lo explique: la pérdida de entrenamiento está aumentando, no la pérdida de validación. Por ejemplo, esto no sucede cuando se usa SGD, solo con Adam.
Bai Li
El modelo tiene 1000 parámetros y solo hay 1 punto de datos, por lo que el modelo debe ajustarse exactamente a los datos y la pérdida debe ser cero.
Bai Li el
Oh lo siento, tienes razón. Hay 64 puntos de datos.
Bai Li
Hay 64 puntos de datos (es decir, restricciones) y 1000 parámetros, por lo que es posible encontrar opciones para los parámetros para que el error sea cero (y esto es fácil de hacer analíticamente). Mi pregunta es por qué Adam no encuentra esto.
Bai Li
Continuemos esta discusión en el chat .
Bai Li

Respuestas:

19

Esta pequeña inestabilidad al final de la convergencia es una característica de Adam (y RMSProp) debido a cómo estima las magnitudes gradientes medias sobre los pasos recientes y las divide por ellas.

10-1010-5 5

En realidad, esto hace que Adam sea menos estable y peor para su problema que un descenso de gradiente más básico, suponiendo que desea obtener una pérdida numéricamente cercana a cero como los cálculos lo permiten.

En la práctica, en los problemas de aprendizaje profundo, no se acerca tanto a la convergencia (y para algunas técnicas de regularización como la interrupción temprana, no se desea), por lo que generalmente no es una preocupación práctica sobre los tipos de problemas que Adam fue diseñado para.

En realidad, puede ver que esto ocurre para RMSProp en una comparación de diferentes optimizadores (RMSProp es la línea negra; observe los últimos pasos justo cuando llega al objetivo):

ingrese la descripción de la imagen aquí

Puede hacer que Adam sea más estable y pueda acercarse a la verdadera convergencia al reducir la tasa de aprendizaje. P.ej

optimizer = torch.optim.Adam(model.parameters(), lr=1e-5)

lr=1e-510-7 7

Neil Slater
fuente
Esta es una visualización espectacular, Neil. ¿Cuáles son las dimensiones reales? ¿Qué representan x e y? ¿Son los cuadros algunas delta to n épocas por cuadro? Supongo que la estrella es el óptimo global en una representación topográfica de disparidad (error) en relación con dos parámetros seleccionados. ¿Es mi suposición correcta?
Douglas Daseeco
No es mi visualización, la encontrarás en muchos lugares. Las dimensiones son unidades arbitrarias de parámetros de entrada para una función de prueba, y el gráfico muestra líneas de contorno para esa función (nuevamente en unidades arbitrarias, presumiblemente escaladas para que NN funcione bien). Cada cuadro es un paso de actualización de peso. Probablemente sea equivalente a una actualización de mini lotes, y debido al comportamiento de SGD, espero que de hecho se resuelva exactamente utilizando el verdadero gradiente de la función de prueba, es decir, no hay un conjunto de datos o muestreo.
Neil Slater
1

La razón es exactamente como se menciona en la otra respuesta con una gran sugerencia de usar una tasa de aprendizaje más pequeña para evitar este problema en gradientes pequeños.

Puedo pensar en un par de enfoques:

  1. Puede recortar los gradientes con un límite superior / inferior, pero esto no garantiza la convergencia y puede provocar la congelación del entrenamiento al quedar atrapado en algunos mínimos locales y nunca salir de él.

  2. Entrena con un tamaño de lote más alto, más épocas y con una tasa de aprendizaje decaída. Ahora no tengo ninguna prueba práctica de que aumentar el tamaño de un lote resulte en mejores gradientes, pero por lo que he observado al enfrentar problemas similares a los suyos, hacerlo casi siempre ha ayudado.

Estoy seguro de que hay otros métodos (como la tasa de aprendizaje cíclico, etc.) que intentan encontrar una tasa de aprendizaje óptima basada en estadísticas.

Sanjay Krishna
fuente