pytorch筆記 <三>
optimizer.zero_grad()
將梯度變為0,用於每個batch最開始,因為梯度在不同batch之間不是累加的,所以必須在每個batch開始的時候初始化累計梯度,重置為0.
for epoch in range(num_epoches):# 每個epoch
for inputs,labels in dataloader:# 每個batch
optimizer.zero_grad()# 初始化梯度
outputs = model(inputs)# 正向
_,pred = torch.max(outputs,1)
loss = criterion(inputs,pred)# 計算loss
#...
loss.backward() # 反向
optimizer.step()# 更新權重
torch.max()
在某個dim上返回最大的值以及在該dim上的索引,所以是返回兩個值。
max(input, dim, keepdim=False, out=None)
>>> import torch
>>> a = torch.randn(3,3)
>>> print(torch.max(a,1))
(tensor([1.0404, 1.8460, 0.5961]), tensor([2, 1, 0]))
model(x)輸出的是概率,要獲得類別必須通過torch.max來獲得,但是我們求loss的時候還是求網絡輸出概率與label的loss,因為我們的label是被one-hot編碼的,所以這兩者的loss才是有效的,因為交叉熵衡量的是兩個概率分布之間的相似度。
optimizer.step() 以及 scheduler.step()
optimizer.step()用在每個batch內,當一個batch的數據計算完之后,通過optimizer.step()函數來完成權重的更新,而scheduler.step()用在每個epoch內,當一個epoch的數據運算完之后,調用一下這個函數,以此來決策是否更新我們的learning_rate超參等。
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)
# 每隔step_size個epoch learning_rate變為原來的0.1
# 然后在一個epoch之后執行
exp_lr_scheduler.step()