深度學習調參體驗(一)

深度學習調參體驗(一)

基本原則:

快速試錯

一.一些大的注意事項:

1.先上小規模數據, 模型往大了放,
只要不爆顯存, 能用256個filter就別用128個。直接奔着過擬合去。就是訓練過擬合網絡, 連測試集驗證集這些都可以不用。

爲什麼?

要驗證自己的訓練腳本的流程對不對。這一步小數據量, 生成速度快, 但是所有的腳本都是和未來大規模訓練一致的(除了少跑點循環)。

如果小數據量下, 這麼粗暴的大網絡奔着過擬合去都沒效果。要開始反思自己了, 模型的輸入輸出是不是有問題? 要不要檢查自己的代碼(永遠不要懷疑工具庫, 除非動過代碼)?
模型解決的問題定義是不是有問題? 對應用場景的理解是不是有錯?
不要懷疑NN的能力, 不要懷疑NN的能力, 不要懷疑NN的能力。調參狗能遇到的問題, NN沒法擬合的, 這概率是有多小?

可以不這麼做, 但是等數據準備了兩天, 結果發現有問題要重新生成的時候,時間沒有了。

  1. Loss設計要合理.

一般來說分類就是Softmax, 迴歸就是L2的loss.
但是要注意loss的錯誤範圍(主要是迴歸), 預測一個label是10000的值, 模型輸出0, 算算這loss多大, 這還是單變量的情況下。一般結果都是nan. 所以不僅僅輸入要做normalization, 輸出也要這麼弄。

多任務情況下, 各loss想法限制在一個量級上, 或者最終限制在一個量級上, 初期可以着重一個任務的loss。

  1. 觀察loss勝於觀察準確率

準確率雖然是評測指標, 但是訓練過程中還是要注意loss的。會發現有些情況下, 準確率是突變的, 原來一直是0, 可能保持上千迭代, 然後突然變1。要是因爲這個提前中斷訓練了, 只有老天替惋惜了。而loss是不會有這麼詭異的情況發生的, 畢竟優化目標是loss。

給NN一點時間, 要根據任務留給NN的學習一定空間。不能說前面一段時間沒起色就不管了。有些情況下就是前面一段時間看不出起色, 然後開始穩定學習。

  1. 確認分類網絡學習充分

分類網絡就是學習類別之間的界限。網絡就是慢慢的從類別模糊到類別清晰的。怎麼發現? 看Softmax輸出的概率的分佈。如果是二分類,剛開始的網絡預測都是在0.5上下, 很模糊。隨着學習過程, 網絡預測會慢慢的移動到0,1這種極值附近。如果的網絡預測分佈靠中間, 再學習學習。

  1. Learning Rate設置合理

太大: loss爆炸, 或者nan。

太小: 半天loss沒反映(但是, LR需要降低的情況也是這樣, 這裏可視化網絡中間結果, 不是weights, 有效果, 倆者可視化結果是不一樣的, 太小的話中間結果有點水波紋或者噪點的樣子, 因爲filter學習太慢的原因, 試過就會知道很明顯)。

需要進一步降低了: loss在當前LR下一路降了下來, 但是半天不再降了。

如果有個複雜點的任務,需要人肉盯着調LR的。後面熟悉這個任務網絡學習的特性後, 可以扔一邊跑去了。

如果上面的Loss設計那塊沒法合理, 初始情況下容易爆, 先上一個小LR保證不爆, 等loss降下來了, 再慢慢升LR, 之後當然還會慢慢再降LR, 雖然這很痛苦。

LR在可以工作的最大值下往小收一收, 免得ReLU把神經元弄死了。

6 對比訓練集和驗證集的loss

判斷過擬合, 訓練是否足夠, 是否需要early stop的依據, 這都是中規中矩的原則。

7 清楚receptive field的大小

CV的任務, context window是很重要的。所以對自己模型的receptive field的大小要心中有數。這個對效果的影響還是很顯著的。特別是用FCN,
大目標需要很大的receptive field。不像有fully
connection的網絡, 好歹有個fc兜底, 全局信息都有。

