AI小知識系列(二) 訓練過程Trick合集

1. 寫代碼之前要做的事情

訓練神經網絡前,別管代碼,先從預處理數據集開始。我們先花幾個小時的時間,瞭解數據的分佈並找出其中的規律

Andrej有一次在整理數據時發現了重複的樣本,還有一次發現了圖像和標籤中的錯誤。所以先看一眼數據能避免我們走很多彎路。

由於神經網絡實際上是數據集的壓縮版本,因此您將能夠查看網絡(錯誤)預測並瞭解它們的來源。如果你的網絡給你的預測看起來與你在數據中看到的內容不一致,那麼就會有所收穫。

一旦從數據中發現規律,可以編寫一些代碼對他們進行搜索、過濾、排序。把數據可視化能幫助我們發現異常值,而異常值總能揭示數據的質量或預處理中的一些錯誤。

2.設置端到端的訓練評估框架

處理完數據集,接下來就能開始訓練模型了嗎?並不能!下一步是建立一個完整的訓練+評估 框架。

在這個階段,我們選擇一個簡單又不至於搞砸的模型,比如線性分類器、CNN,可視化損失。獲得準確度等衡量模型的標準,用模型進行預測。

1)固定隨機種子

使用固定的隨機種子,來保證運行代碼兩次都獲得相同的結果,消除差異因素。

2)簡單化

在此階段不要有任何幻想,不要擴增數據。擴增數據後面會用到,但是在這裏不要使用,現在引入只會導致錯誤。

3)繪製測試集損失

在繪製測試集損失時,對整個測試集進行評估,不要只繪製批次測試損失圖像,然後用Tensorboard對它們進行平滑處理。

4)在初始階段驗證損失函數

驗證函數是否從正確的損失值開始。例如,如果正確初始化最後一層,則應在softmax初始化時測量-log(1/n_classes)。

5)初始化

正確初始化最後一層的權重。如果迴歸一些平均值爲50的值,則將最終偏差初始化爲50。如果有一個比例爲1:10的不平衡數據集,請設置對數的偏差,使網絡預測概率在初始化時爲0.1。正確設置這些可以加速模型的收斂。

6)人類基線

監控除人爲可解釋可檢查的損失之外的指標。儘可能評估人的準確性並與之進行比較。或者對測試數據進行兩次註釋,並且對於每個示例,將一個註釋視爲預測,將第二個註釋視爲事實。

7)設置一個獨立於輸入的基線

最簡單的方法是將所有輸入設置爲零,看看模型是否學會從輸入中提取任何信息。

8)過擬合一個batch

增加了模型的容量並驗證我們可以達到的最低損失。

9)驗證減少訓練損失

嘗試稍微增加數據容量。

10)在訓練模型前進行數據可視化

將原始張量的數據和標籤可視化,可以節省了調試次數,並揭示了數據預處理和數據擴增中的問題。

11)可視化預測動態

在訓練過程中對固定測試批次上的模型預測進行可視化。

12)使用反向傳播來獲得依賴關係

一個方法是將第i個樣本的損失設置爲1.0,運行反向傳播一直到輸入,並確保僅在第i個樣本上有非零的梯度。

3.挑選模型

首先我們得有一個足夠大的模型,它可以過擬合,減少訓練集上的損失,然後適當地調整它,放棄一些訓練集損失,改善在驗證集上的損失)

1)挑選模型

爲了獲得較好的訓練損失,我們需要爲數據選擇合適的架構。不要總想着一步到位。如果要做圖像分類,只需複製粘貼ResNet-50,我們可以在稍後的過程中做一些自定義的事。

2)Adam方法是安全的

在設定基線的早期階段,使用學習率爲3e-4的Adam 。根據經驗,Adam對超參數更加寬容,包括不良的學習率。

3)一次只複雜化一個

如果多個信號輸入分類器,建議逐個輸入,然後增加複雜性,確保預期的性能逐步提升,而不要一股腦兒全放進去。比如,嘗試先插入較小的圖像,然後再將它們放大。

4)學習率設置

初始的學習率肯定是有一個最優值的,過大則導致模型不收斂,過小則導致模型收斂特別慢或者無法學習

可以採用搜索法,從小到大開始訓練模型,記錄損失的變化,比如從1e-5增大到1

也可以採用預設規則學習率變化法,見的策略包括fixed,step,exp,inv,multistep,poly,sigmoid等

從結果來看:
  • step,multistep方法的收斂效果最好,這也是我們平常用它們最多的原因。雖然學習率的變化是最離散的,但是並不影響模型收斂到比較好的結果。
  • 其次是exp,poly。它們能取得與step,multistep相當的結果,也是因爲學習率以比較好的速率下降,雖然變化更加平滑,但是結果也未必能勝過step和multistep方法,在這很多的研究中都得到過驗證,離散的學習率變更策略不影響模型的學習。
  • inv和fixed的收斂結果最差。這是比較好解釋的,因爲fixed方法始終使用了較大的學習率,而inv方法的學習率下降過程太快。

實驗證明通過設置上下界,讓學習率在其中進行變化,可以在模型迭代的後期更有利於克服因爲學習率不夠而無法跳出鞍點的情況。

5)每輪訓練數據亂序

每輪數據迭代保持不同的順序,避免模型每輪都對相同的數據進行計算。

6)batch_size選擇

模型性能對batchsize雖然沒有學習率那麼敏感,但是在進一步提升模型性能時,batchsize就會成爲一個非常關鍵的參數。

  • 大的batchsize減少訓練時間,提高穩定性導致模型泛化能力下降

