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?
perceptron
pytorch
Bai Li
fuente
fuente
Respuestas:
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.
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):
Puede hacer que Adam sea más estable y pueda acercarse a la verdadera convergencia al reducir la tasa de aprendizaje. P.ej
lr=1e-5
fuente
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:
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.
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.
fuente