24

Ich lief TensorFlow und ich habe zufällig etwas, das ein NaN ergibt. Ich würde gerne wissen, was es ist, aber ich weiß nicht, wie ich das machen soll. Das Hauptproblem ist, dass ich in einem "normalen" prozeduralen Programm nur eine Druckanweisung schreiben würde, kurz bevor die Operation ausgeführt wird. Das Problem mit TensorFlow ist, dass ich das nicht tun kann, weil ich zuerst das Diagramm deklariere (oder definiere), also hilft das Hinzufügen von Druckanweisungen zur Diagrammdefinition nicht. Gibt es irgendwelche Regeln, Ratschläge, Heuristiken, irgendetwas, um herauszufinden, was das NaN verursachen könnte?Wie kann man NaN-Werte in TensorFlow debuggen?


In diesem Fall habe ich mehr genau wissen, was Linie zu sehen, weil ich habe folgendes:

Delta_tilde = 2.0*tf.matmul(x,W) - tf.add(WW, XX) #note this quantity should always be positive because its pair-wise euclidian distance 
Z = tf.sqrt(Delta_tilde) 
Z = Transform(Z) # potentially some transform, currently I have it to return Z for debugging (the identity) 
Z = tf.pow(Z, 2.0) 
A = tf.exp(Z) 

wenn diese Zeile vorhanden ist, habe ich es, dass es NaN zurück, wie durch meine Zusammenfassung Schriftsteller erklärt . Warum ist das? Gibt es eine Möglichkeit, zumindest zu erforschen, welchen Wert Z hat, nachdem er quadratisch wurzelt?


Für das spezielle Beispiel, das ich geschrieben habe ich versucht, tf.Print(0,Z) aber ohne Erfolg es gedruckt nichts. Wie in:

Delta_tilde = 2.0*tf.matmul(x,W) - tf.add(WW, XX) #note this quantity should always be positive because its pair-wise euclidian distance 
Z = tf.sqrt(Delta_tilde) 
tf.Print(0,[Z]) # <-------- TF PRINT STATMENT 
Z = Transform(Z) # potentially some transform, currently I have it to return Z for debugging (the identity) 
Z = tf.pow(Z, 2.0) 
A = tf.exp(Z) 

Ich verstehe wirklich nicht, was zu tun tf.Print annehmen wird. Warum braucht es zwei Argumente? Wenn ich 1 Tensor drucken möchte, warum müsste ich 2 übergeben? Es scheint mir bizarr.


ich in der Funktion tf.add_check_numerics_ops() war auf der Suche, aber es sagt nicht, wie es zu benutzen (plus die Docs scheinen nicht super hilfreich zu sein). Weiß jemand wie man das benutzt?

Da ich Kommentare hatte, die die Daten möglicherweise schlecht adressieren, verwende ich Standard-MNIST. Ich berechne jedoch eine Menge, die positiv ist (paarweise euklidische Entfernung) und dann Quadratwurzel. So würde ich nicht sehen, wie die Daten speziell ein Problem sein würden.

Antwort

5

Es sieht so aus, als könnten Sie es aufrufen, nachdem Sie das Diagramm erstellt haben.

check = tf.add_check_numerics_ops()

Ich denke, das die Prüfung für alle Gleitkommaoperationen hinzufügen. Dann können Sie in der Funktion "Sitzungen ausführen" die Prüfoperation hinzufügen.

sess.run([check, ...])

+1

FYI diese vermisst einige ops wenn Optimizern verwendet - https://github.com/tensorflow/tensorflow/issues/2288 –

12

Es gibt ein paar Gründe, warum Sie ein NaN-Ergebnis zu bekommen, oft ist es wegen zu hoher Lernrate, aber viele andere Gründe sind möglich, wie zum Beispiel beschädigte Daten in Ihrer Eingabe-Warteschlange oder ein Protokoll von 0 Berechnung.

Wie auch immer, das Debuggen mit einem Ausdruck, wie Sie ihn beschrieben haben, kann nicht durch einen einfachen Druck erfolgen (da dies nur zum Ausdruck der Tensor-Informationen im Graphen führen und keine tatsächlichen Werte drucken würde).

Wenn Sie jedoch tf.print als Op-Datei verwenden (tf.print), dann erhalten Sie, wenn der Graph ausgeführt wird, die tatsächlichen Werte (und es ist eine gute Übung, diese Werte zu debuggen und zu verstehen) das Verhalten deines Netzes).

