pytorch的優化器optimizer使用方法


 

使用 torch.optim 創建一個optim 對象,這個對象會一直保持當前狀態或根據計算的梯度更新參數。

也是模型搭建模塊梯度走向,是模型迭代至關重要一部分。因此,本文為每個模塊自由設計學習率等參數問題進行探討。

本文首先給出探討問題及結論,然后分別解釋探討問題,具體如下:

 

一、探究問題:

①分模塊設計不同參數

②優化器如何自由添加自己參數與保留重要信息

③整體模型如何設計

結果:若設置模塊,則按照模塊參數更新此模塊,若未設置模塊,則按照總體參數更新。

二、定義介紹

基本定義:torch.optim是一個實現了各種優化算法的庫。大部分常用的方法得到支持,並且接口具備足夠的通用性,使得未來能夠集成更加復雜的方法。

構建優化器:構建優化器可選擇optim自定義的方法,一般也是調用其中的,如下可構建:

optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9)

optimizer = optim.Adam([var1, var2], lr = 0.0001)   # [var1, var2] 可理解為優化的變量 lr = 0.0001為梯度下降的學習率,其它未設置表示默認

三、模塊自由設計參數

深度理解:若你構建了網絡模型model,若你想給不同模塊設置不同學習率,將可以采取以下方法:

optimizer = optim.SGD([ {'params': model.base.parameters()}, {'params': model.classifier.parameters(), 'lr': 1e-3} ], lr=1e-2, momentum=0.9)

以上optim.SGD()中的列表就是構建每個參數的學習率,若沒有設置,則默認使用最外如:model.base.parameters()參數使用lr=1e-2  momentum=0.9

 

四、自由添加或更改參數

添加個人需要的變量:

若你想添加個人變量保存optimizer中,可使用:

for b in optimizer.param_groups:
    b.setdefault('init_lr', 0.02)

此時類似optimizer = optim.SGD([ {'params': model.base.parameters()}, {'params': model.classifier.parameters(), 'lr': 1e-3} ],init_lr=0.02, lr=1e-2, momentum=0.9)

若你想更改學習率,可使用:

for b in optimizer.param_groups:
    b.setdefault('init_lr', 0.00005)

此時類似將optimizer = optim.SGD([ model.base.parameters(), lr=0.02, momentum=0.9) 變成
optimizer = optim.SGD([model.base.parameters(), lr=0.00005, momentum=0.9)

注:可理解optimezer已經保存了模型model需要使用的學習率參數。

 

五、優化器查看方法

查看優化器參數:

optimizer.param_groups[0]: 長度為6的字典,包括[‘amsgrad’, ‘params’, ‘lr’, ‘betas’, ‘weight_decay’, ‘eps’]這6個參數;

optimizer.param_groups[1]: 好像是表示優化器的狀態的一個字典;


六、模型使用優化器方法

模型訓練優化器一般方法使用:

大多數optimizer所支持的簡化版本。一旦梯度被如backward()之類的函數計算好后,我們就可以調用這個函數

for input, target in dataset:

  optimizer.zero_grad()

  output = model(input)

  loss = loss_fn(output, target)

  loss.backward()

  optimizer.step()

 

深入用法:

optimizer.step(closure)

一些優化算法例如Conjugate Gradient和LBFGS需要重復多次計算函數,因此你需要傳入一個閉包去允許它們重新計算你的模型。這個閉包應當清空梯度, 計算損失,然后返回。

 

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)

 

七 、模型設置參數方法

 

2022年02月28日新增模型自由設置參數函數代碼

import torch.nn as nn
import torch
class module(nn.Module):
    def __init__(self):
        super(module, self).__init__()
        self.features = nn.Conv2d(in_channels=3, out_channels=64, stride=1, kernel_size=3, padding=1,bias=False)
        self.classifiter = nn.Conv2d(in_channels=64, out_channels=128, stride=1, kernel_size=3, padding=1,bias=True)

        self.relu = nn.ReLU()
    def forward(self, x):

        x = self.features(x)
        x = self.classifiter(x)
        return self.relu(x)

if __name__ == '__main__':

    net=module()
    optimizer = torch.optim.SGD([{'params': net.features.weight, 'lr':  0.1},
                                 # {'params': net.features.bias, 'lr':  0.3},
                                 {'params': net.classifiter.weight},
                                 {'params': net.classifiter.bias,'lr':0.9}
                                 ],          lr=0.5)

    print(optimizer)

 

 

 

 

2022年02月28日新增模型不同模塊的學習相關參數設定代碼,如學習率lr

def sgd_optimizer(cfg, resrep_config:ResRepConfig, model, no_l2_keywords, use_nesterov, keyword_to_lr_mult):
    params = []
    for key, value in model.named_parameters():
        if not value.requires_grad:
            continue
        lr = cfg.base_lr
        weight_decay = cfg.weight_decay
        if "bias" in key or "bn" in key or "BN" in key:
            weight_decay = cfg.weight_decay_bias
            print('set weight_decay_bias={} for {}'.format(weight_decay, key))
        for kw in no_l2_keywords:
            if kw in key:
                weight_decay = 0
                print('NOTICE! weight decay = 0 for ', key, 'because {} in {}'.format(kw, key))
                break
        if 'bias' in key:
            apply_lr = 2 * lr
        else:
            apply_lr = lr
        if keyword_to_lr_mult is not None:
            for keyword, mult in keyword_to_lr_mult.items():
                if keyword in key:
                    apply_lr *= mult
                    print('multiply lr of {} by {}'.format(key, mult))
                    break
        if 'compactor' in key:
            use_momentum = resrep_config.compactor_momentum
            print('momentum {} for {}'.format(use_momentum, key))
        else:
            use_momentum = cfg.momentum
        params += [{"params": [value], "lr": apply_lr, "weight_decay": weight_decay, "momentum": use_momentum}]  # 每一層使用不同的參數
    optimizer = torch.optim.SGD(params, lr, momentum=cfg.momentum, nesterov=use_nesterov)
    return optimizer

 


免責聲明!

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



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