python - ¿Cómo resolver la pérdida de Nan?
tensorflow (4)
Problema
Estoy ejecutando una red neuronal profunda en el MNIST donde la pérdida se define como sigue:
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, label))
El programa parece ejecutarse correctamente hasta que obtenga una pérdida nan en el minibercado 10000+. A veces, el programa se ejecuta correctamente hasta que finaliza. Creo que tf.nn.softmax_cross_entropy_with_logits
me está dando este error. Esto es extraño, porque el código solo contiene mul
y add
operaciones.
Solución posible
Tal vez puedo usar:
if cost == "nan":
optimizer = an empty optimizer
else:
...
optimizer = real optimizer
Pero no puedo encontrar el tipo de nan
. ¿Cómo puedo verificar una variable es nan
o no?
¿De qué otra manera puedo resolver este problema?
Verifica tu tasa de aprendizaje. Cuanto mayor sea tu red, más parámetros para aprender. Eso significa que también necesita disminuir la tasa de aprendizaje.
No tengo tu código o datos. Pero tf.nn.softmax_cross_entropy_with_logits
debería ser estable con una distribución de probabilidad válida (más información aquí ). Supongo que sus datos no cumplen este requisito. Un problema análogo también se discutió aquí . Lo cual lo llevaría a cualquiera de las siguientes:
Implemente su propia función
softmax_cross_entropy_with_logits
, por ejemplo, try ( fuente ):epsilon = tf.constant(value=0.00001, shape=shape) logits = logits + epsilon softmax = tf.nn.softmax(logits) cross_entropy = -tf.reduce_sum(labels * tf.log(softmax), reduction_indices=[1])
Actualice sus datos para que tenga una distribución de probabilidad válida
La razón por la que obtienes los NaN es muy probable que en algún lugar de tu función de costos o softmax intentes tomar un registro de cero, que no es un número. Pero para responder a su pregunta específica sobre la detección de NaN, Python tiene una capacidad incorporada para probar NaN en el módulo matemático. Por ejemplo:
import math
val = float(''nan'')
val
if math.isnan(val):
print(''Detected NaN'')
import pdb; pdb.set_trace() # Break into debugger to look around
Aquí encuentro un problema similar TensorFlow cross_entropy NaN problem
Gracias al autor user1111929
tf.nn.softmax_cross_entropy_with_logits => -tf.reduce_sum(y_*tf.log(y_conv))
es en realidad una forma horrible de calcular la entropía cruzada. En algunas muestras, ciertas clases podrían excluirse con certeza después de un tiempo, lo que da como resultado y_conv = 0 para esa muestra. Normalmente no es un problema ya que no estás interesado en eso, pero en la forma en que cross_entropy está escrito allí, arroja 0 * log (0) para esa muestra / clase en particular. De ahí el NaN.
Reemplazándolo con
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv + 1e-10))
O
cross_entropy = -tf.reduce_sum(y_*tf.log(tf.clip_by_value(y_conv,1e-10,1.0)))
Resolvió el problema de nan.