一、概念
Pytorch中優化器的目的:將損失函數計算出的差值Loss減小。
優化過程:優化器計算網絡參數的梯度,然后使用一定的算法策略來對參數進行計算,用新的參數來重新進行訓練,最終降低Loss。
其中官網提供了13種優化算法,其中主要的有5種:SGD(stochastic gradient descent 隨機梯度下降),Adagrad(自適應梯度算法),Adam(Adaptive Moment Estimation 自適應矩估計),RMSprop(Root Mean Square Prop 均方根),LBFGS(Limited-memory Broyden–Fletcher–Goldfarb–Shanno 有限內存中進行BFGS算法),其他均為改進算法,比如Adadelta是Adagrad的改進算法。
其中還有很多算法細節可能后續會慢慢補充。
二、介紹和示例
2.1 SGD算法
SGD算法可實現隨機梯度下降(可選動量)。
torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False)
params:可迭代參數以優化或定義參數組。
lr:初始學習率,可隨著訓練過程不斷調整學習率。
momentum:動量,通常設置為0.9,0.8。momentum又稱為動量梯度下降。
dampening:動量阻尼,默認為0。
weight_decay:權值衰減系數,即L2正則化。
nesterov:啟用牛頓動量。Nesterov是Momentum的變種,就是梯度的計算方法有所不同,先用當前的速度v更新一遍權重θ,然后用更新參數p計算梯度g。
動量法:
nesterov:
learning_rate = 1e-2
optim = torch.optim.SGD(wzh.parameters(), lr=learning_rate, momentum=0.9, weight_decay=1e-2)# 優化器調優
optim.zero_grad()
loss.backward()
optim.step()
2.2、Adagrad
Adagrad算法可以自適應的給所有的參數分配學習率,學習率的大小與梯度的大小成反比。
torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0, initial_accumulator_value=0, eps=1e-10)
lr_decay:學習率衰減因子,默認為0。
eps :將其添加到分母以提高數值穩定性,默認值為1e-10,其主要的作用是避免分母為0.
optim1 = torch.optim.Adagrad(wzh.parameters(), lr=learning_rate, lr_decay=0, weight_decay=0.01,initial_accumulator_value=0, eps=1e-10)
2.3 RMSprop
RMSprop算法是Adagrad的改進形式,特點是使用指數衰減滑動平均來更新梯度平方,以避免Adagrad累計梯度平方導致學習率過小的缺點。
torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)
alpha:平滑常數,默認為0.99。
centered:如果為真,計算中心 RMSProp,梯度通過其方差的估計進行歸一化。
由官網給出的公式可以看出,用α的值來更新梯度平方。
optim2 = torch.optim.RMSprop(wzh.parameters(), lr=learning_rate, alpha=0.99, eps=1e-8, weight_decay=0.01,momentum=0, centered=False)
2.4 Adam
Adam算法結合了RMSProp和Momentum的算法思路,由公式可以看出,分別用m和v兩個動量來對梯度進行計算,可以說是目前應用相當廣泛的優化器算法。
betas:用于計算梯度及其平方的運行平均值的系數,默認值為(0.9, 0.999)。
amsgrad:是否使用論文 On the Convergence of Adam and Beyond 中該算法的 AMSGrad 變體,默認值為false。
optim3 = torch.optim.Adam(wzh.parameters(), lr=learning_rate, betas=(0.9, 0.999), eps=1e-8, weight_decay=0.01,amsgrad=False)
2.5 LBFGS
LBFGS是BFGS四位大佬一起開發的一個算法,可以有效節省系統內存,縮小BFGS算法迭代產生的n維D矩陣,只保留部分步數。
pytorch中也可以使用改算法,但需要注意:
1:此優化器不支持每個參數選項和參數組(只能有一個)。
2:現在所有參數都必須在一個設備上。
3:這是一個非常占用內存的優化器(它需要額外的 param_bytes * (history_size + 1) 字節)。 如果它不適合內存嘗試減少歷史記錄大小,或使用不同的算法。
torch.optim.LBFGS(params, lr=1, max_iter=20, max_eval=None, tolerance_grad=1e-07, tolerance_change=1e-09, history_size=100, line_search_fn=None)
max_iter:每個優化步驟的最大迭代次數,默認值20。
max_eval:每個優化步驟的最大函數評估次數,默認值max_iter * 1.25.
tolerance_grad:一階最優性的終止容限,默認值1e-5。
tolerance_change:函數值/參數更改的終止容差,默認值1e-9。
history_size:更新歷史大小 。
line_search_fn:“strong_wolfe”或“None” 。
詳細原理部分可見:
一文讀懂L-BFGS算法
optim3 = torch.optim.LBFGS(wzh.parameters(), lr=1, max_iter=20, max_eval=None, tolerance_grad=1e-07, tolerance_change=1e-09, history_size=100, line_search_fn=None)
三、參考文章
通俗易懂理解(梯度下降)優化算法:Momentum、AdaGrad、RMSProp、Adam