Sie verwenden die Print-Anweisung jedoch nicht vollständig in der richtigen Weise.Dies ist ein Op, also müssen Sie ihm einen Tensor übergeben und einen Ergebnistor anfordern, mit dem Sie später im ausführenden Graphen arbeiten müssen. Andernfalls wird der Op nicht ausgeführt und es erfolgt kein Druckvorgang. Versuchen Sie dies:

Z = tf.sqrt(Delta_tilde) 
Z = tf.Print(Z,[Z], message="my Z-values:") # <-------- TF PRINT STATMENT 
Z = Transform(Z) # potentially some transform, currently I have it to return Z for debugging (the identity) 
Z = tf.pow(Z, 2.0) 
+3

Warum macht man das erste Z, wenn die zweite Z passieren müssen sind die Daten? Im Wesentlichen ist die API für "tf.Print" verwirrend. Warum brauchen wir zwei Eingabeargumente, um eine einzige Sache zu drucken? – Pinocchio

+0

Die Liste der Tensoren [Z] wird gedruckt, wenn der erste Tensor Z ausgewertet wird. Manchmal möchte man verschiedene Dinge ausdrucken. – holdenlee

+0

Hier ist ein kleiner Ausschnitt, den ich für einige Tensor 'x' nützlich finde: ' DEBUGGING = False' 'x = x wenn nicht DEBUGGING sonst tf.Print (x, [x], 'Wert von x:')' –

1

Zunächst müssen Sie überprüfen Sie die Daten richtig eingeben. In den meisten Fällen ist dies der Grund. Aber natürlich nicht immer.

Normalerweise verwende ich Tensorboard, um zu sehen, was während des Trainings passiert. So können Sie die Werte auf jedem Schritt sehen mit

Z = tf.pow(Z, 2.0)  
summary_z = tf.scalar_summary('z', Z) 
#etc.. 
summary_merge = tf.merge_all_summaries() 
#on each desired step save: 
    summary_str = sess.run(summary_merge) 
    summary_writer.add_summary(summary_str, i) 

Sie können auch einfach eval und den aktuellen Wert drucken:

print(sess.run(Z)) 
+0

Das Problem ist, dass es NaN-Werte bekommen, so dass ich die Zusammenfassung Verfasser tatsächlich mein Skript beendet, so dass ich es nicht sehen kann. Schlägst du vor, stattdessen den Wert vor dem Op zu schreiben, der das NaN verursachen könnte? (wahrscheinlich vor dem sqrt) Auch das ist Teil eines Netzwerkes, also rufe ich sess.run auf irgendeinen Zug auf. Ich kann nicht einfach sass.run Z (oder ich weiß nicht wie). – Pinocchio

+0

Sie können einige Ops von ausführen 'op1_answer, op2_answer, opN_answer = sess.run ([op1, op2, opN], feed_dict = {etc ..})' –

0

Die Antworten sind schon gut. Wenn Sie nach allgemeinen Debugging-Techniken suchen (d. H. Nicht spezifisch für Tensorflow), ist dieses Dokument sehr hilfreich: http://russellsstewart.com/notes/0.html

+1

Dies beantwortet nicht die OP-Frage – mhasan

2

Ab Version 0.12 wird TensorFlow mit einem integrierten Debugger namens tfdbg ausgeliefert. Es optimiert den Arbeitsablauf des Debuggens dieser Art von Fehlern mit schlechter numerischer Wertigkeit (wie inf und nan). Die Dokumentation befindet sich unter:

0

Früher fand ich es viel schwieriger zu bestimmen, wo die Nans und infs auftreten können, als den Fehler zu beheben. Als Ergänzung zu der Antwort @ scai, würde ich einige Punkte möchte hier hinzufügen:

Die Debug-Modul können Sie importiert von:

from tensorflow.python import debug as tf_debug 

ist viel besser als jeder Druck oder geltend zu machen.

Sie können einfach, indem Sie Ihre Wrapper Sie Sitzung durch die Debug-Funktion hinzufügen:

sess = tf_debug.LocalCLIDebugWrapperSession(sess) 
sess.add_tensor_filter("has_inf_or_nan", tf_debug.has_inf_or_nan) 

Und Sie werden eine Befehlszeilenschnittstelle veranlassen, dann geben Sie: run -f has_inf_or_nan und lt -f has_inf_or_nan wo die nans zu finden oder infs sind. Der erste ist der erste Ort, an dem die Katastrophe eintritt. Durch den Variablennamen können Sie den Ursprung in Ihrem Code verfolgen.

Referenz: https://developers.googleblog.com/2017/02/debug-tensorflow-models-with-tfdbg.html

Verwandte Themen