深度学习 —— 调整学习率(finetune)

2022-09-23 09:06:48

PyTorch将深度学习中常用的优化方法全部封装在torch.optim中,其设计十分灵活,能够很方便的扩展成自定义的优化方法。

所有的优化方法都是继承基类optim.Optimizer,并实现了自己的优化步骤。下面就以最基本的优化方法——随机梯度下降法(SGD)举例说明。这里需重点掌握:

  • 优化方法的基本使用方法
  • 如何对模型的不同部分设置不同的学习率
  • 如何调整学习率
# 首先定义一个LeNet网络classNet(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(16*5*5,120),
            nn.ReLU(),
            nn.Linear(120,84),
            nn.ReLU(),
            nn.Linear(84,10))defforward(self, x):
        x= self.features(x)
        x= x.view(-1,16*5*5)
        x= self.classifier(x)return x

net= Net()
from torchimport  optim
optimizer= optim.SGD(params=net.parameters(), lr=1)
optimizer.zero_grad()# 梯度清零,等价于net.zero_grad()input= t.randn(1,3,32,32)
output= net(input)
output.backward(output)# fake backward

optimizer.step()# 执行优化
# 为不同子网络设置不同的学习率,在finetune中经常用到# 如果对某个参数不指定学习率,就使用最外层的默认学习率
optimizer=optim.SGD([{'params': net.features.parameters()},# 学习率为1e-5{'params': net.classifier.parameters(),'lr':1e-2}], lr=1e-5)
optimizer

在这里插入图片描述

# 只为两个全连接层设置较大的学习率,其余层的学习率较小
special_layers= nn.ModuleList([net.classifier[0], net.classifier[3]])
special_layers_params=list(map(id, special_layers.parameters()))
base_params=filter(lambda p:id(p)notin special_layers_params,
                     net.parameters())

optimizer= t.optim.SGD([{'params': base_params},{'params': special_layers.parameters(),'lr':0.01}], lr=0.001)
optimizer

在这里插入图片描述

对于如何调整学习率,主要有两种做法。一种是修改optimizer.param_groups中对应的学习率,另一种是更简单也是较为推荐的做法——新建优化器,由于optimizer十分轻量级,构建开销很小,故而可以构建新的optimizer。但是后者对于使用动量的优化器(如Adam),会丢失动量等状态信息,可能会造成损失函数的收敛出现震荡等情况。

# 方法1: 调整学习率, 手动decay, 保存动量for param_groupin optimizer.param_groups:
    param_group['lr']*=0.1# 学习率为之前的0.1倍
optimizer

在这里插入图片描述

# 方法2: 调整学习率,新建一个optimizer
old_lr=0.1
optimizer1=optim.SGD([{'params': net.features.parameters()},{'params': net.classifier.parameters(),'lr': old_lr*0.1}], lr=1e-5)
optimizer1

在这里插入图片描述

  • 作者:aift
  • 原文链接:https://blog.csdn.net/ft_sunshine/article/details/91615018
    更新时间:2022-09-23 09:06:48