淺談Pytorch torch.optim優(yōu)化器個(gè)性化的使用
一、簡化前饋網(wǎng)絡(luò)LeNet
import torch as t class LeNet(t.nn.Module): def __init__(self): super(LeNet, self).__init__() self.features = t.nn.Sequential( t.nn.Conv2d(3, 6, 5), t.nn.ReLU(), t.nn.MaxPool2d(2, 2), t.nn.Conv2d(6, 16, 5), t.nn.ReLU(), t.nn.MaxPool2d(2, 2) ) # 由于調(diào)整shape并不是一個(gè)class層, # 所以在涉及這種操作(非nn.Module操作)需要拆分為多個(gè)模型 self.classifiter = t.nn.Sequential( t.nn.Linear(16*5*5, 120), t.nn.ReLU(), t.nn.Linear(120, 84), t.nn.ReLU(), t.nn.Linear(84, 10) ) def forward(self, x): x = self.features(x) x = x.view(-1, 16*5*5) x = self.classifiter(x) return x net = LeNet()
二、優(yōu)化器基本使用方法
建立優(yōu)化器實(shí)例
循環(huán):
清空梯度
向前傳播
計(jì)算Loss
反向傳播
更新參數(shù)
from torch import optim # 通常的step優(yōu)化過程 optimizer = optim.SGD(params=net.parameters(), lr=1) optimizer.zero_grad() # net.zero_grad() input_ = t.autograd.Variable(t.randn(1, 3, 32, 32)) output = net(input_) output.backward(output) optimizer.step()
三、網(wǎng)絡(luò)模塊參數(shù)定制
為不同的子網(wǎng)絡(luò)參數(shù)不同的學(xué)習(xí)率,finetune常用,使分類器學(xué)習(xí)率參數(shù)更高,學(xué)習(xí)速度更快(理論上)。
1.經(jīng)由構(gòu)建網(wǎng)絡(luò)時(shí)劃分好的模組進(jìn)行學(xué)習(xí)率設(shè)定,
# # 直接對(duì)不同的網(wǎng)絡(luò)模塊制定不同學(xué)習(xí)率 optimizer = optim.SGD([{'params': net.features.parameters()}, # 默認(rèn)lr是1e-5 {'params': net.classifiter.parameters(), 'lr': 1e-2}], lr=1e-5)
2.以網(wǎng)絡(luò)層對(duì)象為單位進(jìn)行分組,并設(shè)定學(xué)習(xí)率
# # 以層為單位,為不同層指定不同的學(xué)習(xí)率 # ## 提取指定層對(duì)象 special_layers = t.nn.ModuleList([net.classifiter[0], net.classifiter[3]]) # ## 獲取指定層參數(shù)id special_layers_params = list(map(id, special_layers.parameters())) print(special_layers_params) # ## 獲取非指定層的參數(shù)id 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)
四、在訓(xùn)練中動(dòng)態(tài)的調(diào)整學(xué)習(xí)率
'''調(diào)整學(xué)習(xí)率''' # 新建optimizer或者修改optimizer.params_groups對(duì)應(yīng)的學(xué)習(xí)率 # # 新建optimizer更簡單也更推薦,optimizer十分輕量級(jí),所以開銷很小 # # 但是新的優(yōu)化器會(huì)初始化動(dòng)量等狀態(tài)信息,這對(duì)于使用動(dòng)量的優(yōu)化器(momentum參數(shù)的sgd)可能會(huì)造成收斂中的震蕩 # ## optimizer.param_groups:長度2的list,optimizer.param_groups[0]:長度6的字典 print(optimizer.param_groups[0]['lr']) old_lr = 0.1 optimizer = optim.SGD([{'params': net.features.parameters()}, {'params': net.classifiter.parameters(), 'lr': old_lr*0.1}], lr=1e-5)
可以看到optimizer.param_groups結(jié)構(gòu),[{'params','lr', 'momentum', 'dampening', 'weight_decay', 'nesterov'},{……}],集合了優(yōu)化器的各項(xiàng)參數(shù)。
重寫sgd優(yōu)化器
import torch from torch.optim.optimizer import Optimizer, required class SGD(Optimizer): def __init__(self, params, lr=required, momentum=0, dampening=0, weight_decay1=0, weight_decay2=0, nesterov=False): defaults = dict(lr=lr, momentum=momentum, dampening=dampening, weight_decay1=weight_decay1, weight_decay2=weight_decay2, nesterov=nesterov) if nesterov and (momentum <= 0 or dampening != 0): raise ValueError("Nesterov momentum requires a momentum and zero dampening") super(SGD, self).__init__(params, defaults) def __setstate__(self, state): super(SGD, self).__setstate__(state) for group in self.param_groups: group.setdefault('nesterov', False) def step(self, closure=None): """Performs a single optimization step. Arguments: closure (callable, optional): A closure that reevaluates the model and returns the loss. """ loss = None if closure is not None: loss = closure() for group in self.param_groups: weight_decay1 = group['weight_decay1'] weight_decay2 = group['weight_decay2'] momentum = group['momentum'] dampening = group['dampening'] nesterov = group['nesterov'] for p in group['params']: if p.grad is None: continue d_p = p.grad.data if weight_decay1 != 0: d_p.add_(weight_decay1, torch.sign(p.data)) if weight_decay2 != 0: d_p.add_(weight_decay2, p.data) if momentum != 0: param_state = self.state[p] if 'momentum_buffer' not in param_state: buf = param_state['momentum_buffer'] = torch.zeros_like(p.data) buf.mul_(momentum).add_(d_p) else: buf = param_state['momentum_buffer'] buf.mul_(momentum).add_(1 - dampening, d_p) if nesterov: d_p = d_p.add(momentum, buf) else: d_p = buf p.data.add_(-group['lr'], d_p) return loss
以上這篇淺談Pytorch torch.optim優(yōu)化器個(gè)性化的使用就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
利用 python 對(duì)目錄下的文件進(jìn)行過濾刪除
這篇文章主要給大家介紹了關(guān)于如何利用 python 對(duì)目錄下的文件進(jìn)行過濾刪除的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12django頁面跳轉(zhuǎn)問題及注意事項(xiàng)
這篇文章主要介紹了django頁面跳轉(zhuǎn)問題及注意事項(xiàng),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07python 實(shí)現(xiàn)的車牌識(shí)別項(xiàng)目
這篇文章主要介紹了python 實(shí)現(xiàn)的車牌識(shí)別項(xiàng)目,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-01-01對(duì)Python3中dict.keys()轉(zhuǎn)換成list類型的方法詳解
今天小編就為大家分享一篇對(duì)Python3中dict.keys()轉(zhuǎn)換成list類型的方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-02-02如何利用python實(shí)現(xiàn)把視頻轉(zhuǎn)換成gif圖形
將視頻轉(zhuǎn)換為 GIF 圖形的重要性不言而喻,在信息快速傳播和多種社交平臺(tái)廣泛應(yīng)用的背景下,GIF 動(dòng)畫不僅為個(gè)人用戶提供了一種輕松的表達(dá)方式,本文給大家介紹了如何利用python實(shí)現(xiàn)把視頻轉(zhuǎn)換成gif圖形,需要的朋友可以參考下2024-10-10Python延時(shí)操作實(shí)現(xiàn)方法示例
這篇文章主要介紹了Python延時(shí)操作實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了Python基于sched庫與time庫實(shí)現(xiàn)延時(shí)操作的方法,需要的朋友可以參考下2018-08-08