[英]How can I implement a weighted cross entropy loss in tensorflow using sparse_softmax_cross_entropy_with_logits
[英]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()
函數時,變量labels
是labels
的數值,但如果您自己實現交叉熵損失,則labels
必須是這些數字標簽的單熱編碼。
更新:由於@mdaoust的評論,我已經更正了答案。 正如他所說的那樣,只有在將softmax函數應用於logits后才能使用零,而不是之前。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.