2016-09-19 2 views
4

Ich erhalte NaN, wenn ich die sparse_softmax_cross_entropy_with_logits Verlustfunktion in tensorflow zu nutzen versuchen. Ich habe ein einfaches Netzwerk, so etwas wie:NaN von sparse_softmax_cross_entropy_with_logits in Tensorflow

layer = tf.nn.relu(tf.matmul(inputs, W1) + b1) 
layer = tf.nn.relu(tf.matmul(inputs, W2) + b2) 
logits = tf.matmul(inputs, W3) + b3 
loss = tf.sparse_softmax_cross_entropy_with_logits(logits, labels) 

Ich habe viele Klassen (~ 10000), so dass ich denke ich bin immer NaN weil die logit in mindestens eine meiner Beispiele korrigieren Klasse entsprechend Null gekürzt wurde . Gibt es eine Möglichkeit, dies zu vermeiden?

Antwort

6

Es stellt sich tatsächlich heraus, dass einige meiner Etiketten außer Reichweite waren (zum Beispiel ein Etikett von 14000, wenn meine Logits Matrix nur 150 x 10000). Es stellt sich heraus, dass dies eher zu einem NaN als zu einem Fehler führt.

+0

Können Sie erklären, was Sie unter "Etiketten außerhalb der Reichweite" verstehen? Ich denke, für jede Probe sind die Etiketten eine Vektorlänge, die dem Logit entspricht. Ich versuchte 'a = tf.constant (np.array ([[200,1, 20000,3, .5, .9], [1,0, 10000.0, 10,0, 10,0]])) l = tf.constant (np.array ([ [1, 1, 1, 1, 1], [1, 0, 0]])) s.run (tf.nn.softmax_cross_entropy_with_logits (Logits = a, Etikett = l)) '. Wenn die Dimension nicht übereinstimmt, würde sie sich über die Dimension beschweren; und wenn die Summe der Wahrscheinlichkeit> 1 ist, verursacht sie keinen Fehler oder "NaN". Was meinst du mit "ein Label von 14000"? –

+0

Der Unterschied ist, dass ich 'tf verwendet habe.sparse_softmax_cross_entropy_with_logits' also sind die Eingaben der Index des Labels. Wenn ich außerhalb des Bereichs sage, meine ich, dass ich z. B. den Index 23 geliefert habe, während für jedes Beispiel nur 7 logits für die Funktion bereitgestellt wurden. –

3

tf.sparse_softmax_cross_entropy_with_logits behandelt den Fall von log(0) für Sie, Sie müssen sich nicht darum kümmern.

Normalerweise ist ein NaN aufgrund einer hohen Lernrate des Optimierungsalgorithmus. Versuchen Sie es zu senken, bis NaN Fehler verschwinden und der Verlust beginnt

0

Der NaN Fehler zu verringern, wahrscheinlich tritt auf, wenn eine der softmaxed Logits auf 0 abgeschnitten wird, wie Sie gesagt haben, und dann führt er log (0) zu berechnen, die Kreuz-Entropie-Fehler.

Um dies zu vermeiden, wie es in this other answer vorgeschlagen wird, könnten Sie die Werte des Softmax-Ausgangs so abschneiden, dass sie niemals Null sind.

out = tf.clip_by_value(out,1e-10,100.0) 

Oder Sie könnten eine kleine Konstante in den mit Nullen zu vermeiden:

out = out + 1e-10 

Das Problem damit ist, dass die softmax Funktion auf dem Logits intern von sparse_softmax_cross_entropy_with_logits() angelegt wird, so können Sie nicht ihr Verhalten ändern .

Um dies zu umgehen, den Cross Entropy Fehler selbst codieren und die Konstante 1e-10 zum Ausgang des Softmax hinzufügen, nicht zu den Logits.

loss = -tf.reduce_sum(labels*tf.log(tf.nn.softmax(logits) + 1e-10)) 

Beachten Sie, dass mit der sparse_softmax_cross_entropy_with_logits() Funktion der Variable labels der numerische Wert des Etiketts war, aber wenn man den Quer Entropieverlust selbst implementieren, müssen labels die One-Hot-Codierung dieser numerischen Etiketten sein.

Update: Ich habe die Antwort dank dem Kommentar von @mdaoust korrigiert. Wie er sagte, sind die Nullen nur relevant, nachdem die Softmax-Funktion auf die Logits angewendet wurde, nicht vorher.

+1

Ein Logit von Null ist nichts besonderes. Logits können negativ sein. Das Clippen auf [-100,100] wäre vernünftiger, könnte aber das Problem nicht lösen. – mdaoust

+1

Sie haben Recht, es zählt nur, wenn der Softmax-Ausgang Null ist, nicht wenn der Logit Null ist. Vielen Dank! – gcucurull

Verwandte Themen