[tensorflow]如何處理樣本不均衡?

樣本不均衡的主要處理方法有:

1、上採樣

2、下采樣

3、構造少量樣本

4、修改loss函數


其中修改loss函數也有不同的方法,包括交叉熵、Focal Loss等,本文主要講TensorFlow中交叉熵損失函數如何實現樣本不均衡的處理。這是一種比較常見的損失函數。


TensorFlow中有四種交叉熵的實現,分別如下:

  • tf.nn.sigmoid_cross_entropy_with_logits
  • tf.nn.softmax_cross_entropy_with_logits
  • tf.nn.sparse_softmax_cross_entropy_with_logits
  • tf.nn.weighted_cross_entropy_with_logits

  • [tensorflow]如何處理樣本不均衡?


    注意這四個函數使用的情況是不同的,下面我會分別將這幾個函數的原理和作用場景


    tf.nn.sigmoid_cross_entropy_with_logits和tf.nn.weighted_cross_entropy_with_logits是直接通過logits進行sigmoid,然後輸出每個類別的概率。一般用在多標籤分類,如一張圖片可以同時是狗和貓。


    比如 上面的例子,三分類時,模型的 logist 為 [3, 3, 1]。輸入標籤為[1, 1, 0],表示這張圖片既屬於貓也屬於狗,tf.nn.sigmoid_cross_entropy_with_logits的計算公式為:

    <code>z * -log(sigmoid(x)) + (1 - z) * -log(1 - sigmoid(x))/<code>

    根據上面的例子,將logist每一維度進行sigmoid為[0. 6, 0.6, 0.2] ,然後再和[1, 1, 0]相乘。

    然後加上[0, 4, 0.4, 0.8] 和 [0, 0, 1](1-z的值)相乘結果。

    本質上這是把每個label的維度都當做一個二分類,然後把所有的二分類的的交叉熵損失函數相加。


    tf.nn.weighted_cross_entropy_with_logits的作用是對每個二分類的標籤,給正樣本賦更高的權重,從而處理樣本不均衡問題。


    tf.nn.sigmoid_cross_entropy_with_logits和tf.nn.softmax_cross_entropy_with_logits都是對單標籤分類進行處理,也就是說每個樣本分類的值是唯一的。


    tf.nn.sigmoid_cross_entropy_with_logits和tf.nn.softmax_cross_entropy_with_logits的不同在於前者輸入是onehot向量,後者是單個維度的標籤值,這樣在類別很多的情況下,能節省資源,計算得更快。


    那麼這種情況的樣本不均衡怎麼處理呢?

    我一般的做法是在lable上做手腳,因為交叉熵需要乘以一個label項,將onehot向量放大相應的倍數就可以達到對loss進行加權的目的,比如我們有樣本數目A,B,C類分別為6W 、1.5W、1W的數據,我們的損失函數的代碼可以寫成:

    <code>class_weights = tf.constant([[1.0, 4.0, 6.0]])
    weights = tf.reduce_sum(class_weights * self.label, axis=1)
    unweight_loss = tf.nn.softmax_cross_entropy_with_logits(labels=self.label, logits=logits)

    self.loss = self.cross_entropy = tf.reduce_mean(weights * unweight_loss)/<code>

    參考文獻:

    [1] https://zhuanlan.zhihu.com/p/67650069

    [2] https://www.jianshu.com/p/88d1eac07d57


    如果覺得內容不錯或者有問題,可以在評論區留言,或者私信我,謝謝大家!


    分享到:


    相關文章: