學習率是神經網絡訓練中最重要的超參數之一,針對學習率的優化方式很多,Warmup是其中的一種
(一)、什么是Warmup?
Warmup是在ResNet論文中提到的一種學習率預熱的方法,它在訓練開始的時候先選擇使用一個較小的學習率,訓練了一些epoches或者steps(比如4個epoches,10000steps),再修改為預先設置的學習來進行訓練。
(二)、為什么使用Warmup?
由於剛開始訓練時,模型的權重(weights)是隨機初始化的,此時若選擇一個較大的學習率,可能帶來模型的不穩定(振盪),選擇Warmup預熱學習率的方式,可以使得開始訓練的幾個epoches或者一些steps內學習率較小,在預熱的小學習率下,模型可以慢慢趨於穩定,等模型相對穩定后再選擇預先設置的學習率進行訓練,使得模型收斂速度變得更快,模型效果更佳。
ExampleExampleExample:Resnet論文中使用一個110層的ResNet在cifar10上訓練時,先用0.01的學習率訓練直到訓練誤差低於80%(大概訓練了400個steps),然后使用0.1的學習率進行訓練。
(三)、Warmup的改進
(二)所述的Warmup是constant warmup,它的不足之處在於從一個很小的學習率一下變為比較大的學習率可能會導致訓練誤差突然增大。於是18年Facebook提出了gradual warmup來解決這個問題,即從最初的小學習率開始,每個step增大一點點,直到達到最初設置的比較大的學習率時,采用最初設置的學習率進行訓練。
1.gradual warmup的實現模擬代碼如下:
""" Implements gradual warmup, if train_steps < warmup_steps, the learning rate will be `train_steps/warmup_steps * init_lr`. Args: warmup_steps:warmup步長閾值,即train_steps<warmup_steps,使用預熱學習率,否則使用預設值學習率 train_steps:訓練了的步長數 init_lr:預設置學習率 """ import numpy as np warmup_steps = 2500 init_lr = 0.1 # 模擬訓練15000步 max_steps = 15000 for train_steps in range(max_steps): if warmup_steps and train_steps < warmup_steps: warmup_percent_done = train_steps / warmup_steps warmup_learning_rate = init_lr * warmup_percent_done #gradual warmup_lr learning_rate = warmup_learning_rate else: #learning_rate = np.sin(learning_rate) #預熱學習率結束后,學習率呈sin衰減 learning_rate = learning_rate**1.0001 #預熱學習率結束后,學習率呈指數衰減(近似模擬指數衰減) if (train_steps+1) % 100 == 0: print("train_steps:%.3f--warmup_steps:%.3f--learning_rate:%.3f" % ( train_steps+1,warmup_steps,learning_rate))
2.上述代碼實現的Warmup預熱學習率以及學習率預熱完成后衰減(sin or exp decay)的曲線圖如下:
(四)總結
使用Warmup預熱學習率的方式,即先用最初的小學習率訓練,然后每個step增大一點點,直到達到最初設置的比較大的學習率時(注:此時預熱學習率完成),采用最初設置的學習率進行訓練(注:預熱學習率完成后的訓練過程,學習率是衰減的),有助於使模型收斂速度變快,效果更佳。