【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)
對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