簡體   English   中英

來自Tensorflow中的sparse_softmax_cross_entropy_with_logits的NaN

[英]NaN from sparse_softmax_cross_entropy_with_logits in Tensorflow

當我嘗試在tensorflow中使用sparse_softmax_cross_entropy_with_logits丟失函數時,我得到NaN。 我有一個簡單的網絡,如:

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

我有很多類(~10000),所以我想我得到了NaN,因為至少有一個示例中對應於正確類的logit被截斷為零。 有辦法避免這種情況嗎?

事實證明我的一些標簽超出了范圍(例如標簽為14000,當我的logits矩陣只有150 x 10000時)。 事實證明,這導致了NaN而不是錯誤。

tf.sparse_softmax_cross_entropy_with_logits為您處理log(0)的情況,您不必擔心它。

通常, NaN歸因於優化算法的高學習率。 嘗試降低它直到NaN錯誤消失並且損失開始減少

如上所述,當其中一個softmaxed logits被截斷為0時,可能會發生NaN錯誤,然后執行log(0)來計算交叉熵錯誤。

為了避免這種情況,正如在其他答案中建議的那樣,您可以剪切softmax輸出的值,使它們永遠不為零。

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

或者你可以添加一個小常量來避免零:

out = out + 1e-10

它的問題在於softmax函數通過sparse_softmax_cross_entropy_with_logits()在內部應用於logits,因此您無法更改其行為。

為了克服這個問題,自己編碼交叉熵誤差並將常數1e-10添加到softmax的輸出,而不是logits。

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

請注意,使用sparse_softmax_cross_entropy_with_logits()函數時,變量labelslabels的數值,但如果您自己實現交叉熵損失,則labels必須是這些數字標簽的單熱編碼。

更新:由於@mdaoust的評論,我已經更正了答案。 正如他所說的那樣,只有在將softmax函數應用於logits后才能使用零,而不是之前。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM