torch.optim

torch.optim是一个实现了各种优化算法的库。

1. 如何使用optimizer

我们需要构建一个optimizer对象。这个对象能够保持当前参数状态并基于计算得到的梯度进行参数更新。

1.1 构建

为了构建一个Optimizer,你需要给它一个包含了需要优化的参数(必须都是Variable对象)的iterable。然后,你可以设置optimizer的参 数选项,比如学习率,权重衰减,等等。

例子:

optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9)
optimizer = optim.Adam([var1, var2], lr = 0.0001)

1.2 为每个参数单独设置选项

Optimizer也支持为每个参数单独设置选项。此时,我们应该传入dict的iterable。每一个dict都分别定义了一组参数,并且包含一个param键,这个键对应参数的列表。

当你只想改动一个参数组的选项,但其他参数组的选项不变时,这是非常有用的。

例如,当我们想指定每一层的学习率时,

optim.SGD([
                {'params': model.base.parameters()},
                {'params': model.classifier.parameters(), 'lr': 1e-3}
            ], lr=1e-2, momentum=0.9)

这意味着model.base的参数将会使用1e-2的学习率,model.classifier的参数将会使用1e-3的学习率,并且0.9的momentum将会被用于所有的参数。

1.3 进行单次优化

所有的optimizer都实现了step()方法,这个方法会更新所有的参数。它能按两种方式来使用:

1.optimizer.step()

这是大多数optimizer所支持的简化版本。一旦梯度被如backward()之类的函数计算好后,我们就可以调用这个函数。

例子:

for input, target in dataset:
    optimizer.zero_grad()
    output = model(input)
    loss = loss_fn(output, target)
    loss.backward()
    optimizer.step()

2.optimizer.step(closure)

这个函数的用法没看懂,但用的也很少。

2. 优化器

class torch.optim.Optimizer(params, defaults)

这是所有优化器的基类。

参数

  • params (iterable) —— Variable 或者 dict的iterable。指定了什么参数应当被优化。
  • defaults —— (dict):包含了优化选项默认值的字典(一个参数组没有指定的参数选项将会使用默认值)。

(1)load_state_dict(state_dict)

加载optimizer状态。

参数

state_dict (dict) —— optimizer的状态。应当是一个调用state_dict()所返回的对象。

(2)state_dict()

dict返回optimizer的状态。

它包含两项。

state - 一个保存了当前优化状态的dict。optimizer的类别不同,state的内容也会不同。
param_groups - 一个包含了全部参数组的dict。

(3)step(closure)

进行单次优化 (参数更新)。

closure参数是可选的。

(4)zero_grad()

清空所有被优化过的Variable的梯度。

下面给出几个最常用的优化器。

class torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)[source]

参数:

  • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
  • lr (float, 可选) – 学习率(默认:1e-3)
  • betas (Tuple[float, float], 可选) – 用于计算梯度以及梯度平方的运行平均值的系数(默认:0.9,0.999)
  • eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
  • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)

class torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)[source]

参数:

  • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
  • lr (float, 可选) – 学习率(默认:1e-2)
  • momentum (float, 可选) – 动量因子(默认:0)
  • alpha (float, 可选) – 平滑常数(默认:0.99)
  • eps (float, 可选) – 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
  • centered (bool, 可选) – 如果为True,计算中心化RMSProp,并且用它的方差预测值对梯度进行归一化
  • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认: 0)

class torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False)[source]

参数:

  • params (iterable) – 待优化参数的iterable或者是定义了参数组的dict
  • lr (float) – 学习率
  • momentum (float, 可选) – 动量因子(默认:0)
  • weight_decay (float, 可选) – 权重衰减(L2惩罚)(默认:0)
  • dampening (float, 可选) – 动量的抑制因子(默认:0)
  • nesterov (bool, 可选) – 使用Nesterov动量(默认:False)

例子:

>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> optimizer.zero_grad()
>>> loss_fn(model(input), target).backward()
>>> optimizer.step()

3. 调整学习率

torch.optim.lr_scheduler 提供了几种方法来根据 epoch 的数量调整学习率。

学习率调整应该在优化器更新后应用,比如:

model = [Parameter(torch.randn(2, 2, requires_grad=True))]
optimizer = SGD(model, 0.1)
scheduler = ExponentialLR(optimizer, gamma=0.9)

for epoch in range(20):
    for input, target in dataset:
        optimizer.zero_grad()
        output = model(input)
        loss = loss_fn(output, target)
        loss.backward()
        optimizer.step()
    scheduler.step()

torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=- 1, verbose=False)

将每个参数组的学习率设置为初始 lr 乘以给定函数。当 last_epoch=-1 时,设置initial lr 为 lr。

l r e p o c h = l r i n i t i a l ∗ l r _ l a m b d a ( e p o c h ) lr_{epoch} =lr_{initial} * lr\_lambda(epoch) lrepoch=lrinitiallr_lambda(epoch)

在这里插入图片描述

# Assuming optimizer has two groups.
lambda1 = lambda epoch: epoch // 30
lambda2 = lambda epoch: 0.95 ** epoch
scheduler = LambdaLR(optimizer, lr_lambda=[lambda1, lambda2])
for epoch in range(100):
    train(...)
    validate(...)
    scheduler.step()

torch.optim.lr_scheduler.MultiplicativeLR(optimizer, lr_lambda, last_epoch=- 1, verbose=False)

将每个参数组的学习率乘以指定函数中给出的因子。 当 last_epoch=-1 时,设置初始 lr 为 lr。

l r e p o c h = l r e p o c h − 1 ∗ l r _ l a m b d a ( e p o c h ) lr_{epoch} =lr_{epoch - 1} * lr\_lambda(epoch) lrepoch=lrepoch1lr_lambda(epoch)

在这里插入图片描述

lmbda = lambda epoch: 0.95
scheduler = MultiplicativeLR(optimizer, lr_lambda=lmbda)
for epoch in range(100):
    train(...)
    validate(...)
    scheduler.step()

torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=- 1, verbose=False)

step_size epochs 衰减每个参数组的学习率。 请注意,这种衰减可能与此调度程序外部对学习率的其他更改同时发生。 当 last_epoch=-1 时,设置初始 lr 为 lr。

在这里插入图片描述

# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.05     if epoch < 30
# lr = 0.005    if 30 <= epoch < 60
# lr = 0.0005   if 60 <= epoch < 90
# ...
scheduler = StepLR(optimizer, step_size=30, gamma=0.1)
for epoch in range(100):
    train(...)
    validate(...)
    scheduler.step()

torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=- 1, verbose=False)

一旦 epoch 的数量达到milestones之一,通过 gamma 衰减每个参数组的学习率。 请注意,这种衰减可能与此调度程序外部对学习率的其他更改同时发生。 当 last_epoch=-1 时,设置初始 lr 为 lr。

在这里插入图片描述

# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.05     if epoch < 30
# lr = 0.005    if 30 <= epoch < 80
# lr = 0.0005   if epoch >= 80
scheduler = MultiStepLR(optimizer, milestones=[30,80], gamma=0.1)
for epoch in range(100):
    train(...)
    validate(...)
    scheduler.step()

torch.optim.lr_scheduler.ConstantLR(optimizer, factor=0.3333333333333333, total_iters=5, last_epoch=- 1, verbose=False)

将每个参数组的学习率衰减一个小的常数因子,直到 epoch 的数量达到预定义的total_iters。 请注意,这种衰减可能与此调度程序外部对学习率的其他更改同时发生。 当 last_epoch=-1 时,设置初始 lr 为 lr。

在这里插入图片描述

# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.025   if epoch == 0
# lr = 0.025   if epoch == 1
# lr = 0.025   if epoch == 2
# lr = 0.025   if epoch == 3
# lr = 0.05    if epoch >= 4
scheduler = ConstantLR(self.opt, factor=0.5, total_iters=4)
for epoch in range(100):
    train(...)
    validate(...)
    scheduler.step()

torch.optim.lr_scheduler.LinearLR(optimizer, start_factor=0.3333333333333333, end_factor=1.0, total_iters=5, last_epoch=- 1, verbose=False)

通过线性改变小的乘法因子来衰减每个参数组的学习率,直到 epoch 的数量达到预定义的total_iters。 请注意,这种衰减可能与此调度程序外部对学习率的其他更改同时发生。 当 last_epoch=-1 时,设置初始 lr 为 lr。

在这里插入图片描述

# Assuming optimizer uses lr = 0.05 for all groups
# lr = 0.025    if epoch == 0
# lr = 0.03125  if epoch == 1
# lr = 0.0375   if epoch == 2
# lr = 0.04375  if epoch == 3
# lr = 0.05    if epoch >= 4
scheduler = LinearLR(self.opt, start_factor=0.5, total_iters=4)
for epoch in range(100):
    train(...)
    validate(...)
    scheduler.step()
  • 7
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值