- 前言
- 一,資料層面處理方法
- 1.1,資料擴充
- 1.2,資料(重)采樣
- 資料采樣方法總結
- 1.3,類別平衡采樣
- 二,演算法(損失函式)層面處理方法
- 2.1,Focal Loss
- 2.2,損失函式加權
- 參考資料
前言
在機器學習的經典假設中往往假設訓練樣本各類別數目是均衡的,但在實際場景中,訓練樣本資料往往都是不均衡(不平衡)的,比如在影像二分類問題中,一個極端的例子是,訓練集中有 95 個正樣本,但是負樣本只有 5 個,這種類別資料不均衡的情況下,如果不做不平衡樣本的處理,會導致模型在數目較少的類別上出現“欠學習”現象,即可能在測驗集上完全喪失對負樣本的預測能力,
除了常見的分類、回歸任務,類似影像語意分割、深度估計等像素級別任務中也是存在不平衡樣本問題的,
解決不平衡樣本問題的處理方法一般有兩種:
- 從“資料層面”入手:分為資料采樣法和類別平衡采樣法,
- 從“演算法層面”入手:代價敏感方法,
注意本文只介紹不平衡樣本的處理思想和策略,不涉及具體代碼,在實際專案中,需要針對具體人物,結合不平衡樣本的處理策略來設計具體的資料集處理或損失函式代碼,從而解決對應問題,
一,資料層面處理方法
資料層面的處理方法一般是借助資料采樣法(sampling)使得輸入到模型的訓練集樣本趨向于平衡,即各類樣本的數目趨向于一致,
資料層面的處理方法主要有兩種策略,一種是資料重采樣方法,發生在資料預處理階段,會改變整體訓練集的數目和分布,一種類別平衡采樣方法,發生在資料加載階段(這里的加載是指加載到模型中,不是指從硬碟中讀取檔案),通過設定采樣策略來使得不同類別樣本送入模型訓練總的次數是近似的,
1.1,資料擴充
所謂資料不平衡,其實就是某些類別的資料量太少,那就直接增加一些唄,簡單直接,如果有的選,那肯定是優先選擇重新采取資料的辦法了,當然大部分時候我們都沒得選,這個時候最有效的辦法自然是通過資料增強來擴充資料了,
資料增強的手段有多種,常見的如下:
- 水平 / 豎直翻轉
- 90°,180°,270° 旋轉
- 翻轉 + 旋轉(旋轉和翻轉其實是保證了資料特征的旋轉不變性能被模型學習到,卷積層面的方法可以參考論文
ACNet) - 亮度,飽和度,對比度的隨機變化
- 隨機裁剪(Random Crop)
- 隨機縮放(Random Resize)
- 加模糊(Blurring)
- 加高斯噪聲(Gaussian Noise)
值得注意的是資料增強手段的使用必須結合具體任務而來,除了前三種以外,其他的要慎重考慮,因為不同的任務場景下資料特征依賴不同,比如高斯噪聲,在天池鋁材缺陷檢測競賽中,如果高斯噪聲增加不當,有些圖片原本在采集的時候相機就對焦不準,導致工件難以看清,倘若再增加高斯模糊屬性,部分圖片樣本基本就廢了,
參考文章 如何針對資料不平衡做處理,
雖然目前深度學習框架中都自帶了一些資料增強函式,但更多更強的資料增強手段可以使用一些影像增強庫,比如 imgaug 這個 python 庫,
模型訓練程序中,pytorch 框架如何在資料構建 pipeline 階段使用 imgaug 庫可以參考文章 資料增強-imgaug,
1.2,資料(重)采樣
簡單的資料重采樣方法分為資料上采樣(over-sampling、up-sampling,也叫資料過采樣) 或 也叫資料欠采樣資料下采樣(under-sampling 、down-sampling ),
1,對于樣本數目較少的類別,可用資料過采樣方法(over-sampling),即通過復制方法使得該類影像數目增至與樣本最多類的樣本數一致,
2,而對于樣本數較多的類別,可使用資料欠采樣(Under-sampling,也叫資料欠采樣)方法,對于深度學習和計算機視覺領域的任務來說,下采樣并不是直接隨機丟棄一部分影像,正確的下采樣策略是: 在批處理訓練時(資料加載階段 dataloader),對于樣本較多的類別,嚴格控制每批(batch)隨機抽取的影像數目,使得每批讀取的資料中正負樣本是均衡的(類別均衡),以二分類任務為例,假設原始資料分布情況下每批處理訓練正負樣本平均數量比例為 9:1,如僅使用下采樣策略,則可在每批隨機挑選訓練樣本時每 9 個正樣本只取 1 個作為該批訓練集的正樣本,負樣本選擇策略不變,這樣可使得每批讀取的訓練資料中正負樣本時平衡的,
資料過采樣和欠采樣示意圖如下所示,

