动态调整模型中的学习率

调整模型中学习率的方法主要有:

  1. 一种是修改optimizer.param_groups中对应的学习率
  2. 另一种是新建优化器

注意:由于optimizer十分轻量级,构建开销很小,故可以构建新的optimizer。但新建优化器会重新初始化动量等状态信息,这对使用动量的优化器来说(如带momentum的sgd),可能会造成损失函数在收敛过程中出现震荡。

首先我们建立一个LeNet网络:

import torch as t
import torch.nn as nn
from torch import optim
from torch.autograd import Variable as V

#定义个LeNet网络
class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.features=nn.Sequential(
            nn.Conv2d(3,6,5),
            nn.ReLU(),
            nn.MaxPool2d(2,2),
            nn.Conv2d(6,16,5),
            nn.ReLU(),
            nn.MaxPool2d(2,2)
        )
        self.classifier=nn.Sequential(
            nn.Linear(5*5*16,120),
            nn.ReLU(),
            nn.Linear(120,84),
            nn.ReLU(),
            nn.Linear(84,10)
        )

    def forward(self, x):
        x=self.features(x)
        x=x.view(-1,5*5*16)
        x=self.classifier(x)
        return x

并初始化参数:

net=Net()
optimizer=optim.SGD(params=net.parameters(),lr=1)
optimizer.zero_grad()   #梯度清零,等价于net.zero_grad()
input=V(t.randn(1,3,32,32)) # batch_size,sentence_length/in_channels,height,width
out=net(input)
out.backward(out)
optimizer.step()    #执行优化

到这里模型已经搭建好,并可以自动进行梯度更新,接下来看一下优化器种设置学习率的两种方法:

1. 为不同子网络设置不同的学习率,在fintune中经常用到

这里我们分别设置features和classifer两层不同的学习率,分别是1e-5、1e-2。

# 如果对某个参数不指定学习率,就使用默认学习率
optimizer=optim.SGD([{'params':net.features.parameters(),#学习率为1e-5
                      },
                     {'params':net.classifier.parameters(),'lr':1e-2}
                     ],lr=1e-5 #默认学习率
                    )

2. 修改optimizer.param_group中对应学习率

这里只为两个全连接层设置较大的学习率,其余曾的学习率较小:

# 只为两个全连接层设置较大的学习率,其余层的学习率较小
special_layers=nn.ModuleList([net.classifier[0],net.classifier[3]])

#取出这两层里面参数对应的id
special_layers_params=list(map(id,special_layers.parameters()))

#除这两层以外参数的id
base_params=filter(lambda p:id(p) not in special_layers_params,net.parameters())

optimizer=t.optim.SGD([
    {'params':base_params}, #这两这两层params会根据id去定位模型层,并更新学习率
    {'params':special_layers_params,'lr':0.01}
],lr=0.001)

3. 通过新建optimizer,动态调整学习率(本质上是方法1)

optimizer=optim.SGD([{'params':net.features.parameters(),#学习率为1e-5
                      },
                     {'params':net.classifier.parameters(),'lr':old_lr*0.1}
                     ],lr=1e-5 #默认学习率
                    )
发布了457 篇原创文章 · 获赞 57 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/weixin_38664232/article/details/104678160