類別不均衡處理辦法總結

   對於深度學習而言,數據量不平衡是很常見的問題,如:工廠的產品缺陷率一般在 0.1% 左右,患者病例比較少等。最近遇到個項目,樣本類別極其不均衡,多的類別有上萬張,少的僅有幾百張,爲了有好的訓練效果,嘗試了很多方法,在這篇博客總結下我使用的,還有見到的一些方法。

一、過採樣欠採樣

   既然不平衡,那就想辦法讓他平衡,增加數據和減少數據。一般的方法是過採樣和欠採樣。

  過採樣的意思就是:把少數類別數量重複利用,相當於某個類別100張,複製後,數據量就成爲200張。不過這種方法不推薦,可能會造成過擬合。最好是通過數據增強的方式來對少數類別的數量進行數據擴充。數據增強方式與代碼:鏈接

  欠採樣的意思就是:數據量大的類別數據並不是全部都使用,比如一萬張圖像,使用三四千張來作爲訓練數據。根據自己的數據量進行調整,儘量平衡。我就是使用了這個方法。

二、創造數據

  既然有一些類別數量很少,就想辦法創造數據、生成數據。能儘量想辦法找數據就找,一些公共數據集,或者去谷歌爬蟲一些圖片(谷歌爬蟲方法鏈接

  方法1:根據自己數量特徵,想辦法生成不同的背景。即保留特徵,換背景(這種生成數據方法一般適用於類別數據特徵比較明顯,易分割)

  方法2:SMOTE 及其衍生技術。這是個算法,我沒用過,不過看到很多地方都提到這個算法,網上有實線,倒是可以試一試。

三、合併新的少數類別

意思是根據自己的項目,將一些數據量少的類別進行一定的合併,比如,自行車、摩托車,統稱爲非機動車類別。根據自己需求來更改。

四、調整類權重

如果類別不均衡很嚴重,神經網絡會傾向與數據量大的類別進行預測,這顯然不是我們想要的效果,所以需要對不同類別設置不同的重要程度,少類數據量少,我們更加應該關注。故需要對數據量少的類別加大權重

方法1:更改交叉商損失

交叉熵公式如下

在tensorflow中的函數是:tf.nn.softmax_cross_entropy_with_logits(logits=prediction,labels=y)

我們需要對類別設置一定的權重,設置的比例最好是與不同類別數據量比例相反。比如三類的數據量,100,200,300這樣我們需要設置的比例爲3:2:1.如下面代碼所示。這樣對數據量少的類別加大了損失權重。這個方法可以使用多類別。

class_weight = tf.constant([3,2,1])
y_class_weight = y*class_weight
loss = -tf.reduce_mean(y_class_weight*tf.log(yprediction))

該方法我試過,不過沒有很好的效果,當然這個比例是要調參的,沒有放之四海皆準的。

方法2:更換交叉商函數

官方函數:tf.nn.weighted_cross_entropy_with_logits 

之前普通的交叉熵函數定義爲:

 

[公式]

就是在交叉熵的公式裏面對應的少數類乘上一個係數:
​​​該函數實現的是:如果pos_weights > 1減小了錯誤負樣本的權重,因此提高了recall。相反如果pos_weights < 1減小了錯誤正樣本的權重,因此提高了precision。pos_weight是作爲損失表達式中正目標項的乘法系數引入的。

[公式]

該方法也是不錯的,不過我認爲這個方法只適用於兩類,正負樣本,比如用於目標檢測解決正負樣本不均衡的問題,或者語義分割,如車道線檢測。對於多分類效果好像沒用,我試了下。

五、更改損失函數(Focal Loss)

論文:Focal Loss for Dense Object Detection 
論文鏈接:https://arxiv.org/abs/1708.02002 

  將損失函數更改爲Focal Loss。這個損失是愷明大神提出來的。主要是來解決目標檢測中正負樣本不均衡的問題,這個損失函數是在標準交叉熵損失基礎上修改得到的。這個函數可以通過減少易分類樣本的權重,使得模型在訓練時更專注於難分類的樣本.這個函數已經有實現如下:

pytorch:https://github.com/clcarwin/focal_loss_pytorch

tensorflow:https://github.com/ailias/Focal-Loss-implement-on-Tensorflow

mxnet:https://github.com/unsky/focal-loss

如果需要看Focal Loss損失函數講解,推薦一個博客:https://blog.csdn.net/u014380165/article/details/77019084

六、更改評價標準

  評價標準很重要,因爲如果你不知道該如何正確度量你的成果,你也就不能取得進展。當然既然樣本都不均衡了,肯定不能使用單一的準確率來評價模型是否好了,比如使用:召回率、F1分數、一個 ROC 曲線、準確度召回曲線(precision-recall curve)等。西瓜上上有詳細解析。

F1 分數(F1 Score):是準確度(precision)和召回率(recall)的調和平均值

ROC 曲線下的面積(AUC):是一個很好的一般統計。它等於一個隨機的正面樣本將得到比一個隨機的負面樣本更高排名的概率。

七、提高一些判別閾值

   當你得到概率估計之後,不要盲目地使用 0.50 的決策閾值來區分類別,提高一點。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章