資料采樣方法總結
資料過采樣和欠采樣本質的簡單理解就是“增加圖片”和“刪圖片”:
- 過采樣:重復正比例資料,實際上沒有為模型引入更多形式資料,過分強調正比例資料,會放大正比例噪音對模型的影響,
- 欠采樣:丟棄大類別的部分資料,和過采樣一樣會存在過擬合的問題,
同時兩種資料重采樣方法都是會改變資料原始分布的,比如資料過采樣增加較小類別的樣本數,資料欠采樣減少較大類別的樣本數,有可能產生模型過擬合等問題,
這里的較小類別的意思是樣本數目較少的類別,較大類別即樣本數目較多的類別,
以上內容都是對解決類別不平衡問題中資料采樣方法的策略描述,但想要在實際任務中解決問題,還要求我們加深對任務(task)的分析、對資料的理解分析,以及要求我們有更多的資料處理、資料采樣的代碼經驗,即良好的策略 + 熟練的工具,
需要注意的是,因為僅僅使用資料上采樣策略有可能會引起模型過擬合問題,所以在實際任務中,更為保險的資料采樣策略哇往往是將上采樣和下采樣結合起來使用,
1.3,類別平衡采樣
前面的資料重采樣策略是著重于類別樣本數量,而另一類采樣策略則是直接著重于類別本身,不改變資料總體樣本數,即類別平衡采樣方法,其簡單策略是把樣本按類別分組,每個類別生成一個樣本串列,訓練程序中隨機選擇 1 個或幾個類別,然后從每個類別所對應的樣本串列中隨機選擇樣本,這樣可保證每個類別參與訓練的機會比較均衡,
上述類別平衡方法過于簡單,實際應用中有很多限制,比如在類別數很多的多分類任務中(如 ImageNet 資料集),由此,在類別平衡采樣的基礎上,國內海康威視研究院提出了一種“類別重組采樣”的平衡方法,
類別重組法是在《決議卷積神經網路》這本書中看到的,可惜沒在網上找到原論文和代碼,但這個方法感徑訓是很有用的,且也比較好復現,
如下圖所示,類別重組方法步驟如下:

- 對原始樣本的每個類別的樣本分別排序好,計算每個類別的樣本數目,并記錄樣本數最多的那個類別的樣本數量
max_num, - 基于最大樣本數
max_num產生一個亂數串列,然后用此串列中的亂數對各自類別的樣本數求余,得到對應索引值串列index_list,random.shuffle(list(range(max_num))) - 根據該索引值串列
index_list,從該類的影像資料中提取影像,生成該類的影像隨機串列, - 最后吧所有類別的隨機串列連接在一起后一起隨機打亂次序,即可得到最終的影像串列,可以發現最終的這個影像隨機串列中每個類別的樣本數目是一致的(樣本數較少的類別,影像會存在多次采樣),然后每輪(
epoch)都對此串列進行遍歷資料用于模型訓練,如此重復,

