與優化函數相關的部分在
torch.optim
子產品中,其中包含了大部分現在已有的流行的優化方法。
如何使用 Optimizer
Optimizer
要想使用optimizer,需要建立一個optimizer 對象,這個對象會儲存目前狀态,并根據梯度更新參數。
怎樣構造 Optimizer
Optimizer
要構造一個
Optimizer
,需要使用一個用來包含所有參數(
Tensor
形式)的iterable,把相關參數(如learning rate、weight decay等)裝進去。
注意,如果想要使用
.cuda()
方法來将model移到GPU中,一定要確定這一步在構造
Optimizer
之前。因為調用
.cuda()
之後,model裡面的參數已經不是之前的參數了。
示例代碼如下:
optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum = 0.9)
optimizer = optim.Adam([var1, var2], lr = 0.0001)
常用參數
last_epoch
代表上一次的epoch的值,初始值為-1。
單獨指定參數
也可以用一個dict的iterable指定參數。這裡的每個dict都必須要
params
這個key,
params
包含它所屬的參數清單。除此之外的key必須它的
Optimizer
(如
SGD
)裡面有的參數。
You can still pass options as keyword arguments. They will be used as defaults, in the groups that didn’t override them. This is useful when you only want to vary a single option, while keeping all others consistent between parameter groups.
這在針對特定部分進行操作時很有用。比如隻希望給指定的幾個層單獨設定學習率:
optim.SGD([
{'params': model.base.parameters()},
{'params': model.classifier.parameters(), 'lr': 0.001}
],
lr = 0.01, momentum = 0.9)
在上面這段代碼中
model.base
将會使用預設學習率0.01,而
model.classifier
的參數蔣歡使用0.001的學習率。
怎樣進行單次優化
所有optimizer都實作了
step()
方法,調用這個方法可以更新參數,這個方法有以下兩種使用方法:
optimizer.step()
optimizer.step()
多數optimizer裡都可以這麼做,每次用
backward()
這類的方法計算出了梯度後,就可以調用一次這個方法來更新參數。
示例程式:
for input, target in dataset:
optimizer.zero_grad()
ouput = model(input)
loss = loss_fn(output, target)
loss.backward()
optimizer.step()
optimizer.step(closure)
optimizer.step(closure)
有些優化算法會多次重新計算函數(比如Conjugate Gradient、LBFGS),這樣的話你就要使用一個閉包(closure)來支援多次計算model的操作。這個closure的運作過程是,清除梯度,計算loss,傳回loss。
(這個我不太了解,因為這些優化算法不熟悉)
示例程式:
for input, target in dataset:
def closure():
optimizer.zero_grad()
output = model(input)
loss = loss_fn(output, target)
loss.backward()
return loss
optimizer.step(closure)
優化算法
這裡就不完整介紹documentation中的内容了,隻介紹基類。具體的算法的參數需要了解它們的原理才能明白,這個改天單獨來一篇文章介紹。
Optimizer
class torch.optim.Optimizer(params, defaults)
這是所有optimizer的基類。
注意,各參數的順序必須保證每次運作都一緻。有些資料結構就不滿足這個條件,比如dictionary的iterator和set。
參數
-
(iterable)是params
或者torch.Tensor
的iterable。這個參數指定了需要更新的Tensor。dict
-
(dict)是一個dict,它包含了預設的的優化選項。defaults
方法
add_param_group(param_group)
這個方法的作用是增加一個參數組,在fine tuning一個預訓練的網絡時有用。
load_state_dict(state_dict)
這個方法的作用是加載optimizer的狀态。
state_dict()
擷取一個optimizer的狀态(一個dict)。
zero_grad()
方法用于清空梯度。
step(closure)
用于進行單次更新。
Adam
class torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)