大部分內容參考自《Machine Learning Yearning》
Bias 和 Variance
偏差(bias)是指演算法在訓練集上的偏差,也就是錯誤率,錯誤越大偏差越大,欠擬合
方差(variance)是指演算法在開發集(或測試集)上的表現比訓練集上差多少,也可以理解為過擬合,表現 為訓練集正確率很高,測試集上的正確率很低
可避免偏差和不可避免偏差
偏差可以分為兩個部分,包括可避免偏差和不可避免偏差
如何理解:假設現有一個珍稀動物識別系統,任務難度大,即便由人類來區分,也存在14%的錯誤率(最優錯誤率)
現在演算法達到:
訓練錯誤率=15%
開發錯誤率=30%
可以將訓練錯誤率(偏差)分解如下:
最伏錯誤率(“不可避免偏差”):14%,可以將其認為是學習演算法的偏差“不可避免”的部分。
可避免偏差:1%。即訓練錯誤率和最伏誤差率之間的差值。
舉個例子,該例子中最優錯誤率是 14%,我們有:
● 訓練誤差 = 15%
● 開發誤差 = 16%
i這種情況下,可避免的偏差誤差是 1%,方差誤差約為 1%。因此,演算法已經做的很好了,幾乎沒有提升的空間。它只比最佳錯誤率低 2%
如何設定期望誤差率
使用人類表現水平來估計最優錯誤率,並設定可達到的“期望錯誤率”。 假設你的演算法在某個任務上達到了 10% 的誤差,但普通人所能達到的誤差是 2% . 由此我們就可以知道最優錯誤率是 2% 或更低,這也表明可避免偏差至少是 8% . 所以你應當嘗試一下降低偏差的技術。更一般地說,有一個合理可實現的“期望錯誤率”可以幫助你去估計學習演算法的可避免偏差。這反過來也幫你決定是否使用誤差降低技術
偏差和方差的幾種情況和解決方案
1)假設訓練集錯誤率1%,開發集錯誤率10%,則樣本方差大,過擬合
-
修改模型架構
減小模型規模(比如神經元/層的數量),減小網路複雜度
-
增加正則化
-
L 1 Regularization
-
L 2 Regularization
-
Dropout層
-
-
新增Batch Normalization
-
加入提前終止(Early stopping)
-
模型初始化
-
通過特徵選擇減少輸入特徵的數量和種類
-
特徵降維
-
根據誤差分析修改特徵
-
檢測訓練資料集和測試資料是否有相對應的特徵,資料分佈是否一致,不一致的時候,繼續特徵工程工作
-
增加訓練資料的種類,使得訓練資料覆蓋所有測試資料的特使用資料增強
-
增加資料量
2)假設訓練錯誤率為15%,開發錯誤率為16%,這個時候,偏差比較大,欠擬合
-
增加訓練epoch
-
增大batch-size
-
調整啟用函式(例如使用relu)
-
調整優化演算法
-
例如使用Adam
-
增大learning rate
-
-
增加網路複雜度
-
增加網路層數
-
增加摺積層輸出的通道數
-
增加全連線層的節點數
-
-
檢測訓練資料集和測試資料是否有相對應的特徵
-
增加訓練資料的種類,使得訓練資料覆蓋所有測試資料的特性,
-
增加外部資料集,如果擔心外部資料集汙染training set,可以將外部資料集的權重調低一點
-
資料增強
-
3)假設訓練錯誤率為15%,開發錯誤率為30%,高偏差,高方差
這個時候,先要解決偏差問題,只有在訓練集上開始收斂了,才能開始考慮測試集上的方差問題。因此遇到這種情況,先按照高偏差解決,高偏差解決之後,也許可能高方差的問題也就消失了,如果沒有消失,在考慮解決高方差的問題。
4)假設訓練錯誤率為0.5%,開發錯誤率為1%,低偏差,低方差(完美狀態)
5)假設訓練錯誤率為0.5%,開發錯誤率為1%,低偏差,低方差,但是開發集loss在低點持續震盪
-
確認訓練集和測試集分佈是否存在較大的差異,差異大的話進行特徵工程
-
確認是否資料增強做的太多了
-
嘗試調整學習率,在不同階段使用不用學習率
-
思考和檢查網路是否還是有點欠擬合,如果還有,解決欠擬合
-
找到更多訓練資料,使其能夠覆蓋較多的樣本分佈
模型調參Pipeline
-
設定固定隨機種子
-
先不要使用資料增強
-
設定合理的baseline
-
過擬合一個batch,然後觀察loss最低可以到達多少,對比baseline,如果可以到達很低,進行下一步,如果不行,則考慮 情況2)
-
繪製training和testing 階段的loss曲線
-
驗證loss函式
-
如果train loss 小
-
如果test set 的loss 大,而train set 的loss小,說明過擬合,使用情況1)解決
-
如果test set的loss 也小,那麼基本上算是成功了
-
如果test set 的 loss 也小,但是震盪,使用 情況5)解決
-
-
如果train loss 大
進入步驟2)
-
已優化模型如何進一步提高
-
優化網路結構,使用更好的backbone
-
使用更好的LOSS函式,比如:迴歸問題可以考慮smooth-l1等
-
考慮使用難例挖掘的方法
-
有條件的話,加大batchsize
-
考慮預訓練模型
-
觀察測試樣本,查詢case,針對Case來,補充樣本+資料增強
-
嘗試不同的優化函式,交替訓練,fine-tuning
-
不同的權重初始化方法
-
嘗試不同的學習率初始值和衰減值
-
考慮在梯度上做文章,可以是梯度裁剪、梯度校驗、梯度歸一化等方法
-
繼續特徵工程(往往最有效)