web-dev-qa-db-fra.com

Comment résoudre la perte de nan?

Problème

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.

Solution possible

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?

9
Swind D.C. Xu

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.

9
Ilyakom

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
7
Greg K

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.

5
demianzhang

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 à:

  1. 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])
    
  2. Mettez à jour vos données afin qu'elles aient une distribution de probabilité valide

2
Fematich