20 votos

¿Por qué fluctúa la pérdida/precisión durante el entrenamiento? (Keras, LSTM)

Utilizo la red LSTM en Keras. Durante el entrenamiento, la pérdida fluctúa mucho, y no entiendo por qué ocurre eso.

Aquí está el NN que estaba usando inicialmente: enter image description here

Y aquí están las pérdidas y la precisión durante el entrenamiento: enter image description here

(Tenga en cuenta que la precisión alcanza el 100%, pero tarda unas 800 épocas).

Pensé que estas fluctuaciones se producen debido a las capas Dropout / cambios en la tasa de aprendizaje (he utilizado rmsprop / adam), así que hice un modelo más simple: enter image description here

También he utilizado SGD sin impulso ni decaimiento. He probado diferentes valores para lr pero sigo obteniendo el mismo resultado.

sgd = optimizers.SGD(lr=0.001, momentum=0.0, decay=0.0, nesterov=False)

Pero sigo teniendo el mismo problema: la pérdida fluctúa en lugar de disminuir. Siempre he pensado que se supone que la pérdida disminuye gradualmente, pero aquí no parece comportarse así.

Así que..:

  1. ¿Es normal que la pérdida fluctúe así durante el entrenamiento? ¿Y por qué ocurriría?

  2. Si no es así, ¿por qué ocurriría esto para el modelo LSTM simple con el lr a un valor muy pequeño?

Gracias. (Tenga en cuenta que he consultado preguntas similares aquí, pero no me ayudaron a resolver mi problema).

Pónganse al día.: para más de 1000 épocas (sin capa BatchNormalization, sin modificador RmsProp de Keras): enter image description here

Actualización. 2: Para el gráfico final:

model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
history = model.fit(train_x, train_y, epochs = 1500)

Datos: secuencias de valores de la corriente (procedentes de los sensores de un robot).

Variables objetivo: la superficie sobre la que está operando el robot (como vector unidireccional, 6 categorías diferentes).

Preprocesamiento:

  1. cambiar la frecuencia de muestreo para que las secuencias no sean demasiado largas (LSTM no parece aprender de otro modo);
  2. cortar las secuencias en las secuencias más pequeñas (la misma longitud para todas las secuencias más pequeñas: 100 pasos de tiempo cada una);
  3. comprobar que cada una de las 6 clases tiene aproximadamente el mismo número de ejemplos en el conjunto de entrenamiento.

Sin relleno.

Forma del conjunto de entrenamiento (#secuencias, #tiempos en una secuencia, #características):

(98, 100, 1) 

Forma de las etiquetas correspondientes (como vector de un solo golpe para 6 categorías):

(98, 6)

Capas:

enter image description here

El resto de los parámetros (tasa de aprendizaje, tamaño del lote) son los mismos que los predeterminados en Keras:

keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=None, decay=0.0)

tamaño_lote: Entero o Ninguno. Número de muestras por actualización de gradiente. Si no se especifica, será por defecto 32.

Actualización. 3: La pérdida por batch_size=4 :

enter image description here

Para batch_size=2 el LSTM no parece aprender correctamente (la pérdida fluctúa en torno al mismo valor y no disminuye).

Actualización. 4: Para ver si el problema no es sólo un error en el código: He hecho un ejemplo artificial (2 clases que no son difíciles de clasificar: cos vs arccos). Pérdida y precisión durante el entrenamiento para estos ejemplos: enter image description here

16voto

Robert White Puntos 31

Hay varias razones que pueden causar fluctuaciones en la pérdida de entrenamiento a lo largo de las épocas. La principal, sin embargo, es el hecho de que casi todas las redes neuronales se entrenan con diferentes formas de descenso por gradiente estocástico . Esta es la razón por la que existe el parámetro batch_size, que determina cuántas muestras desea utilizar para realizar una actualización de los parámetros del modelo. Si utiliza todas las muestras para cada actualización, debería ver que disminuye y finalmente alcanza un límite. Tenga en cuenta que hay otras razones para que la pérdida tenga algún comportamiento estocástico.

Esto explica por qué vemos oscilaciones. Pero en tu caso, es más que normal diría yo. Mirando su código, veo dos posibles fuentes.

  1. Red grande, conjunto de datos pequeño: Parece que estás entrenando una red relativamente grande con más de 200.000 parámetros con un número muy pequeño de muestras, ~100. Para ponerlo en perspectiva, usted quiere aprender 200.000 parámetros o encontrar un buen mínimo local en un espacio de 200.000 D utilizando sólo 100 muestras. Por lo tanto, es posible que acabe dando vueltas en lugar de encontrar un buen mínimo local. (El vagabundeo también se debe a la segunda razón que se expone a continuación).

  2. Tamaño_lote muy pequeño. Usted utiliza batch_size muy pequeño. Así que es como si estuvieras confiando en cada pequeña porción de los puntos de datos. Digamos que dentro de tus puntos de datos, tienes una muestra mal etiquetada. Esta muestra cuando se combina con 2-3 muestras incluso correctamente etiquetados, puede dar lugar a una actualización que no disminuye la pérdida global, pero aumentarla, o tirarlo fuera de un mínimo local. Cuando el batch_size es mayor, estos efectos se reducen. Junto con otras razones, es bueno tener batch_size superior a algún mínimo. Tenerlo demasiado grande también haría que el entrenamiento fuera lento. Por lo tanto, el tamaño_lote debería tratarse como un hiperparámetro.

2voto

Anthony Gatti Puntos 31

Tu curva de pérdidas no me parece tan mala. Definitivamente debería "fluctuar" un poco hacia arriba y hacia abajo, siempre y cuando la tendencia general sea que va hacia abajo - esto tiene sentido.

El tamaño del lote también influirá en el aprendizaje de la red, por lo que es recomendable optimizarlo junto con la velocidad de aprendizaje. Además, yo trazaría toda la curva (hasta que alcance el 100% de precisión/mínima pérdida). Parece que la has entrenado durante 800 epochs y sólo muestras las primeras 50 epochs - la curva completa probablemente mostrará una historia muy diferente.

0voto

Lukasz M Puntos 3232

Las fluctuaciones son normales dentro de ciertos límites y dependen de que utilices un método heurístico, pero en tu caso son excesivas. A pesar de todo el rendimiento toma una dirección definida y por lo tanto el sistema funciona. Por los gráficos que has colgado, el problema depende de tus datos por lo que es un entrenamiento difícil. Si ya has probado a cambiar la tasa de aprendizaje prueba a cambiar el algoritmo de entrenamiento. Estaria de acuerdo en probar sus datos: primero calcule la tasa de error de Bayes usando un KNN (use el truco de regresion en caso de que lo necesite), de esta manera podra comprobar si los datos de entrada contienen toda la informacion que necesita. Después prueba el LSTM sin la validación o dropout para verificar que tiene la capacidad de conseguir el resultado que necesitas. Si el algoritmo de entrenamiento no es adecuado, deberías tener los mismos problemas incluso sin la validación o el abandono. Sólo al final ajustar el entrenamiento y el tamaño de validación para obtener el mejor resultado en el conjunto de prueba. La teoría del aprendizaje estadístico no es un tema del que se pueda hablar de una sola vez, debemos proceder paso a paso.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X