pytorch---損失函數和優化器


pytorch---損失函數和優化器

 

一、損失函數

損失函數可以當作是nn的某一個特殊層,也是nn.Module的子類。但是實際中。然而在實際使用中通常將這些loss function專門提取出來,和主模型互相獨立。

score=t.randn(3,2)                 //batch_size=3,類別是2.
label=t.Tensor([1,0,1].long()) //注意label必須得是longTensor
criterion=nn.CrossEntropyLoss() //CroosEntropyLoss是常用的二分類損失函數
loss=criterion(score,label)

 

 

二、優化器

所有的優化方法都封裝在torch.optim里面,他的設計很靈活,可以擴展為自定義的優化方法。

所有的優化方法都是繼承了基類optim.Optimizer。並實現了自己的優化步驟。

 

關於優化器需要掌握:

1、優化方法基本使用方法。

2、如何為不同的層設置不同的學習率。

3、如何調整學習率。

 

1、優化方法基本使用

import optim
ptimizer=optim.SGD(params=net.parameters(),lr=0.1)
optimizer.zero_grad() //梯度清零

output=net(input)
output.backward(output)
optimizer.step()

 

2、如何為不同的層設置不同的學習率

法1

 

# 為不同子網絡設置不同的學習率,在finetune中經常用到
# 如果對某個參數不指定學習率,就使用最外層的默認學習率
optimizer =optim.SGD([
              {'params': net.features.parameters()}, # 學習率為1e-5
              {'params': net.classifier.parameters(), 'lr': 1e-2}
          ], lr=1e-5)

 

法2

 


# 只為兩個全連接層設置較大的學習率,其余層的學習率較小
special_layers = nn.ModuleList([net.classifier[0], net.classifier[3]])
special_layers_params = list(map(id, special_layers.parameters()))
base_params = filter(lambda p: id(p) not in special_layers_params,
                    net.parameters())

optimizer = t.optim.SGD([
          {'params': base_params},
          {'params': special_layers.parameters(), 'lr': 0.01}
      ], lr=0.001 )
optimizer

 

 

3、如何調整學習率

法1(比較推薦):新建一個optimizer。對於使用動量的優化器(如Adam),會丟失動量等狀態信息,可能會造成損失函數的收斂出現震盪等情況


old_lr = 0.1
optimizer1 =optim.SGD([
              {'params': net.features.parameters()},
              {'params': net.classifier.parameters(), 'lr': old_lr*0.1}
          ], lr=1e-5)
optimizer1

 

法2:一種是修改optimizer.param_groups中對應的學習率

 


# 方法2: 調整學習率, 手動decay, 保存動量
for param_group in optimizer.param_groups:
  param_group['lr'] *= 0.1 # 學習率為之前的0.1倍
optimizer



三、functional

 

nn中的每一個layer在functional中基本都有與之對應的函數。為此怎么判斷何時用nn.Module,何時用functional里的函數呢。

 



input = t.randn(2, 3)
model = nn.Linear(3, 4)
output1 = model(input)
output2 = nn.functional.linear(input, model.weight, model.bias)
output1 == output2


b = nn.functional.relu(input)
b2 = nn.ReLU()(input)
b == b2

可見,Module是一個類,會自動提取可學習的參數。 但是functional是一個純函數。所以當某layer是有看學習參數的話用Module實現(卷積、全連接),否則就是functional(激活、池化)。但是,注意Dropout雖然可學習參數但是因為在訓練和測試的時候他的行為不一樣,所以仍然放在Module,通使用nn.Module對象能夠通過model.eval操作加以區分。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM