0605-优化器

0605-优化器

pytorch完整教程目录:https://www.cnblogs.com/nickchen121/p/14662511.html

一、优化器概述

torch 把深度学习中常用的优化方法都存储在 torch.optim 中,它的设计十分灵活,可以很方便的扩展成自定义的优化方法。

所有的优化方法都继承基类 optim.Optimizer,并实现了自己的优化步骤,接下来我们将以最基本的优化方法——随机梯度下降法(SGD)距离说明。在这里需要重点掌握以下三个方法:

  • 优化方法的基本使用方法
  • 如何对模型的不同部分设置不同的学习率(lr)
  • 如何调整学习率
import torch as t
from torch import nn
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(16 * 5 * 5, 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, 16 * 5 * 5)
        x = self.classifier(x)
        return x


net = Net()
from torch import optim

optimizer = optim.SGD(params=net.parameters(), lr=1)
optimizer.zero_grad()  # 梯度清零,等价于 net.zero_grad()

inp = V(t.randn(1, 3, 32, 32))
output = net(inp)
output.backward(output)

optimizer.step()  # 优化参数

二、针对不同的网络设定不同的 lr

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

三、针对不同的层设定不同的 lr

# 只为两个全连接层设置较大的学习率,其余层的学习率较小
special_layers = nn.ModuleList([net.classifier[0], net.classifier[3]])
special_layers_params = list(map(id, special_layers.parameters()))  # 得到特殊层的 id

# 筛选出不属于特殊层的层
base_params = filter(lambda p: id(p) not in special_layers_params,
                     net.parameters())

# 对于特殊层和非特殊层设定不同的 lr
optimizer = t.optim.SGD([{
    'params': base_params
}, {
    'params': special_layers.parameters(),
    'lr': 0.01
}],
                        lr=0.001)

四、动态修改 lr

在跑代码的过程中,我们可能需要中途改变学习率的大小。在 torch 中提供了两种做法:

  1. 直接修改 optimizer.parm_groups 中对应的学习率(不推荐)
  2. 由于 optimizer 十分轻量级,开销很小,因此可以新建优化器(推荐)

如果使用第二种方法新建一个优化器,在这个过程中新建的优化器会初始化动量等状态信息,这对使用动量的优化器来说(如自带 momentum 的 sgd),可能会造成损失函数在收敛过程中震荡。

# 调整学习率,新建一个 optimizer
old_lr = 0.1

optimizer = optim.SGD([{
    'params': net.features.parameters()
}, {
    'params': net.classifier.parameters(),
    'lr': old_lr * 0.1
}],
                      lr=1e-5)
posted @ 2021-04-25 09:55  B站-水论文的程序猿  阅读(811)  评论(0编辑  收藏  举报