Pérdida de NaN cuando entrena la red de regresión


Tengo una matriz de datos en "codificación one-hot" (todos unos y ceros) con 260,000 filas y 35 columnas. Estoy usando Keras para entrenar una red neuronal simple para predecir una variable continua. El código para hacer la red es el siguiente:

model = Sequential()
model.add(Dense(1024, input_shape=(n_train,)))
model.add(Activation('relu'))
model.add(Dropout(0.1))

model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.1))

model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Dense(1))

sgd = SGD(lr=0.01, nesterov=True);
#rms = RMSprop()
#model.compile(loss='categorical_crossentropy', optimizer=rms, metrics=['accuracy'])
model.compile(loss='mean_absolute_error', optimizer=sgd)
model.fit(X_train, Y_train, batch_size=32, nb_epoch=3, verbose=1, validation_data=(X_test,Y_test), callbacks=[EarlyStopping(monitor='val_loss', patience=4)] )

Sin embargo, durante el proceso de entrenamiento, veo que la pérdida disminuye muy bien, pero durante la mitad de la segunda época, va a nan:

Train on 260000 samples, validate on 64905 samples
Epoch 1/3
260000/260000 [==============================] - 254s - loss: 16.2775 - val_loss:
 13.4925
Epoch 2/3
 88448/260000 [=========>....................] - ETA: 161s - loss: nan

Intenté usar RMSProp en lugar de SGD, intenté tanh en lugar de relu, intenté con y sin deserción, todo en vano. Probé con un modelo más pequeño, es decir, con una sola capa oculta, y el mismo problema (se convierte en nan en un punto diferente). Sin embargo, funciona con menos características, es decir, si solo hay 5 columnas, y da predicciones bastante buenas. Parece que hay algún tipo de desbordamiento, pero no puedo imaginar por qué the la pérdida no es irrazonablemente grande en absoluto.

Python versión 2.7.11, ejecutándose en una máquina Linux, solo CPU. Lo probé con la última versión de Theano, y también tengo Nans, así que traté de ir a Theano 0.8.2 y tienen el mismo problema. Con la última versión de Keras tiene el mismo problema, y también con la versión 0.3.2.

Author: Seanny123, 2016-05-15

6 answers

La regresión con redes neuronales es difícil de conseguir porque la salida es ilimitada, por lo que es especialmente propenso al problema de gradientes de explosión (la causa probable de las nan).

Históricamente, una solución clave para la explosión de gradientes era reducir la tasa de aprendizaje, pero con la llegada de algoritmos de tasa de aprendizaje adaptativo por parámetro como Adam, ya no es necesario establecer una tasa de aprendizaje para obtener un buen rendimiento. Hay muy pocas razones para usar SGD con momentum más a menos que seas un demonio de la red neuronal y sepas cómo ajustar el horario de aprendizaje.

Aquí hay algunas cosas que podrías intentar:

  1. Normalice sus salidas por cuantil normalizando o z scoring . Para ser riguroso, calcule esta transformación en los datos de entrenamiento, no en todo el conjunto de datos. Por ejemplo, con la normalización de cuantiles, si un ejemplo está en el percentil 60 del conjunto de entrenamiento, obtiene un valor de 0.6. (También puedes desplace los valores normalizados cuantil hacia abajo por 0.5 de modo que el percentil 0 es -0.5 y el percentil 100 es +0.5).

  2. Agregue la regularización, ya sea aumentando la tasa de abandono o agregando penalizaciones L1 y L2 a los pesos. La regularización de L1 es análoga a la selección de características, y ya que usted dijo que reducir el número de características a 5 da un buen rendimiento, L1 también puede.

  3. Si esto aún no ayuda, reduzca el tamaño de su red. Esto no es siempre la mejor idea ya que puede dañar el rendimiento, pero en su caso tiene un gran número de neuronas de primera capa (1024) en relación con las características de entrada (35) por lo que puede ayudar.

  4. Aumente el tamaño del lote de 32 a 128. 128 es bastante estándar y potencialmente podría aumentar la estabilidad de la optimización.

 39
Author: 1'',
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-15 19:06:55

La respuesta por 1" es bastante buena. Sin embargo, todas las correcciones parecen solucionar el problema indirectamente en lugar de directamente. Yo recomendaría usar recorte de degradado, que simplemente recortará cualquier degradado que esté por encima de un cierto valor.