二. 簡短的注意事項:

  1. 預處理: -mean/std zero-center就夠了, PCA, 白化什麼的都用不上。反正CNN能學習encoder, PCA用不用其實關係不大, 大不了網絡裏面自己學習出來一個。

  2. shuffle, shuffle, shuffle。

  3. 網絡原理的理解最重要, CNN的conv這塊, 得明白sobel算子的邊界檢測。

  4. Dropout, Dropout, Dropout(不僅僅可以防止過擬合, 其實這相當於做人力成本最低的Ensemble, 當然, 訓練起來會比沒有Dropout的要慢一點, 同時網絡參數最好相應加一點, 對, 這會再慢一點)。

  5. CNN更加適合訓練回答是否的問題, 如果任務比較複雜, 考慮先用分類任務訓練一個模型再finetune。

  6. 不要用ReLU(CV領域)。

  7. 不要用3x3。

  8. 不要用xavier。

  9. LRN一類的, 其實可以不用。不行可以再拿來試試看。

  10. filter數量2^n。

  11. 多尺度的圖片輸入(或者網絡內部利用多尺度下的結果)有很好的提升效果。

  12. 第一層的filter, 數量不要太少。否則根本學不出來(底層特徵很重要)。

  13. sgd adam 這些選擇上,一般對網絡不是決定性的。反正不要用sgd momentum。

  14. batch normalization,要鼓勵使用batch normalization。

  15. 不要完全相信論文裏面的東西。結構什麼的覺得可能有效果, 可以拿去試試。

  16. 有95%概率不會使用超過40層的模型。

  17. shortcut的聯接是有作用的。

  18. 暴力調參最可取,調完這個模型說不定過兩天這模型就扔掉了。

  19. 機器, 機器, 機器。

  20. Google的inception論文, 結構要好好看看。

  21. 一些傳統的方法, 要了解。自己的程序就用過1x14的手寫filter, 寫過之後看看inception裏面的1x7, 7x1。

三.產品開發

·
33卷積是CNN的主流組件。平時有設計一些解決分類,迴歸任務的網絡,裏面的卷積核基本都設置爲33,要說原因的話應該去問問VGG16吧。兩個33的卷積核堆疊能獲得55卷積核的感受野並且參數比5*5卷積核少,所以是大量推薦使用的。

·
可以適當使用1N卷積。爲什麼要提這一點呢,這是因爲1N卷積可以減少計算量,並且1N卷積可以在某個方向強調感受野,也就是說假如如果要對一個長方形形狀的目標進行分類,可以使用1N的卷積核搭配3*3的卷積覈對長邊方向設定更大的感受野,或許可以獲得泛化性能的提升。

·
ACNet結構。這個研究來自於ICCV2019,可以在33卷積的基礎上加上13和31的旁路卷積核,最後在推理階段把三個卷積核都fusion到33卷積核上,在許多經典CV任務上都可以獲得大概1個點的提升。

非對稱卷積通常用於逼近現有的正方形卷積以進行模型壓縮和加速,先前的一些工作表明,可以將標準的dd卷積分解爲d1和1d卷積,以減少參數量。其背後的理論相當簡單:如果二維卷積核的秩爲1,則運算可等價地轉換爲一系列一維卷積。由於深度網絡中下學習到的核具有分佈特徵值,其內在秩比實際中的高,因此直接將變換應用於核會導致顯著的信息損失。Denton等人基於SVD分解找到一個低秩逼近,然後對上層進行精細化以恢復性能。Jaderberg等人通過最小化重構誤差,成功學習了水平核和垂直核。Jin等人應用結構約束使二維卷積可分離,在獲得相當精度的條件下時間加速了2倍。另一方面,非堆成卷積也被廣泛的用來做網絡結構設計,例如Inception-v3中,77卷積被17卷積和71卷積代替。語義分割ENet網絡也採用這種方法來設計高效的語義分割網絡,雖然精度略有下降,但降低了33%的參數量。

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

關注3x3卷積,這在現代CNN體系結構中大量使用。在給定的體系結構下,通過簡單地將每個3x3卷積層替換爲ACB來構建ACNet,該ACB模塊包含三個並行層,內核大小分別爲3x3,1x3,和3x1。和標準CNN的常規做法類似,在三層中的每一層之後都進行批量歸一化,並將三個分支的輸出綜合作爲ACB的輸出。可以使用與原始模型相同的配置來訓練ACNet,而無需調整任何額外的超參數。可以訓練ACNet達到更高的精度。訓練完成後,嘗試將每個ACB轉換爲產生相同輸出的標準卷積層這樣,與經過常規訓練的對等方相比,可以獲得不需要任何額外計算的功能更強大的網絡。該轉換通過兩個步驟完成,即BN融合和分支融合。