對於小數據量的模型,可以全量訓練,這樣能更準確的朝着極值所在的方向更新。但是對於大數據,全量訓練將會導致內存溢出,因此需要選擇一個較小的batch_size。如果這時選擇batch_size爲1,則此時爲在線學習,每次修正方向爲各自樣本的梯度方向修正,難以達到收斂。batch_size增大,處理相同數據量的時間減少,但是達到相同精度的輪數增多。實際中可以逐步增大batch_size,隨着batch_size增大,模型達到收斂,並且訓練時間最爲合適。

7)學習率和batchsize的關係

通常當我們增加batchsize爲原來的N倍時,要保證經過同樣的樣本後更新的權重相等,按照線性縮放規則,學習率應該增加爲原來的N倍[5]。但是如果要保證權重的方差不變,則學習率應該增加爲原來的sqrt(N)倍[7],目前這兩種策略都被研究過,使用前者的明顯居多。

從兩種常見的調整策略來看,學習率和batchsize都是同時增加的。學習率是一個非常敏感的因子,不可能太大,否則模型會不收斂。同樣batchsize也會影響模型性能,那實際使用中都如何調整這兩個參數呢?

研究表明,衰減學習率可以通過增加batchsize來實現類似的效果,這實際上從SGD的權重更新式子就可以看出來兩者確實是等價的,文中通過充分的實驗驗證了這一點。

研究表明,對於一個固定的學習率,存在一個最優的batchsize能夠最大化測試精度,這個batchsize和學習率以及訓練集的大小正相關。

對此實際上是有兩個建議:

  • 如果增加了學習率,那麼batch size最好也跟着增加,這樣收斂更穩定。
  • 儘量使用大的學習率,因爲很多研究都表明更大的學習率有利於提高泛化能力。如果真的要衰減,可以嘗試其他辦法,比如增加batch size,學習率對模型的收斂影響真的很大,慎重調整

4.正則化

理想的話,我們現在有一個大模型,在訓練集上擬合好了。

現在,該正則化了。捨棄一點訓練集上的準確率,可以換取驗證集上的準確率。

1)獲取更多數據

至今大家最偏愛的正則化方法,就是添加一些真實訓練數據。

不要在一個小數據集花太大功夫,試圖搞出大事情來。有精力去多收集點數據,這是唯一一個確保性能單調提升的方法。

2)數據擴增

把數據集做大,除了繼續收集數據之外,就是擴增了。旋轉,翻轉,拉伸,做擴增的時候可以野性一點。
可參考數據增強方法

3)有創意的擴增

還有什麼辦法擴增數據集?比如域隨機化 (Domain Randomization) ,模擬 (Simulation) ,巧妙的混合 (Hybrids) ,比如把數據插進場景裏去。甚至可以用上GAN。

4)預訓練

當然,就算你手握充足的數據,直接用預訓練模型也沒壞處。

5)跟監督學習死磕

不要對無監督預訓練太過興奮了。至少在視覺領域,無監督到現在也沒有非常強大的成果。雖然,NLP領域有了BERT,有了會講故事的GPT-2,但我們看到的效果很大程度上還是經過了人工挑選。

6)輸入低維一點

把那些可能包含虛假信號的特徵去掉,因爲這些東西很可能造成過擬合,尤其是數據集不大的時候。

同理,如果低層細節不是那麼重要的話,就輸入小一點的圖片,捕捉高層信息就好了。

7)模型小一點

許多情況下,都可以給網絡加上領域知識限制 (Domain Knowledge Constraints) ,來把模型變小。

比如,以前很流行在ImageNet的骨架上放全連接層,但現在這種操作已經被平均池化取代了,大大減少了參數。

8)減小批尺寸

對批量歸一化 (Batch Normalization) 這項操作來說,小批量可能帶來更好的正則化效果 (Regularization) 。

9)Dropout

給卷積網絡用dropout2d。不過使用需謹慎,因爲這種操作似乎跟批量歸一化不太合得來。

10)權重衰減Weight Decay

增加權重衰減 (Weight Decay) 的懲罰力度。

L2正則化的目的就是爲了讓權重衰減到更小的值,在一定程度上減少模型過擬合的問題,所以權重衰減也叫L2正則化。

11)早停法Early Stop

不用一直一直訓練,可以觀察驗證集的損失,在快要過擬合的時候,及時喊停。

12)附加

大模型很容易過擬合,幾乎是必然,但早停的話,模型可以表現很好。

最後的最後,如果想要更加確信,自己訓練出的網絡,是個不錯的分類器,就把第一層的權重可視化一下,看看邊緣 (Edges) 美不美。

如果第一層的過濾器看起來像噪音,就需要再搞一搞了。同理,激活 (Activations) 有時候也會看出瑕疵來,那樣就要研究一下哪裏出了問題。

5.調參

1)隨機網格搜索

在同時調整多個超參數的情況下,網格搜索聽起來是很誘人,可以把各種設定都包含進來。

但是要記住,隨機搜索纔是最好的。

直覺上說,這是因爲網絡通常對其中一些參數比較敏感,對其他參數不那麼敏感。

如果參數a是有用的,參數b起不了什麼作用,就應該對a取樣更徹底一些,不要只在幾個固定點上多次取樣。

2)超參數優化

世界上,有許多許多靚麗的貝葉斯超參數優化工具箱,很多小夥伴也給了這些工具好評。

但我個人的經驗是,State-of-the-Art都是用實習生做出來的 (誤) 。

6.測試階段

1)模型融合

2)TTA測試時增強

測試時將原始數據做不同形式的增強,然後取結果的平均值作爲最終結果

提高了結果的穩定性和精準度.

參考博客

https://zhuanlan.zhihu.com/p/64864995

https://zhuanlan.zhihu.com/p/63841572

http://karpathy.github.io/2019/04/25/recipe/

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