En Keras puedes usar clipnorm=1 (ver https://keras.io/optimizers / ) para simplemente recortar todos los degradados con una norma superior a 1.

 15
Author: pir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-26 23:07:01

Me enfrenté al mismo problema antes. Busco y encuentro esta pregunta y respuestas. Todos esos trucos mencionados anteriormente son importantes para entrenar una red neuronal profunda. Las probé todas, pero aún tengo a NAN.

También encuentro esta pregunta aquí. https://github.com/fchollet/keras/issues/2134 . Cité el resumen del autor como sigue:: "Quería señalar esto para que se archive para otros que puedan experimentar este problema en el futuro. Estaba corriendo en mi función de pérdida de repente devolver una nan después de ir tan lejos en el proceso de entrenamiento. He comprobado el relus, el optimizador, la función de pérdida, mi abandono, de conformidad con el relus, el tamaño de mi red y la forma de la red. Todavía estaba recibiendo una pérdida que finalmente se convirtió en una abuela y me estaba poniendo bastante frustrado.

Entonces me di cuenta. Puede que tenga una mala entrada. Resulta que una de las imágenes que estaba entregando a mi CNN (y haciendo normalización media en) no era más que 0. para este caso cuando resté la media y normalizé por la desviación de std y así terminé con una matriz ejemplar que no era más que la de nan. Una vez que fijé mi función de normalización, mi red ahora entrena perfectamente."

Estoy de acuerdo con el punto de vista anterior: la entrada es sensible para su red. En mi caso, utilizo el valor logarítmico de la estimación de densidad como entrada. El valor absoluto podría ser muy grande, lo que puede resultar en NaN después de varios pasos de gradientes. Creo que el la comprobación de entrada es necesaria. Primero, debe asegurarse de que la entrada no incluya -inf o inf, o algunos números extremadamente grandes en valor absoluto.

 12
Author: HenryZhao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-07 08:22:50

Me enfrenté a un problema muy similar, y así es como lo conseguí ejecutar.

Lo primero que puede intentar es cambiar su activación a LeakyReLU en lugar de usar Relu o Tanh. La razón es que a menudo, muchos de los nodos dentro de sus capas tienen una activación de cero, y backpropogation no actualiza los pesos de estos nodos porque su gradiente también es cero. Esto también se llama el problema ' ReLU moribundo '(puede leer más sobre él aquí: https://datascience.stackexchange.com/questions/5706/what-is-the-dying-relu-problem-in-neural-networks).

Para hacer esto, puede importar la activación de LeakyReLU usando:

from keras.layers.advanced_activations import LeakyReLU

E incorporarlo dentro de sus capas de esta manera:

model.add(Dense(800,input_shape=(num_inputs,)))
model.add(LeakyReLU(alpha=0.1))

Además, es posible que la característica de salida (la variable continua que está tratando de predecir) sea un conjunto de datos desequilibrado y tenga demasiados 0. Una forma de solucionar este problema es usar suavizado. Puedes hacer esto agregando 1 al numerador de todos sus valores en esta columna y dividiendo cada uno de los valores en esta columna por 1/(promedio de todos los valores en esta columna)

Esto esencialmente cambia todos los valores de 0 a un valor mayor que 0 (que todavía puede ser muy pequeño). Esto evita que la curva prediga 0s y minimice la pérdida (eventualmente convirtiéndola en NaN). Los valores más pequeños se ven más afectados que los valores más grandes, pero en general, el promedio del conjunto de datos sigue siendo el mismo.

 3
Author: Arnav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-18 23:30:08

Estaba recibiendo la pérdida como nan en la primera época, tan pronto como el entrenamiento comienza. Solución tan simple como quitar el nas de los datos de entrada funcionó para mí (df.dropna ())

Espero que esto ayude a alguien que se encuentre con un problema similar

 2
Author: Krithi07,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-31 11:38:00

Probé todas las sugerencias en esta página y muchas otras en vano. Estábamos importando archivos csv con pandas, luego usando keras Tokenizer con entrada de texto para crear vocabularios y matrices vectoriales de palabras. Después de notar algunos archivos CSV llevó a nan, mientras que otros trabajaron, de repente nos fijamos en la codificación de los archivos y nos dimos cuenta de que ascii archivos NO estaban trabajando con keras, dando lugar a nan pérdida y precisión de 0.0000e+00; sin embargo, utf-8 y utf-16 archivos estaban trabajando! Avance.

Si está realizando un análisis textual y obtiene una pérdida nan después de probar estas sugerencias, use file -i {input} (linux) o file -I {input} (osx) para descubrir su tipo de archivo. Si tiene ISO-8859-1 o us-ascii, intente convertir a utf-8 o utf-16le. No he probado esto último, pero me imagino que también funcionaría. Esperemos que esto ayude a alguien muy, muy frustrado!

 0
Author: Clay Coleman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-08 09:59:51