如何更好地調(diào)整學(xué)習(xí)率
【GiantPandaCV導(dǎo)讀】learning rate對模型調(diào)優(yōu)重要性不言而喻,想到超參數(shù)調(diào)優(yōu)第一個可能想到的方法就是網(wǎng)格搜索Grid Search,但是這種方法需要大量的計算資源。之前使用fastai的時候發(fā)現(xiàn)其集成了一個功能叫l(wèi)r_finder(), 可以快速找到合適的學(xué)習(xí)率,本文就主要分析這個15年就提出來的技術(shù)Cyclical Learning Rates。
鏈接:https://arxiv.org/abs/1506.01186

1. 前言
一般學(xué)習(xí)率可以人工設(shè)置,根據(jù)經(jīng)驗進行設(shè)置。通常會嘗試初始學(xué)習(xí)率為0.1 0.01 0.001 0.0001等來觀察初始階段loss收斂情況。
lr過大會導(dǎo)致loss爆炸
lr過小會導(dǎo)致loss下降過于緩慢
warmup可以防止模型過于震蕩,在小學(xué)習(xí)率的warmup下可以讓模型趨于穩(wěn)定,這樣可以使模型收斂速度變快、模型效果更佳。
finetune時候需要用到的learning rate往往比較小,因為backbone部分的權(quán)重已經(jīng)固定,所以微調(diào)部分權(quán)重不需要太大的學(xué)習(xí)率。
除了人工設(shè)置learning rate還可以用以下方法:
grid search: 網(wǎng)格搜索最合適的learning rate,這種方法代價比較大,比如舊版的yolov3中就使用了這種grid search的策略,如果計算資源不夠的情況下往往很難找到最好的參數(shù)。
random search:采用隨機的方法進行搜索,在一定區(qū)間內(nèi)產(chǎn)生隨機點,找到最優(yōu)解的近似解。
heuristically search:啟發(fā)搜索可以通過利用啟發(fā)信息來引導(dǎo)搜索,減少搜索范圍,降低問題復(fù)雜度,從而可以減少對計算資源的需求,提高了搜索效率。啟發(fā)式搜索有模擬退火算法、遺傳算法、進化規(guī)劃、蟻群算法、貝葉斯優(yōu)化。
一些推薦的調(diào)參包:
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 選擇一個合適的初始學(xué)習(xí)率
使用CLR可以在CIFAR10數(shù)據(jù)集上達到以下效果:

可以看出CLR可以讓模型收斂速度加快,在更少的迭代下收斂到更高的精度,并且集成到了fastai中,可見這種方法得到了認可。
learning rate在很多scheduler中并不是一直不變的,而是不斷上升和下降,雖然這種調(diào)整方法短期內(nèi)來看對模型性能有不利影響,但是長期來看對最終性能是有幫助的。
一般來說,學(xué)習(xí)率會被設(shè)置在一個最大值、最小值的范圍內(nèi),并且學(xué)習(xí)率在這些邊界之間進行循環(huán)變化,變化方式有以下幾種:
triangular window,即線性的變換learning rate
Welch window,即拋物線狀變換learning rate
Hann window,即正弦變換learning rate
實驗發(fā)現(xiàn)這幾種方法并沒有差異非常明顯,所以本文以最簡單的triangular window作為基準,如下圖所示:

通常認為loss優(yōu)化最困難的地方在于鞍點,而不是局部最小值,鞍點梯度過小所以會讓學(xué)習(xí)的過程變慢。這個時候增大學(xué)習(xí)率可以讓模型越過鞍點。以上理論就是CLR的一個直觀的理解,為此需要不斷動態(tài)調(diào)整learning rate的大小。
代碼實現(xiàn):
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有一個直觀理解以后,還有一個關(guān)鍵問題需要解決:** 如何確定learning rate最大值和最小值?**
LR range test 可以用來解決這個問題,即通過增加學(xué)習(xí)率觀察結(jié)果的方式來判斷最大值和最小值。通過不斷增加學(xué)習(xí)率以及對應(yīng)的結(jié)果可以得到accuracy vs learning rate圖或者loss vs learning rate圖。
這里借用:https://blog.csdn.net/m0_37477175/article/details/89395050 中的圖示。

base_lr的設(shè)置:base_lr要選擇loss圖剛開始下降的點,上圖就是0.001。
max_lr的設(shè)置: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. 代碼實現(xiàn)
keras 版本實現(xiàn)詳見:https://github.com/bckenstler/CLR
pytorch版本實現(xiàn):https://github.com/weiaicunzai/pytorch-cifar100
筆者使用pytorch版跑的結(jié)果如下,通過下圖可以判斷base_lr=1e-5 max_lr=1e-3

最后推薦一個可玩性很高的網(wǎng)站:https://losslandscape.com/explorer 你可以選取一個初始點,然后進行隨機梯度下降,通過調(diào)整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
歡迎添加筆者微信,進群交流