·
卷積核權重初始化方式。對於weight的初始化一般都是使用xavier初始化。對於bias的初始化全置於0。

·
Batch Normalization。這是一直在使用的技巧,可以很大程度的加快收斂速度。建議搭建自己網絡的時候儘量加上BN,如果有BN了全連接層就沒必要加Dropout了。

·
目標檢測不能盲目去掉fpn結構。在針對自己的數據調檢測任務如yolov3的時候不能盲目砍掉fpn結構,儘管分析出某個分支的Anchor基本不可能會對預測的目標起作用,但如果直接去掉分支很可能會帶來漏檢。

·
優化器的選擇。基本都是帶動量的SGD。如果優化不動可以試試Adam。

·
激活函數。可以先用ReLU做一版,如果想再提升精度可以將ReLU改成PReLU試試。更傾向於直接使用ReLU。

·
batch_size:在不同類型的任務中,batch_size的影響也不同, Batch_size是怎麼影響模

型性能的。

·
初始學習率。一般是從0.01開始設置,這個學習率和學習率衰減策略是相關的,但不宜設置的過大過小,0.01和0.1應該是比較常用的。學習率衰減策略一般使用multistep方式,step_size的設置要看視的的max_iter而定。

·
數據與處理之zero-center。第一次見到這個詞是在看cs231n的視頻上。主要有2個步驟,第一個是減均值,第二個是除以方差。這樣做下來最後的輸入是滿足均值爲0方差爲1的概率分佈的,一般減均值是最常用的,後面的除以方差用不用可能需要自己動手試驗一下看看效果。

·
殘差結構和密集連接。resnet的殘差結構和dense net密集連接結構,做工程的時候考慮到速度近乎不可能說完全使用完整版本的resnet和densenet的完整結構,但可以自己動手將網絡的某些模塊替換爲殘差結構和密集連接,替換的時候可以適當降低這倆結構的複雜度,類似於通道數減半,密集連接中只保留一半連接等等。這裏需要做一些消融實驗來驗證改進後的精度。

·
關於loss。優秀的loss一般是對模型的泛化性能有所改善的,但在用loss的時候往往並不是直接替換loss那麼簡單,需要仔細思考loss背後的數學原理,要用對地方纔可有提升。例如,如何將Focal Loss用到YOLOv3中提升map,大家可以看看這個帖子。https://www.zhihu.com/question/293369755。

·
找到模型調參時的可靠評價指標。在調整參數訓練模型時一定要找到正確的評價指標,沒調整一個參數就要記錄一下模型的評價指標如準確率,map值,miou值等。並且在調參時建議將調整的參數和在測試集上的精度組合成一個字符串給模型重命令,方便之後快速review。

·
使用了帶backbone的網絡,如訓練VGG16-SSD建議選擇finetune的方式,從頭訓練不僅費時費力,甚至難以收斂。

·
在做分割實驗的時候發現用upsamling 加1*1卷積代替反捲積做上採樣得到的結果更平滑,並且miou差距不大,所以認爲這兩者都是都可以使用的。

·
一些Anchor-based目標檢測算法爲了提高精度,都是瘋狂給框,ap值確實上去了,但也導致了fp會很多,並且這部分fp沒有迴歸,在nms階段也濾不掉。相比於ap提升而言,工程上減少fp更加重要。Gaussian
yolov3的fp相比於yolov3會減少40%,Anchor-free算法暫時接觸得不多,就不太瞭解了。

·
特徵提取。VGG16,VGG19,ResNet50,Xception是非常好用的幾個特徵提取模型。建議使用訓練好的經典模型對數據集提取特徵向量存儲到本地,更方便使用,同時可以大幅度降低顯存消耗。

·
ensemble:

o 將不同的經典網絡提取出的特徵向量,假設VGG16提取出的特徵向量維度是N,c1],ResNet50提取的特徵向量維度是[N,c2],Xception提取的特徵向量維度是[N, c3],那麼可以使用三個係數a、b、c將其組合爲形狀爲[N, ac1+bc2+c*c3],其中a、b、c三個參數的取值代表使用哪個模型的特徵多一些,如果是分類迴歸比賽,在後面接特徵處理網絡就可以了。可以取不同的a、b、c得到不同的特徵,然後對結果做voting,soft-voting等多種處理,一般結果不會太差啦。

o 可以使用不同的初始化方式訓練出模型,然後做ensemble。

o 可以使用用不同超參數(如學習率,batch_size,優化器)訓練出不同模型,然後做ensemble。

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