【學習筆記】Pytorch深度學習—優化器(二)
前面學習過了Pytorch中優化器optimizer的基本屬性和方法,優化器optimizer的主要功能是 “管理模型中的可學習引數,並利用引數的梯度grad以一定的策略進行更新”。本節內容分為4部分,(1)、(2)首先了解2個重要概念Learning rate學習率和momentum動量,(3)在此基礎上,學習Pytorch中的SGD隨機梯度下降優化器;(4)最後,瞭解Pytorch提供的十種優化器。
learning rate 學習率
上節課優化器(一)講過梯度下降法的更新思路,也就是要求損失函式Loss或者引數朝著梯度的負方向去變化。為了更好的理解梯度下降法,下面給出一個例子。
引例:
圖1 梯度下降法公式應用
然而,從上面的例子中可以看出梯度下降法不僅沒能使得y(或Loss值)降低至0甚至使得y變得更大了。
引例實驗
程式碼演示梯度下降法全過程。
構造“損失函式”
繪製函式\(y=4x^2\)影象,該y值可類比為Loss值,梯度下降法的目的在於使得Loss值逐步降低至0。
圖2 構造損失函式曲線
迭代更新部分
此外,當前梯度下降法公式還沒有考慮到學習率lr的影響,因此下述實驗學習率不設定即為lr=1,最大迭代引數為4。
# -------------- gradient descent ------------- flag = 1 if flag: iter_rec, loss_rec, x_rec = list(), list(), list() //當前公式還沒有考慮學習率的影響,因此該引數lr設為 1 lr = 1 # /1. /.5 /.2 /.1 /.125 //迭代次數設為 4 max_iteration = 4 # /1. 4 /.5 4 /.2 20 200 for i in range(max_iteration): //輸入x 計算 Loss y = func(x) //反向傳播計算梯度 y.backward() print("Iter:{}, X:{:8}, X.grad:{:8}, loss:{:10}".format( i, x.detach().numpy()[0], x.grad.detach().numpy()[0], y.item())) x_rec.append(x.item()) //這裡的x.data.sub_的 inplace操作可完成引數的更新 x.data.sub_(lr * x.grad) # x -= x.grad 數學表示式意義: x = x - x.grad # 0.5 0.2 0.1 0.125 //執行更新之後,對引數的梯度進行清零 x.grad.zero_() iter_rec.append(i) loss_rec.append(y)
對損失函式使用梯度下降法的輸出結果
從圖3可以看出,迭代4次,Loss值不僅沒有降低反而升高到了188萬,同時最終引數x的梯度值也達到了\(10^3\),直接引發了梯度爆炸現象。
圖3 對上述函式使用梯度下降法輸出結果
學習率
為什麼使用了梯度下降法,Loss值並沒有減小反而增大?
觀察圖1所示梯度下降法的求解過程,可以看出每次迭代時由於梯度grad()較大,從而引起新的引數變大進而導致Loss函式值不降反升,梯度爆炸等現象。因此,為了控制引數更新的步伐,就在原本的公式基礎上引入了學習率LR,如下所示。
實驗
依次設定學習率為0.5、0.2、0.1、0.125,觀察Loss函式值及函式曲線變化情況
# ------------------ gradient descent -------------
flag = 1
if flag:
iter_rec, loss_rec, x_rec = list(), list(), list()
//當前公式還沒有考慮學習率的影響,因此該引數lr設為 1
lr = 0.5 # /0.5 /0.2 /0.1 /0.125
//迭代次數設為 4
max_iteration = 4 # /1. 4 /.5 4 /.2 20 200
for i in range(max_iteration):
//輸入x 計算 Loss
y = func(x)
//反向傳播計算梯度
y.backward()
print("Iter:{}, X:{:8}, X.grad:{:8}, loss:{:10}".format(
i, x.detach().numpy()[0], x.grad.detach().numpy()[0], y.item()))
x_rec.append(x.item())
//這裡的x.data.sub_的 inplace操作可完成引數的更新
x.data.sub_(lr * x.grad) # x -= x.grad 數學表示式意義: x = x - x.grad # 0.5 0.2 0.1 0.125
//執行更新之後,對引數的梯度進行清零
x.grad.zero_()
iter_rec.append(i)
loss_rec.append(y)
實驗結果
如果預先能知道損失函式Loss的函式表示式,就可以預先求得在學習率為0.125時,Loss就可以直接下降為0。但是通常,是不可能獲得損失函式表示式的,因此0.125並不能直接求得。那麼,該如何設定學習率呢?下面觀察多個學習率之間Loss的變化情況。
多個學習率之間Loss變化情況
實驗結果
圖4 多學習率Loss曲線的變化情況
< 總結 >
學習率
功能:用來控制更新的步伐
使用:設定學習率時,不能過大否則導致梯度爆炸、Loss值激增現象,也不能太小,這樣就導致Loss值很難收斂。
通常設定為0.01.
學習率用來控制更新的步伐;在設定學習率時,不能過大比如0.5、0.3如圖4(1)可能導致梯度爆炸、Loss值激增現象;學習率也不能太小,這樣就導致Loss值很難收斂,進入收斂需要花費大量時間。
momentum 動量
在優化器中除了學習率還有momentum動量
Momentum(動量、衝量)
結合當前梯度與上一次更新資訊,用於當前更新
< 預備知識 >
指數加權平均是在時間序列中經常使用的求取平均值的方法,其思想:求取當前時刻的平均值,距離當前時刻越近的引數值參考性越大,所佔的權重也就越大,這些權重隨著時間間隔增大是成指數下降的。
如下圖5所示討論了指數加權平均的計算原理,根據一溫度散點圖,列寫了其計算式。
圖5 指數加權平均計算原理
圖6 距離當前時刻越遠權重成指數衰減下降
由於\(\beta\)控制著權重的記憶週期,\(\beta\)值越小,記憶週期越長,作用越遠;通常,會設定beta=0.9,beta=0.9的物理意義是更加關注當前時刻10天左右的資料。(\(\frac{1}{(1-\beta)}=\frac{1}{1-0.9}=10\))
通過上述例子,瞭解到指數加權平均中具有1個非常重要的引數\(\beta\),該\(\beta\)對應到梯度下降中就是momentum係數。
< momentum加入,隨機梯度下降公式更新 >
瞭解了momentum係數,下面就給出Pytorch中加入了momentum係數後,隨機梯度下降中更新公式:
①僅考慮學習率的梯度下降:
\[w_{i+1}=w_i-lr*g(w_i) \]
②加入momentum係數後隨機梯度下降更新公式:
\[v_{i}=m*v_{i-1}+*g(w_i) \]
\[w_{i+1}=w_i+lr*v_{i} \]
\(w_{i+1}\):第i+1次更新的引數;\(lr\):學習率;\(v_i\):更新量,\(m\):momentum係數,對應指數加權平均就是\(\beta\)值;\(g(w_i)\):\(w_i的梯度\)
更新公式不再乘以梯度而是更新量\(v_i\),該更新量\(v_i\)由兩部分構成,不僅有當前的梯度資訊\(g(w_i)\)還有上一時刻的更新資訊。
<更新公式實驗>
下面進行帶上momentum的隨機梯度下降實驗,觀察Loss的變化。具體操作是:觀察1個較小學習率0.01和1個較大學習率0.03 和 其中1個加了momentum後,觀察兩種情況下的Loss曲線。
圖7 實驗結果分析
圖8 實驗結果分析
最後,嘗試了多次momentum,直到momentum=0.63時,學習率為0.01的Loss比學習率為0.03的Loss更快收斂。設定合適mometum係數,考慮當前梯度資訊結合之前的梯度資訊,可以加速更新模型引數。
Momentum(動量、衝量)
結合當前梯度與上一次更新資訊,用於當前引數,從而實現慣性思想,加速模型收斂。
torch.optim.SGD
Pytorch中提供的最常用、實用的優化器SGD
optim.SGD(params,lr=<object object>,
momentum=0,dampening=0,
weight_decay=0,nesterov=False)
主要引數:
params:管理的引數組
lr:初始學習率
momentum:動量係數,beta
weight_decay:L2正則化係數
nesterov:是否採用NAG
解釋
(1)params(optimizer屬性param_groups):管理的引數組引數組是1個list,其中的每1個元素是dict,dict中又很多key,這些key中最重要的是params——其中的value就是管理的引數
;
(2)weight_decay:用來設定L2正則化係數;
(3)nesterov:布林變數,通常設定為False,控制是否採用NAG這一梯度下降方法,參考 《 On the importance of initialization and momentum in deep learning》
Pytorch的十種優化器
1、optim.SGD:隨機梯度下降法
2、optim.Adagrad:自適應學習率梯度下降法(對每個可學習引數具有1個自適應學習率)
3、optim.RMSprop:Adagrad的改進
4、optim.Adadelta:Adagrad的改進
5、optim.Adam:RMSprop結合Momentum
6、optim.Adamax:Adam增加學習率上限
7、optim.SparseAdam:稀疏版Adam
8、optim.ASGD:隨機平均梯度下降
9、optim.Rprop:彈性反向傳播(優化器應用場景在所有樣本full_batch 一起計算梯度)
10、optim.LBFGS:BFGS的改進
圖9 其他優化器相關文獻
PS:大部分任務的模型都可以採用SGD優化,其次,Adam優化器也比較常用,Adam優化器可以使用較大的學習率。