在训练模型时,有时候依据需求需要对模型的不同层(比如convolutional layer, linear layer等)或者不同层的weght和bias设置不同的学习率,针对这个问题,我们有以下几种方式解决:
以5层卷积的模型为例:
class Net5(nn.Module):
def __init__(self):
super(Net5, self).__init__()
self.baseConv = nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(3, 128, 3, 1, 1)),
('relu1', nn.ReLU()),
('conv2', nn.Conv2d(128, 128, 3, 1, 1)),
('relu2', nn.ReLU()),
('conv3', nn.Conv2d(128, 128, 3, 1, 1)),
('relu3', nn.ReLU())])
)
self.conv4 = nn.Conv2d(128, 64, 3, 1, 1)
self.conv5 = nn.Conv2d(64, 3, 3, 1, 1)
def forward(self, x):
h = self.baseConv(x)
h = self.conv4(h)
result = self.conv5(h)
return result
1、对不同的层设置不同的学习率
假如此处对baseConv中三个卷积层设置学习率为lr=0.001,conv4与conv5的学习率为0.0001;
方式1:最简单的方式
net = Net5()
params = []
params += [{'param': net.baseConv.parameters(), 'lr': 0.001}]
params += [{'param': net.conv4.parameters(), 'lr': 0.0001}]
params += [{'param': net.conv5.parameters(), 'lr': 0.0001}]
solver = Adam(params=params)
方式2: 利用lis,map以及filter函数
base_params = list(map(id, net.baseConv.parameters()))
other_params = filter(lambda p: id(p) not in base_params, net.parameters())
params = [{'param': net.baseConv.parameters(), 'lr': 0.001},
{'param': other_params, 'lr': 0.0001}]
solver = Adam(params=params)
2、对于不同层的weight和bias设置 不同的学习率
例如将Net5的前4个卷积层的weight的学习率设为0.001,bias的学习率为0.0001,第五个卷积层的weight和bias的学习率设为0.0001,这种设置方式如下:
lr = 0.001
params = []
base_params = dict(net.baseConv.named_parameters())
for key, value in base_params.items():
if 'bias' not in key:
params += [{'param': [value], 'lr': lr}]
else:
params += [{'param': [value], 'lr': lr * 0.1}]
conv4_param = dict(net.conv4.named_parameters())
for key, value in conv4_param.items():
if 'bias' not in key:
params += [{'param': [value], 'lr': lr}]
else:
params += [{'param': [value], 'lr': lr * 0.1}]
params += [{'param': net.conv5.parameters(), 'lr': lr * 0.1}]
solver = Adam(params=params)
以上的方法可实现针对Pytorch中需要为不同layer设计不同学习率。