Optimizer
optimizer.param_groups用法的示例分析
日期:2022年7月25日
pytorch版本: 1.11.0
對于param_groups
的探索
optimizer.param_groups
: 是一個(gè)list,其中的元素為字典;
optimizer.param_groups[0]
:長度為7的字典,包括[‘params’, ‘lr’, ‘betas’, ‘eps’, ‘weight_decay’, ‘amsgrad’, ‘maximize’]這7個(gè)參數(shù);
下面用的Adam優(yōu)化器創(chuàng)建了一個(gè)optimizer
變量:
>>> optimizer.param_groups[0].keys()
>>> dict_keys(['params', 'lr', 'betas', 'eps', 'weight_decay', 'amsgrad', 'maximize'])
可以自己把訓(xùn)練參數(shù)分別賦予不同的學(xué)習(xí)率,這樣子list里就不止一個(gè)元素了,而是多個(gè)字典了。
-
params
是一個(gè)list[…],里面存放參數(shù)>>> len(optimizer.param_groups[0]['params']) >>> 48 >>> optimizer.param_groups[0]['params'][0] >>> Parameter containing: tensor([[ 0.0212, -0.1151, 0.0499, ..., -0.0807, -0.0572, 0.1166], [-0.0356, -0.0397, -0.0980, ..., 0.0690, -0.1066, -0.0583], [ 0.0238, 0.0316, -0.0636, ..., 0.0754, -0.0891, 0.0258], ..., [ 0.0603, -0.0173, 0.0627, ..., 0.0152, -0.0215, -0.0730], [-0.1183, -0.0636, 0.0381, ..., 0.0745, -0.0427, -0.0713],
-
lr
是學(xué)習(xí)率>>> optimizer.param_groups[0]['lr'] >>> 0.0005
-
betas
是一個(gè)元組(…),與動量相關(guān)>>> optimizer.param_groups[0]['betas'] >>> (0.9, 0.999)
-
eps
>>> optimizer.param_groups[0]['eps'] >>> 1e-08
-
weight_decay
是一個(gè)int變量>>> optimizer.param_groups[0]['weight_decay'] >>> 0
-
amsgrad
是一個(gè)bool變量>>> optimizer.param_groups[0]['amsgrad'] >>> False
-
maximize
是一個(gè)bool變量>>> optimizer.param_groups[0]['maximize'] >>> False
以網(wǎng)上的例子來繼續(xù)試驗(yàn):
import torch
import torch.optim as optim
w1 = torch.randn(3, 3)
w1.requires_grad = True
w2 = torch.randn(3, 3)
w2.requires_grad = True
o = optim.Adam([w1])
print(o.param_groups)
# 輸出
>>>
[{'params': [tensor([[-0.1002, 0.3526, -1.2212],
[-0.4659, 0.0498, -0.2905],
[ 1.1862, -0.6085, 0.4965]], requires_grad=True)],
'lr': 0.001,
'betas': (0.9, 0.999),
'eps': 1e-08,
'weight_decay': 0,
'amsgrad': False,
'maximize': False}]
以下主要是Optimizer
這個(gè)類有個(gè)add_param_group
的方法
# Per the docs, the add_param_group method accepts a param_group parameter that is a dict. Example of use:
import torch
import torch.optim as optim
w1 = torch.randn(3, 3)
w1.requires_grad = True
w2 = torch.randn(3, 3)
w2.requires_grad = True
o = optim.Adam([w1])
print(o.param_groups)
# 輸出
>>> [{'params': [tensor([[-1.5916, -1.6110, -0.5739],
[ 0.0589, -0.5848, -0.9199],
[-0.4206, -2.3198, -0.2062]], requires_grad=True)], 'lr': 0.001, 'betas': (0.9, 0.999), 'eps': 1e-08, 'weight_decay': 0, 'amsgrad': False, 'maximize': False}]
o.add_param_group({'params': w2})
print(o.param_groups)
# 輸出
>>> [{'params': [tensor([[-1.5916, -1.6110, -0.5739],
[ 0.0589, -0.5848, -0.9199],
[-0.4206, -2.3198, -0.2062]], requires_grad=True)], 'lr': 0.001, 'betas': (0.9, 0.999), 'eps': 1e-08, 'weight_decay': 0, 'amsgrad': False, 'maximize': False},
{'params': [tensor([[-0.5546, -1.2646, 1.6420],
[ 0.0730, -0.0460, -0.0865],
[ 0.3043, 0.4203, -0.3607]], requires_grad=True)], 'lr': 0.001, 'betas': (0.9, 0.999), 'eps': 1e-08, 'weight_decay': 0, 'amsgrad': False, 'maximize': False}]
平時(shí)寫代碼如何動態(tài)修改學(xué)習(xí)率(常規(guī)操作)
for param_group in optimizer.param_groups:
param_group["lr"] = lr
補(bǔ)充:pytorch中的優(yōu)化器總結(jié)
以SGD優(yōu)化器為例:
from torch import nn as nn
import torch as t
from torch.autograd import Variable as V
from torch import optim # 優(yōu)化器
# 定義一個(gè)LeNet網(wǎng)絡(luò)
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()
# 通常的step優(yōu)化過程
optimizer = optim.SGD(params=net.parameters(), lr=1)
optimizer.zero_grad() # 梯度清零,相當(dāng)于net.zero_grad()
input = V(t.randn(1, 3, 32, 32))
output = net(input)
output.backward(output)
optimizer.step() # 執(zhí)行優(yōu)化
為不同的子網(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è)定,
# 為不同子網(wǎng)絡(luò)設(shè)置不同的學(xué)習(xí)率,在finetune中經(jīng)常用到
# 如果對某個(gè)參數(shù)不指定學(xué)習(xí)率,就使用默認(rèn)學(xué)習(xí)率
optimizer = optim.SGD(
[{'params': net.features.parameters()}, # 學(xué)習(xí)率為1e-5
{'params': net.classifiter.parameters(), 'lr': 1e-2}], lr=1e-5
)
2.以網(wǎng)絡(luò)層對象為單位進(jìn)行分組,并設(shè)定學(xué)習(xí)率文章來源:http://www.zghlxwxcb.cn/news/detail-414351.html
# 只為兩個(gè)全連接層設(shè)置較大的學(xué)習(xí)率,其余層的學(xué)習(xí)率較小
# 以層為單位,為不同層指定不同的學(xué)習(xí)率
# 提取指定層對象
special_layers = nn.ModuleList([net.classifiter[0], net.classifiter[3]])
# 獲取指定層參數(shù)id
special_layers_params = list(map(id, special_layers.parameters()))
# 獲取非指定層的參數(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)
參考:
https://blog.csdn.net/weixin_43593330/article/details/108490956
https://www.cnblogs.com/hellcat/p/8496727.html
https://www.yisu.com/zixun/456082.html文章來源地址http://www.zghlxwxcb.cn/news/detail-414351.html
到了這里,關(guān)于有關(guān)optimizer.param_groups用法的示例分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!