2016-10-20 42 views
5

Problem

Ich bin ein Tief Neural Network auf dem MNIST laufen, wo der Verlust wie folgt definiert:Wie man Nanverlust löst?

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, label))

Das Programm scheint korrekt zu funktionieren, bis ich einen nan Verlust im 10000+ bekommen Minibatch. Manchmal läuft das Programm bis zum Ende korrekt. Ich denke, tf.nn.softmax_cross_entropy_with_logits gibt mir diesen Fehler. Dies ist seltsam, weil der Code nur mul und add Operationen enthält.

Mögliche Lösung

Vielleicht kann ich verwenden:

if cost == "nan": 
    optimizer = an empty optimizer 
else: 
    ... 
    optimizer = real optimizer 

Aber ich kann nicht die Art von nan finden. Wie kann ich überprüfen, ob eine Variable nan ist oder nicht?

Wie sonst kann ich dieses Problem lösen?

+1

prüfen Umsetzung von „tf.add_check_numerics_ops“, die 'Assert' ops jedem Tensor ergänzt um sicherzustellen, dass es keine nans, Sie können so verwenden, was es für nanness überprüfen verwendet –

+0

Ich bin neu in tensorflow, wenn ich "tf.add_check_numerics_ops", es bringt mir einen Fehler "tensorflow.python.framework.errors.InvalidArgumentError: Alle Eingaben in das Knotenmodell/CheckNumerics_254 müssen vom selben Frame stammen." Habe ich es falsch benutzt? –

+0

Ich meinte nur, dass Sie in der Implementierung von 'add_check_numerics_ops' schauen können, um zu sehen, welche Op bestimmt, ob eine Variable NaN ist, und diese Op –

Antwort

1

Ich habe Ihren Code oder Daten nicht. Aber tf.nn.softmax_cross_entropy_with_logits sollte mit einer gültigen Wahrscheinlichkeitsverteilung stabil sein (mehr Info here). Ich nehme an, dass Ihre Daten diese Anforderung nicht erfüllen. Ein analoges Problem wurde ebenfalls diskutiert here. Welche würden Sie führen entweder zu:

  1. Ihre eigene softmax_cross_entropy_with_logits Funktion implementieren, z.B. versuchen (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. Aktualisieren Sie Ihre Daten, so dass sie eine gültige Wahrscheinlichkeitsverteilung hat

+0

Ich benutze das Standard-Mnist-Dataset, ich denke, seine Wahrscheinlichkeitsverteilung ist gültig. –

+0

Warum wird das Epsilon eher zu logits als zu softmax hinzugefügt? –

+0

'epsilon' wird den logits hinzugefügt, so dass die Summe der resultierenden softmax immernoch 1 ist, aber auch keine Nullen enthalten kann (diese ergeben NaN). Es ist sehr seltsam, dass Sie dieses Problem mit dem Standard-mnist-Dataset haben ... Können Sie überprüfen, was passiert, wenn Sie diese neue 'cross_entropy'-Funktion verwenden? Wenn das nicht funktioniert, müssen Sie sich wahrscheinlich die tatsächlichen Logits ansehen. – Fematich

7

Prüfen Sie Ihre Lernrate. Je größer Ihr Netzwerk, desto mehr Parameter müssen Sie lernen. Das bedeutet, dass Sie auch die Lernrate verringern müssen.

6

Der Grund, warum Sie NaN bekommen, ist höchstwahrscheinlich, dass Sie irgendwo in Ihrer Kostenfunktion oder softmax versuchen, ein Protokoll von Null zu nehmen, die keine Zahl ist. Um Ihre spezifische Frage zum Nachweis von NaN zu beantworten, verfügt Python jedoch über eine eingebaute Fähigkeit, im Mathematikmodul nach NaN zu suchen. Zum Beispiel:

import math 
val = float('nan') 
val 
if math.isnan(val): 
    print('Detected NaN') 
    import pdb; pdb.set_trace() # Break into debugger to look around 
+0

log (0) = -Unendlichkeit so weit ich weiß – Magnus

2

finde ich ein ähnliches Problem hier TensorFlow cross_entropy NaN problem

Dank der Autor user1111929

tf.nn.softmax_cross_entropy_with_logits => -tf.reduce_sum(y_*tf.log(y_conv)) 

der Berechnung der Quer Entropie tatsächlich eine schreckliche Art und Weise ist. In einigen Stichproben konnten bestimmte Klassen nach einiger Zeit mit Sicherheit ausgeschlossen werden, was zu y_conv = 0 für diese Stichprobe führte. Das ist normalerweise kein Problem, da Sie sich nicht für diese interessieren, aber in der Art, wie cross_entropy dort geschrieben ist, ergibt es 0 * log (0) für dieses spezielle Sample/Klasse. Daher das NaN.

Ersetzen es mit

cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv + 1e-10)) 

Oder

cross_entropy = -tf.reduce_sum(y_*tf.log(tf.clip_by_value(y_conv,1e-10,1.0))) 

Gelöst nan Problem.