[英]How to choose cross-entropy loss in TensorFlow?
分類問題,例如邏輯回歸或多項邏輯回歸,可以優化交叉熵損失。 通常情況下,交叉熵層跟在softmax層之后,產生概率分布。
在 tensorflow 中,至少有十幾種不同的交叉熵損失函數:
tf.losses.softmax_cross_entropy
tf.losses.sparse_softmax_cross_entropy
tf.losses.sigmoid_cross_entropy
tf.contrib.losses.softmax_cross_entropy
tf.contrib.losses.sigmoid_cross_entropy
tf.nn.softmax_cross_entropy_with_logits
tf.nn.sigmoid_cross_entropy_with_logits
哪一個只適用於二元分類,哪一個適用於多類問題? 什么時候應該使用sigmoid
而不是softmax
? sparse
函數與其他函數有何不同,為什么只有softmax
?
相關(更面向數學)討論: Keras 和 TensorFlow 中所有這些交叉熵損失之間有什么區別? .
在函數意義上, sigmoid 是 softmax 函數 的部分情況,當類數等於 2 時。它們都執行相同的操作:將 logits(見下文)轉換為概率。
在簡單的二元分類中,兩者之間沒有太大區別,但是在多項分類的情況下,sigmoid 允許處理非排他標簽(又名multi-labels ),而 softmax 處理排他類(見下文)。
logit (也稱為分數)是在計算概率之前與 class 關聯的原始未縮放值。 就神經網絡架構而言,這意味着 logit 是密集(全連接)層的輸出。
Tensorflow 命名有點奇怪:下面的所有函數都接受 logits,而不是 probabilities ,並自己應用轉換(這只是更有效)。
tf.nn.sigmoid_cross_entropy_with_logits
tf.nn.weighted_cross_entropy_with_logits
tf.losses.sigmoid_cross_entropy
tf.contrib.losses.sigmoid_cross_entropy
(已棄用) 如前所述, sigmoid
損失函數用於二元分類。 但是當類別獨立時,張量流函數更通用並且允許進行多標簽分類。 換句話說, tf.nn.sigmoid_cross_entropy_with_logits
一次解決了N
二元分類。
標簽必須是單熱編碼或可以包含軟類概率。
tf.losses.sigmoid_cross_entropy
還允許設置批內權重,即使某些示例比其他示例更重要。 tf.nn.weighted_cross_entropy_with_logits
允許設置類權重(記住,分類是二進制的),即使正誤差大於負誤差。 這在訓練數據不平衡時很有用。
tf.nn.softmax_cross_entropy_with_logits
(在 1.5 中已棄用)tf.nn.softmax_cross_entropy_with_logits_v2
tf.losses.softmax_cross_entropy
tf.contrib.losses.softmax_cross_entropy
(已棄用) 這些損失函數應該用於多項互斥分類,即從N
類中挑選一個。 當N = 2
時也適用。
標簽必須是單熱編碼或可以包含軟類概率:特定示例可以 50% 的概率屬於 A 類,50% 的概率屬於 B 類。 請注意,嚴格來說,這並不意味着它屬於兩個類別,但可以這樣解釋概率。
就像在sigmoid
家族中一樣, tf.losses.softmax_cross_entropy
允許設置批內權重,即讓一些例子比其他例子更重要。 據我所知,從 tensorflow 1.3 開始,沒有設置類權重的內置方法。
[UPD]在 tensorflow 1.5 中, 引入了v2
版本並且不推薦使用原始的softmax_cross_entropy_with_logits
損失。 它們之間的唯一區別是,在較新的版本中,反向傳播發生在 logits 和標簽中(這是為什么這可能有用的討論)。
tf.nn.sparse_softmax_cross_entropy_with_logits
tf.losses.sparse_softmax_cross_entropy
tf.contrib.losses.sparse_softmax_cross_entropy
(已棄用) 和上面普通的softmax
一樣,這些損失函數應該用於多項互斥分類,即從N
類中挑一個。 區別在於標簽編碼:類被指定為整數(類索引),而不是單熱向量。 顯然,這不允許軟類,但是當有數千或數百萬個類時,它可以節省一些內存。 但是,請注意logits
參數仍然必須包含每個類的 logits,因此它至少消耗[batch_size, classes]
內存。
像上面一樣, tf.losses
版本有一個weights
參數,它允許設置批量權重。
這些函數為處理大量類提供了另一種選擇。 他們不是計算和比較精確的概率分布,而是從隨機樣本中計算損失估計。
的參數weights
和biases
指定一個用於計算一個選擇的采樣的logits單獨的完全連接的層。
像上面一樣, labels
不是單熱編碼,而是具有形狀[batch_size, num_true]
。
采樣函數僅適用於訓練。 在測試時,建議使用標准的softmax
損失(稀疏或單熱)來獲得實際分布。
另一種替代損失是tf.nn.nce_loss
,它執行噪聲對比估計(如果您有興趣,請參閱此非常詳細的討論)。 我已將此函數包含在 softmax 系列中,因為 NCE 保證在極限內逼近 softmax。
但是,對於 1.5 版,必須改用softmax_cross_entropy_with_logits_v2
,同時將其參數與argument key=...
,例如
softmax_cross_entropy_with_logits_v2(_sentinel=None, labels=y,
logits=my_prediction, dim=-1, name=None)
雖然接受的答案包含的信息比所問的要多得多,但我覺得分享一些通用的拇指規則將使答案更加緊湊和直觀:
有了這個,讓我們現在處理一些情況。 假設有一個簡單的二元分類問題- 圖像中是否存在貓? 激活函數和損失函數的選擇是什么? 這將是一個 sigmoid 激活和一個(二進制)CE。 所以可以使用sigmoid_cross_entropy或更優選sigmoid_cross_entropy_with_logits 。 后者結合了激活函數和損失函數,應該是數值穩定的。
多類分類怎么樣。 假設我們想知道圖像中是否存在貓、狗或驢。 激活函數和損失函數的選擇是什么? 這將是一個 softmax 激活和一個(分類)CE。 所以可以使用softmax_cross_entropy或更優選softmax_cross_entropy_with_logits 。 我們假設預期值是單熱編碼(100 或 010 或 001)。 如果(出於某種奇怪的原因),情況並非如此,並且預期值為整數(1 或 2 或 3),則您可以使用上述函數的“稀疏”對應項。
可能還有第三種情況。 我們可以有一個多標簽分類。 因此,同一圖像中可能有一只狗和一只貓。 我們如何處理? 這里的技巧是將這種情況視為多重二元分類問題 - 基本上是貓或沒有貓/狗或沒有狗和驢或沒有驢。 找出這 3 個(二元分類)中每一個的損失,然后將它們相加。 所以基本上這歸結為使用sigmoid_cross_entropy_with_logits損失。
這回答了您提出的 3 個具體問題。 上面共享的功能是所有需要的。 您可以忽略已棄用且不應使用的 tf.contrib 系列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.