簡體   English   中英

如何在 TensorFlow 中選擇交叉熵損失?

[英]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 ,並自己應用轉換(這只是更有效)。

Sigmoid 函數族

如前所述, sigmoid損失函數用於二元分類。 但是當類別獨立時,張量流函數更通用並且允許進行多標簽分類。 換句話說, tf.nn.sigmoid_cross_entropy_with_logits一次解決了N二元分類。

標簽必須是單熱編碼或可以包含軟類概率。

tf.losses.sigmoid_cross_entropy還允許設置批內權重,即使某些示例比其他示例更重要。 tf.nn.weighted_cross_entropy_with_logits允許設置類權重(記住,分類是二進制的),即使正誤差大於負誤差。 這在訓練數據不平衡時很有用。

Softmax 函數族

這些損失函數應該用於多項互斥分類,即從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 和標簽中(這是為什么這可能有用的討論)。

稀疏函數族

和上面普通的softmax一樣,這些損失函數應該用於多項互斥分類,即從N類中挑一個。 區別在於標簽編碼:類被指定為整數(類索引),而不是單熱向量。 顯然,這不允許軟類,但是當有數千或數百萬個類時,它可以節省一些內存。 但是,請注意logits參數仍然必須包含每個類的 logits,因此它至少消耗[batch_size, classes]內存。

像上面一樣, tf.losses版本有一個weights參數,它允許設置批量權重。

采樣的 softmax 函數族

這些函數為處理大量類提供了另一種選擇。 他們不是計算和比較精確的概率分布,而是從隨機樣本中計算損失估計。

的參數weightsbiases指定一個用於計算一個選擇的采樣的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)

雖然接受的答案包含的信息比所問的要多得多,但我覺得分享一些通用的拇指規則將使答案更加緊湊和直觀:

  • 只有一個真正的損失函數。 這是交叉熵(CE) 對於二元分類的特殊情況,這種損失稱為二元 CE (注意公式不變),對於非二元或多類情況,也稱為分類 CE (CCE) 稀疏函數是分類 CE 的一種特殊情況,其中預期值不是單熱編碼而是整數
  • 我們有softmax公式,它是多類場景的激活。 對於二元場景,相同的公式被賦予一個特殊的名稱——sigmoid激活
  • 因為在處理對數函數時有時會出現數值不穩定性(對於極值),TF 建議將激活層和損失層合並為一個函數。 這種組合函數在數值上更穩定。 TF 提供了這些組合函數,它們都以_with_logits為后綴

有了這個,讓我們現在處理一些情況。 假設有一個簡單的二元分類問題- 圖像中是否存在貓? 激活函數和損失函數的選擇是什么? 這將是一個 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.

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