optimizer.param_groups: 是一个list,其中的元素为字典
optimizer.param_groups[0]:是一个字典,一般包括[‘params’, ‘lr’, ‘betas’, ‘eps’, ‘weight_decay’, ‘amsgrad’, ‘maximize’]等参数(不同的优化器包含的可能略有不同,而且还可以额外人为添加键值对)
Pytorch的优化器中都有一个参数:params(model.parameters())。params就是网络中需要优化的网络参数,在这里需要注意的是传入的网络参数必须使可以迭代的对象。
情况一:如果我们只是想优化一个网络,那么我们就把一整个网络看做一个param_groups,params参数的赋值为model.parameters()。
import torch
import torch.nn as nn
# 定义网络
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
self.conv = nn.Sequential(
nn.Conv2d(3, 8, 3),
nn.ReLU(),
)
self.fc = nn.Sequential(
nn.Linear(288, 5)
)
def forward(self, x):
x = self.conv(x)
x = torch.flatten(x, 1)
print(x.shape)
x = self.fc(x)
return x
# 实例化网络
model = Test()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
print("只有一个网络时optimizer.param_groups(list类型)的长度:{}".format(len(optimizer.param_groups)))
输出:
只有一个网络时optimizer.param_groups(list类型)的长度:1
因为这里把整个网络看成了一个param_groups,所以这里的执行结果为:1。
情况二:如果是同时优化多个网络参数,这里介绍两种方法:
a.将多个网络的参数合并到一起,当成一个网络的参数来进行优化一般的赋值方式为
import torch
import torch.nn as nn
# 定义网络
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
self.conv = nn.Sequential(
nn.Conv2d(3, 8, 3),
nn.ReLU(),
)
self.fc = nn.Sequential(
nn.Linear(288, 5)
)
def forward(self, x):
x = self.conv(x)
x = torch.flatten(x, 1)
print(x.shape)
x = self.fc(x)
return x
#此时有两个网络需要优化
model_1 = Test()
model_2 = Test()
optimizer = torch.optim.Adam([*model_1.parameters(), *model_2.parameters()], lr=0.01)
print("两个网络时optimizer.param_groups(list类型)的长度:{}".format(len(optimizer.param_groups)))
输出:
两个网络时optimizer.param_groups(list类型)的长度:1
代码执行结果为:1。说明可以把多个网络参数合并成一个网络参数进行优化。
b.多个网络分开优化,并且可以使用各不相同的学习率,赋值方式为:
import torch
import torch.nn as nn
# 定义网络
class Test(nn.Module):
def __init__(self):
super(Test, self).__init__()
self.conv = nn.Sequential(
nn.Conv2d(3, 8, 3),
nn.ReLU(),
)
self.fc = nn.Sequential(
nn.Linear(288, 5)
)
def forward(self, x):
x = self.conv(x)
x = torch.flatten(x, 1)
print(x.shape)
x = self.fc(x)
return x
#此时有两个网络需要优化
model_1 = Test()
model_2 = Test()
optimizer = torch.optim.Adam([{'params':model_1.parameters()},{'params':model_2.parameters(), 'lr': 0.2}], lr=0.01)
print("优化器里有多少个param_groups: ", len(optimizer.param_groups))
print("网络1的学习率为: ", optimizer.param_groups[0]['lr'])
print("网络2的学习率为: ", optimizer.param_groups[1]['lr'])
输出:
优化器里有多少个param_groups: 2
网络1的学习率为: 0.01
网络2的学习率为: 0.2
从结果中可以看出,每个param_groups中可以单独定义学习率lr,如果没有指定的话则默认采取后面的学习率。