24

Uruchomiłem TensorFlow i zdarzyło mi się, że mam coś na NaN. Chciałbym wiedzieć, co to jest, ale nie wiem, jak to zrobić. Głównym problemem jest to, że w "normalnym" programie proceduralnym napisałbym instrukcję print tuż przed wykonaniem operacji. Problem z TensorFlow polega na tym, że nie mogę tego zrobić, ponieważ najpierw deklaruję (lub definiuję) wykres, więc dodawanie instrukcji drukowania do definicji wykresu nie pomaga. Czy istnieją jakieś zasady, porady, heurystyki, wszystko, co może być przyczyną NaN?W jaki sposób jeden debuguje wartości NaN w TensorFlow?


W tym przypadku wiem więcej właśnie linia patrzeć bo mam następujące:

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) 

gdy linia ta jest obecna mam to, że zwraca NaN deklarowanego przez moich pisarzy podsumowania . Dlaczego to? Czy istnieje sposób, aby przynajmniej zbadać, jaką wartość ma Z, po kwadratowej podstawie?


Na konkretnym przykładzie napisałem, próbowałem tf.Print(0,Z) ale bez powodzenia to wydrukowane nic. Jak w:

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) 

I rzeczywiście nie rozumieją, co tf.Print jest przypuszczać, aby zrobić. Dlaczego potrzebuje dwóch argumentów? Jeśli chcę wydrukować 1 tensor, dlaczego muszę podać 2? Wydaje mi się dziwne.


Szukałem w funkcji tf.add_check_numerics_ops() ale nie mówi, jak go używać (plus docs wydają się nie być bardzo pomocne). Czy ktoś wie, jak tego użyć?


Ponieważ komentarze dotyczące danych mogą być złe, używam standardowego MNISTU. Jednak obliczam ilość, która jest dodatnia (odległość eucledian w parze), a następnie kwadratowo ją kroi. W związku z tym nie widzę, w jaki sposób dane byłyby konkretnie problemem.

Odpowiedz

5

Wygląda na to, że możesz wywołać to po ukończeniu tworzenia wykresu.

check = tf.add_check_numerics_ops()

myślę, że to doda czek dla wszystkich operacji zmiennoprzecinkowych. Następnie w funkcji uruchamiania sesji można dodać operację sprawdzania.

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

+1

FYI to zdobywa pewne ops kiedy są używane optymalizujące - https://github.com/tensorflow/tensorflow/issues/2288 –

12

Istnieje kilka powodów, dla których można uzyskać Nan-wynik, często to właśnie z powodu zbyt wysokich szybkością uczenia się, ale wiele innych powodów są możliwe jak na przykład uszkodzone dane w wejściowym-kolejki lub dziennik obliczeń 0.

W każdym razie debugowanie z opisem opisanym przez drukowanie nie może być wykonane za pomocą prostego wydruku (ponieważ spowodowałoby to tylko drukowanie informacji tensorowej na wykresie i nie drukowanie żadnych rzeczywistych wartości).

Jednakże, jeśli użyjesz tf.print jako op w budowaniu wykresu (tf.print), to po uruchomieniu wykresu otrzymasz rzeczywiste wartości wydrukowane (i to jest dobre ćwiczenie, aby obejrzeć te wartości do debugowania i zrozumieć zachowanie twojej sieci).

Używasz jednak instrukcji print nie do końca w poprawny sposób.To jest op, więc musisz przekazać go tensorowi i zażądać tensora wyniku, który musisz później wykonać na wykresie wykonawczym. W przeciwnym razie operacja nie zostanie wykonana i nie nastąpi drukowanie. Wypróbuj to:

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

Dlaczego trzeba by przejść pierwszy z Jeśli drugi Z to są dane? W istocie API dla 'tf.Print' jest mylące. Dlaczego potrzebujemy dwóch argumentów wejściowych do wydrukowania jednej rzeczy? – Pinocchio

+0

Lista tensorów [Z] jest drukowana, gdy oceniany jest pierwszy tensor Z. Czasami można wydrukować różne rzeczy. – holdenlee

+0

Oto mały wycinek, który uważam za przydatny dla tensora 'x': ' DEBUGGING = False' 'x = x jeśli nie DEBUGGING else tf.Print (x, [x], 'Wartość x:')' –

1

Przede wszystkim musisz poprawnie sprawdzić dane wejściowe. W większości przypadków jest to powód. Ale nie zawsze, oczywiście.

Zwykle używam Tensorboard, aby zobaczyć, co dzieje się podczas treningu. Więc można zobaczyć wartości na każdym kroku z

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) 

także można po prostu eval i wydrukować bieżącą wartość:

print(sess.run(Z)) 
+0

Problem polega na tym, że otrzymuje wartości NaN, więc pisarz podsumowujący faktycznie opuszcza mój skrypt, więc nie jestem w stanie go zobaczyć. Czy sugerujesz zamiast tego zapisać wartość przed operacją, która może być przyczyną NaN? (prawdopodobnie przed sqrt). Jest to również część sieci, więc nazywam sess.run na niektórych operacjach pociągu. Nie mogę po prostu sess.run Z niestety (lub nie wiem jak). – Pinocchio

+0

Możesz uruchomić niektóre operacje przez 'op1_answer, op2_answer, opN_answer = sess.run ([op1, op2, opN], feed_dict = {etc ..})' –

0

Odpowiedzi są już dobre. Jeśli szukasz ogólnych technik debugowania (tj. Nie są one specyficzne dla Tensorflow), ten dokument jest bardzo pomocny: http://russellsstewart.com/notes/0.html

+1

To nie odpowiada na pytanie OP – mhasan

2

Począwszy od wersji 0.12, TensorFlow jest dostarczany z wbudowanym debuggerem o nazwie tfdbg. Optymalizuje przepływ pracy przy debugowaniu tego typu błędnych liczbowo problemów (takich jak inf i nan). Dokumentacja znajduje się pod adresem: https://www.tensorflow.org/programmers_guide/debugger

0

Zauważyłem, że dużo trudniej jest określić, gdzie mogą nans i infy, niż naprawić błąd. Jako uzupełniające do odpowiedzi @ Scal za, chciałbym dodać kilka punktów tutaj:

Moduł debug można przywożone przez:

from tensorflow.python import debug as tf_debug 

jest o wiele lepiej niż jakikolwiek druku lub dochodzić.

Można tylko dodać funkcję debugowania zmieniając opakowanie ty sesję:

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

I będziesz skłonić interfejs wiersza poleceń, a następnie wpisać: run -f has_inf_or_nan i lt -f has_inf_or_nan znaleźć gdzie nans lub infs są. Pierwszy to pierwsze miejsce katastrofy. Za pomocą nazwy zmiennej można śledzić pochodzenie w kodzie.

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