面對高度不均衡數據如何提高精度?這篇文章有妙招
- 2019 年 10 月 7 日
- 筆記
本文是對 CVPR 2019 論文「Class-Balanced Loss Based on Effective Number of Samples」的一篇點評,全文如下:
這篇論文針對最常用的損耗(softmax 交叉熵、focal loss 等)提出了一種按類重新加權的方案,以快速提高精度,特別是在處理類高度不平衡的數據時尤其有用。
本文的實現方法(PyTorch)的 github 地址為:https://github.com/vandit15/Class-balanced-loss-pytorch
有效樣本數
在處理長尾數據集(一個數據集的大多數樣本屬於少數類,而其它許多類的數據很少)時,決定如何權衡不同類的損失是很棘手的。通常,權重設置為類支援的逆或類支援的平方根的逆。
傳統重加權與這裡提到的重加權
然而,如上圖所示,這種現象是因為隨著樣本數的增加,新數據點帶來的額外好處減少了。在訓練神經網路時使用重數據增強(如重縮放、隨機裁剪、翻轉等)時,新添加的樣本很可能是現有樣本的近似副本。用有效樣本數重新加權得到了較好的結果。
有效樣本數可以想像為 n 個樣本覆蓋的實際體積,其中總體積 N 由總樣本數表示。
有效樣本數
我們寫出其公式:
有效樣本數
這裡,我們假設一個新的樣本將只以兩種方式與先前取樣的數據交互:完全覆蓋或完全沒有交集(如上圖所示)。在這種假設下,用歸納法可以很容易地證明上述表達式(請參閱本文的證明)。
我們也可以像下面這樣寫:
每個樣本的貢獻
這意味著第 j 個樣本對有效樣本數貢獻為 β^(j-1)。
上述方程的另一個含義是,如果 β=0,則 En=1。同時,En=n 則 β=1。後者可以很容易地用 L'Hopital's 法則證明。這意味著當 N 很大時,有效樣本數與樣本數相同。在這種情況下,唯一原型數 N 很大,每個樣本都是唯一的。然而,如果 N=1,這意味著所有數據都可以用一個原型表示。
類平衡損失
如果沒有額外的資訊,我們不能為每個類設置單獨的 β 值,因此,使用整個數據,我們會將其設置為特定值(通常設置為0.9、0.99、0.999、0.9999 之一的數值)。
因此,類平衡損失可以寫成:
CB 損失
這裡,L(p,y) 可以是任何損失函數。
類平衡 focal loss
類平衡 focal loss
原始版本的 focal loss 有一個 alpha 平衡變數。相反,我們將使用每個類的有效樣本數對其重新加權。
類似地,這種重新加權項也可以應用於其他著名的損失(sigmoid 交叉熵、softmax 交叉熵等)。
應用
在開始應用之前,在使用基於 sigmoid 的損耗進行訓練時要注意一點:用 b=-log(c-1)初始化最後一層的偏差,其中類的數量是 c,而不是 0。這是因為設置 b=0 在訓練開始時會導致巨大的損失——每個類的輸出概率接近 0.5。因此,我們可以假設類 prior 是 1/c,並相應地設置值 b。
類的權重計算
計算標準化權重
上面的程式碼行是一個簡單的實現,獲取權重並將其標準化。
獲取 one-hot 標籤的 PyTorch 張量
在這裡,我們得到權重的 one hot 值,這樣它們就可以分別與每個類的損失值相乘。
實驗
類平衡提供了顯著的優勢,特別是當數據集高度不平衡時(不平衡=200100)。
結論
利用有效樣本數的概念,可以解決數據重合的問題。由於我們沒有對數據集本身做任何假設,因此重新加權項通常適用於多個數據集和多個損失函數。因此,類不平衡的問題可以用一個更合適的結構來解決,這一點很重要,因為現實世界中的大多數數據集都存在大量的數據不平衡。
參考
[1] Class-Balanced Loss Based on Effective Number of Samples: https://arxiv.org/abs/1901.05555
via:https://towardsdatascience.com/handling-class-imbalanced-data-using-a-loss-specifically-made-for-it-6e58fd65ffab
* 封面圖來源:https://pixabay.com/images/id-63527/