日常的應用中,我們會很經常遇到一個問題:
如何應用強大的model(比如ResNet)去訓練我們自己的數據?
考慮到這樣的幾個事實:
- 通常我們自己的數據集都不會大(<1w)
- 從頭開始訓練耗時
解決方法就是fine-tuning
.
方式
參考CS231的資料,有三種方式
- ConvNet as fixed feature extractor.
其實這裏有兩種做法:
(1) 使用最後一個fc layer之前的fc layer獲得的特徵,學習個線性分類器(比如SVM)
(2) 重新訓練最後一個fc layer- Fine-tuning the ConvNet.
固定前幾層的參數,只對最後幾層進行fine-tuning- Pretrained models.
這個其實和第二種是一個意思,不過比較極端,使用整個pre-trained的model作爲初始化,然後fine-tuning整個網絡而不是某些層
選擇
考慮兩個問題:
- 你的數據集大小
- 你的數據集和ImageNet(假設在ImageNet上訓練的)的相似性
分爲四種情況,解決方法基於的原則就是:
NN中的低層特徵是比較generic的,比如說線、邊緣的信息,高層特徵是Dataset Specific的,基於此,如果你的數據集和ImageNet差異比較大,這個時候你應該儘可能的少用pre-trained model的高層特徵.
數據集小(比如<5000),相似度高
這是最常見的情況,可以僅重新訓練最後一層(fc layer)
數據集大(比如>10000),相似度高
fine-tuning後幾層,保持前面幾層不變或者乾脆直接使用pre-trained model作爲初始化,fine-tuning整個網絡
數據集小,相似度低
小數據集沒有辦法進行多層或者整個網絡的fine-tuning,建議保持前幾層不動,fine-tuning後幾層(效果可能也不會很好)
數據集大,相似度低
雖然相似度低,但是數據集大,可以和2一樣處理
從上面我們可以看出,數據集大有優勢,否則最好是數據集和原始的相似度比較高;如果出現數據集小同時相似度低的情況,這個時候去fine-tuning後幾層未必會有比較好的效果.
Caffe中如何進行fine-tuning
Caffe做fine-tuning相對tensorflow很簡單,只需要簡單修改下配置文件就行了.
此處假設你的數據集比較小,同時相似度比較高,僅需重新訓練最後一層(fc)的情況.
(1) 降低solver中lr和stepsize
這個很明顯,因爲相似度比較高我們可以期望原始獲得的feature和需要的是很接近的,此時需要降低學習率(lr)和迭代次數(stepsize).
(2) 修改最後一層fc的名字,設置好lr_mult
應爲需要訓練最後一層,我們把之前的層的學習率設置的很低(比如0.001),或者你乾脆設置爲0,最後一層設置一定的學習率(比如0.01),所以需要乘以10.
(3) 訓練
其實就已經改好了,是不是很簡單,按照之前標準化的訓練測試就好了
知乎上fine-tuning的介紹上有更加詳細的介紹,可以移步去看.
參考
(1) NodYoung的博客