J'exécute un réseau neuronal profond sur le MNIST où la perte définie comme suit:
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, label))
Le programme semble fonctionner correctement jusqu'à ce que j'obtienne une perte de nan dans le 10000+ e mini-lot. Parfois, le programme s'exécute correctement jusqu'à la fin. Je pense tf.nn.softmax_cross_entropy_with_logits
me donne cette erreur. C'est étrange, car le code contient juste les opérations mul
et add
.
Je peux peut-être utiliser:
if cost == "nan":
optimizer = an empty optimizer
else:
...
optimizer = real optimizer
Mais je ne trouve pas le type de nan
. Comment puis-je vérifier qu'une variable est nan
ou non?
Sinon, comment puis-je résoudre ce problème?
Vérifiez votre taux d'apprentissage. Plus votre réseau est grand, plus il y a de paramètres à apprendre. Cela signifie que vous devez également réduire le taux d'apprentissage.
La raison pour laquelle vous obtenez des NaN est très probablement que quelque part dans votre fonction de coût ou softmax, vous essayez de prendre un journal de zéro, ce qui n'est pas un nombre. Mais pour répondre à votre question spécifique sur la détection de NaN, Python a une capacité intégrée pour tester NaN dans le module mathématique. Par exemple:
import math
val = float('nan')
val
if math.isnan(val):
print('Detected NaN')
import pdb; pdb.set_trace() # Break into debugger to look around
Je trouve un problème similaire ici problème NaN TensorFlow cross_entropy
Merci à l'auteur user1111929
tf.nn.softmax_cross_entropy_with_logits => -tf.reduce_sum(y_*tf.log(y_conv))
est en fait une horrible façon de calculer l'entropie croisée. Dans certains échantillons, certaines classes pourraient être exclues avec certitude après un certain temps, ce qui donnerait y_conv = 0 pour cet échantillon. Ce n'est normalement pas un problème car vous n'êtes pas intéressé par ceux-ci, mais dans la façon dont cross_entropy y est écrit, il donne 0 * log (0) pour cet échantillon/classe particulier. D'où le NaN.
Le remplacer par
cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv + 1e-10))
Ou
cross_entropy = -tf.reduce_sum(y_*tf.log(tf.clip_by_value(y_conv,1e-10,1.0)))
Problème nan résolu.
Je n'ai pas votre code ou vos données. Mais tf.nn.softmax_cross_entropy_with_logits
devrait être stable avec une distribution de probabilité valide (plus d'informations ici ). Je suppose que vos données ne répondent pas à cette exigence. Un problème analogue a également été discuté ici . Ce qui vous amènerait à:
Implémentez votre propre softmax_cross_entropy_with_logits
fonction, par ex. essayez ( source ):
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])
Mettez à jour vos données afin qu'elles aient une distribution de probabilité valide