類別重組法對有點很明顯,在設計好重組代碼函式后,只需要原始影像串列即可,所有操作都在記憶體中在線完成,易于實作且更通用,其實仔細深究可以發現,海康提出的這個類別重組法和前面的資料采樣方法是很類似的,其本質都是通過采樣(sampler)策略讓類別不均衡的各類資料在每輪訓練中出現的次數是一致的,
二,演算法(損失函式)層面處理方法
類別不平衡問題的本質是導致樣本數目較少的類別出現“欠學習”這一機器學習現象,直觀表現是較小樣本的損失函式權重占比也較少,一個很自然的解決辦法是增加小樣本錯分的懲罰代價,并將此代價直接體現在目標函式(損失函式)里,這就是“代價敏感”的方法,“代價敏感”方法的本質可以理解為調整模型在小類別上的注意力,
2.1,Focal Loss
Focal Loss 是在二分類問題的交叉熵(CE)損失函式的基礎上引入的,主要是為了解決 one-stage 目標檢測中正負樣本比例嚴重失衡的問題,該損失函式降低了大量簡單負樣本在訓練中所占的權重,也可理解為一種困難樣本挖掘,經實踐證明 Focal Loss 在 one-stage 目標檢測中還是很有效的,但是在多分類中不一定有效,
Focal Loss 作者通過在交叉熵損失函式上加上一個調整因子(modulating factor)\((1-p_t)^\gamma\),把高置信度 \(p\)(易分樣本)樣本的損失降低一些,Focal Loss 定義如下:
Focal Loss 有兩個性質:
- 當樣本被錯誤分類且 \(p_t\) 值較小時,調制因子接近于
1,loss幾乎不受影響;當 \(p_t\) 接近于1,調質因子(factor)也接近于0,容易分類樣本的損失被減少了權重,整體而言,相當于增加了分類不準確樣本在損失函式中的權重, - \(\gamma\) 引數平滑地調整容易樣本的權重下降率,當 \(\gamma = 0\) 時,
Focal Loss等同于CE Loss, \(\gamma\) 在增加,調制因子的作用也就增加,實驗證明 \(\gamma = 2\) 時,模型效果最好,
直觀地說,調制因子減少了簡單樣本的損失貢獻,并擴大了樣本獲得低損失的范圍,例如,當\(\gamma = 2\) 時,與 \(CE\) 相比,分類為 \(p_t = 0.9\) 的樣本的損耗將降低 100 倍,而當 \(p_t = 0.968\) 時,其損耗將降低 1000 倍,這反過來又增加了錯誤分類樣本的重要性(對于 \(pt≤0.5\) 和 \(\gamma = 2\),其損失最多減少 4 倍),在訓練程序關注物件的排序為正難 > 負難 > 正易 > 負易,
| 難 | 易 | |
|---|---|---|
| 正 | 1. 正難 | 3. 正易,\(\gamma\) 衰減 |
| 負 | 2. 負難,\(\alpha\) 衰減 | 4. 負易,\(\alpha、\gamma\)衰減 |
在實踐中,我們通常采用帶 \(\alpha\) 的 Focal Loss:
作者在實驗中采用這種形式,發現它比非 \(\alpha\) 平衡形式(non-\(\alpha\)-balanced)的精確度稍有提高,實驗表明 \(\gamma\) 取 2,\(\alpha\) 取 0.25 的時候效果最佳,
更多理解參考 focal loss 論文,
2.2,損失函式加權
除了 Focal Loss 這種高明的損失函式策略外,針對影像分類問題,還有一種簡單直接的損失函式加權方法,即在計算損失函式程序中,對每個類別的損失做加權處理,具體的 PyTorch 實作方式如下:
weights = torch.FloatTensor([1, 1, 8, 8, 4]) # 類別權重分別是 1:1:8:8:4
# pos_weight_weight(tensor): 1-D tensor,n 個元素,分別代表 n 類的權重,
# 為每個批次元素的損失指定的手動重新縮放權重,
# 如果你的訓練樣本很不均衡的話,是非常有用的,默認值為 None,
criterion = nn.BCEWithLogitsLoss(pos_weight=weights).cuda()
參考資料
- 《決議卷積神經網路》
- 如何針對資料不平衡做處理
- 10 Techniques to deal with Imbalanced Classes in Machine Learning
本文由博客一文多發平臺 OpenWrite 發布!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/539453.html
標籤:其他
上一篇:Chatgpt注冊全流程教程
下一篇:各開發語言DNS快取配置建議
