如何更好地調整學習率?

【GiantPandaCV導讀】learning rate對模型調優重要性不言而喻,想到超參數調優第一個可能想到的方法就是網格搜索Grid Search,但是這種方法需要大量的計算資源。之前使用fastai的時候發現其集成了一個功能叫lr_finder(), 可以快速找到合適的學習率,本文就主要分析這個15年就提出來的技術Cyclical Learning Rates。

鏈接:https://arxiv.org/abs/1506.01186

1. 前言

一般學習率可以人工設置,根據經驗進行設置。通常會嘗試初始學習率爲0.1 0.01 0.001 0.0001等來觀察初始階段loss收斂情況。

  • lr過大會導致loss爆炸

  • lr過小會導致loss下降過於緩慢

  • warmup可以防止模型過於震盪,在小學習率的warmup下可以讓模型趨於穩定,這樣可以使模型收斂速度變快、模型效果更佳。

  • finetune時候需要用到的learning rate往往比較小,因爲backbone部分的權重已經固定,所以微調部分權重不需要太大的學習率。

除了人工設置learning rate還可以用以下方法:

  • grid search: 網格搜索最合適的learning rate,這種方法代價比較大,比如舊版的yolov3中就使用了這種grid search的策略,如果計算資源不夠的情況下往往很難找到最好的參數。

  • random search:採用隨機的方法進行搜索,在一定區間內產生隨機點,找到最優解的近似解。

  • heuristically search:啓發搜索可以通過利用啓發信息來引導搜索,減少搜索範圍,降低問題複雜度,從而可以減少對計算資源的需求,提高了搜索效率。啓發式搜索有模擬退火算法、遺傳算法、進化規劃、蟻羣算法、貝葉斯優化。

一些推薦的調參包:

Hyperopt: https://github.com/hyperopt/hyperopt

Optunity: https://github.com/claesenm/optunity

Advisor: https://github.com/tobegit3hub/advisor

NNI: https://github.com/microsoft/nni

2. CLR 選擇一個合適的初始學習率

使用CLR可以在CIFAR10數據集上達到一下效果:

可以看出CLR可以讓模型收斂速度加快,在更少的迭代下收斂到更高的精度,並且集成到了fastai中,可見這種方法得到了認可。

learning rate在很多scheduler中並不是一直不變的,而是不斷上升和下降,雖然這種調整方法短期內來看對模型性能有不利影響,但是長期來看對最終性能是有幫助的。

一般來說,學習率會被設置在一個最大值、最小值的範圍內,並且學習率在這些邊界之間進行循環變化,變化方式有以下幾種:

  • triangular window,即線性的變換learning rate

  • Welch window,即拋物線狀變換learning rate

  • Hann window,即正弦變換learning rate

實驗發現這幾種方法並沒有差異非常明顯,所以本文以最簡單的triangular window作爲基準,如下圖所示:

通常認爲loss優化最困難的地方在於鞍點,而不是局部最小值,鞍點梯度過小所以會讓學習的過程變慢。這個時候增大學習率可以讓模型越過鞍點。 以上理論就是CLR的一個直觀的理解,爲此需要不斷動態調整learning rate的大小。

代碼實現:

cycle = np.floor(1+iterations/(2*step_size))
x = np.abs(iterations/step_size - 2*cycle + 1)
lr= base_lr + (max_lr-base_lr)*np.maximum(0, (1-x))*scale_fn(x)

參考自:https://github.com/bckenstler/CLR

對CLR有一個直觀理解以後,還有一個關鍵問題需要解決:** 如何確定learning rate最大值和最小值?**

LR range test 可以用來解決這個問題,即通過增加學習率觀察結果的方式來判斷最大值和最小值。通過不斷增加學習率以及對應的結果可以得到accuracy vs learning rate圖或者loss vs learning rate圖。

這裏借用:https://blog.csdn.net/m0_37477175/article/details/89395050 中的圖示。

  • base_lr的設置:base_lr要選擇loss圖剛開始下降的點,上圖就是0.001。

  • max_lr的設置:max_lr要選擇loss圖開始上升的位置,上圖就是0.1。

再舉一個例子,來自https://github.com/bckenstler/CLR 這個庫提供的例子。

這個圖展示的是accuracy vs learning rate,和loss正好相反:

  • base_lr:選擇acc剛開始上升的點,這裏選擇0.001

  • max_lr:選擇acc剛開始緩和的點,這裏選擇0.006

3. 代碼實現

keras 版本實現詳見:https://github.com/bckenstler/CLR

pytorch版本實現:https://github.com/weiaicunzai/pytorch-cifar100

筆者使用pytorch版跑的結果如下,通過一下圖可以判斷base_lr=1e-5 max_lr=1e-3

最後推薦一個可玩性很高的網站:https://losslandscape.com/explorer 你可以選取一個初始點,然後進行隨機梯度下降,通過調整learning rate可以看到收斂情況,也就是下圖黃色的線。

4. Reference

https://www.fast.ai/2020/02/13/fastai-A-Layered-API-for-Deep-Learning/#ref-lrfinder

https://arxiv.org/abs/1506.01186

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

https://github.com/bckenstler/CLR

https://blog.csdn.net/m0_37477175/article/details/89395050

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