目录

torch.optim

是一个实现各种优化算法的包。

已经支持最常用的方法,并且界面是通用的 足够了,因此更复杂的也可以轻松集成到 前途。

如何使用优化器

要使用,您必须构造一个 optimizer 对象,该对象将包含 当前状态,并将根据计算的梯度更新参数。

构建

要构造一个,你必须给它一个包含 参数(全部应为 S)进行优化。然后 您可以指定特定于优化器的选项,例如 Learning Rate(学习率)、权重衰减等。Variable

例:

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

每个参数选项

还支持指定每个参数的选项。要执行此操作,请改为 传递 s 的 iterable,传入 s 的 iterable。它们中的每一个都将定义一个单独的参数组,并且应该包含 一个键,其中包含属于它的参数列表。其他键 应与优化器接受的关键字参数匹配,并将使用 作为此组的优化选项。Variableparams

例如,当想要指定每层学习率时,这非常有用:

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

这意味着 的参数将使用 的学习率 ,而 的 参数将坚持默认的学习率 。 最后,动量 将用于所有参数。model.base1e-2model.classifier1e-30.9

注意

你仍然可以将选项作为关键字参数传递。它们将用作 defaults,位于未覆盖它们的组中。这在以下情况下非常有用 只想改变一个选项,同时保持所有其他选项一致 参数组之间。

另请考虑以下与参数的不同惩罚相关的示例。 请记住,这会返回一个 iterable , 包含所有可学习的参数,包括 biases 和其他 可能更喜欢不同惩罚的参数。要解决此问题,可以指定 每个参数组的单独惩罚权重:

bias_params = [p for name, p in self.named_parameters() if 'bias' in name]
others = [p for name, p in self.named_parameters() if 'bias' not in name]

optim.SGD([
                {'params': others},
                {'params': bias_params, 'weight_decay': 0}
            ], weight_decay=1e-2, lr=1e-2)

以这种方式,偏差项与非偏差项隔离开来,并且 of 是专门为偏差项设置的,以避免对 这个组。weight_decay0

采取优化步骤

所有优化器都实现了一个方法,该方法更新 参数。它可以通过两种方式使用:

optimizer.step()

这是大多数优化器支持的简化版本。该函数可以是 在使用 例如 .backward()

例:

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

optimizer.step(closure)

一些优化算法(如 Conjugate Gradient 和 LBFGS)需要 多次重新评估函数,因此您必须传入一个闭包,该闭包将 允许他们重新计算您的模型。闭包应清除梯度, 计算损失,然后返回。

例:

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

基类

torch.optim 中。优化器paramsdefaults[来源]

所有优化器的基类。

警告

需要将参数指定为具有确定性 排序,在运行之间保持一致。不这样做的对象示例 满足这些属性的是 dictionaries 值的 set 和 iterators。

参数
  • paramsiterable) - s 或 s 的可迭代对象。指定应优化的 Tensor。

  • defaultsDict[strAny]) – (dict):包含优化默认值的 dict options (在参数组未指定时使用)。

Optimizer.add_param_group

将 param 组添加到 s param_groups

Optimizer.load_state_dict

加载优化器状态。

Optimizer.register_load_state_dict_pre_hook

注册一个 load_state_dict pre-hook,它将在调用之前被调用。它应具有以下签名::。

Optimizer.register_load_state_dict_post_hook

注册一个 load_state_dict 后钩子,该钩子将在调用后调用。它应具有以下签名::。

Optimizer.state_dict

将优化器的状态作为 .

Optimizer.register_state_dict_pre_hook

注册一个 state dict pre-hook,它将在调用之前被调用。

Optimizer.register_state_dict_post_hook

注册一个 state dict post-hook,它将在调用后被调用。

优化器.step

执行单个优化步骤以更新参数。

Optimizer.register_step_pre_hook

注册一个 optimizer step pre hook,它将在 optimizer step 之前调用。

Optimizer.register_step_post_hook

注册一个 optimizer step post 钩子,该钩子将在 optimizer step 之后调用。

Optimizer.zero_grad

重置所有优化 s 的梯度。

算法

阿达德尔塔

实现 Adadelta 算法。

阿达因子

实现 Adafactor 算法。

阿达格勒

实现 Adagrad 算法。

亚当

实现 Adam 算法。

亚当W

实现 AdamW 算法。

稀疏亚当

SparseAdam 实现了适用于稀疏梯度的 Adam 算法的掩码版本。

阿达麦克斯

实现 Adamax 算法(基于无穷范数的 Adam 变体)。

ASGD

实现平均随机梯度下降。

LBFGS 公司

实现 L-BFGS 算法。

纳丹

实现 NAdam 算法。

RAdam

实现 RAdam 算法。

RMS属性

实现 RMSprop 算法。

Rprop

实现弹性反向传播算法。

新币

实现随机梯度下降(可选使用动量)。

我们的许多算法都有针对性能进行优化的各种实现, 可读性和/或通用性,因此我们尝试默认为通常最快的 implementation (如果尚未实现特定 由用户指定。

我们有 3 大类实现:for-loop、foreach(多张量)和 融合。最直接的实现是对参数进行 for 循环,其中 大块计算。For 循环通常比我们的 foreach 慢 实现,将参数组合成一个多张量并运行大块 的 County,从而节省了许多顺序的内核调用。我们的一些 优化器具有更快的融合实现,它融合了 计算到一个内核中。我们可以将 foreach 实现视为 fusing 水平融合实现,并在其上垂直融合。

通常,这 3 种实现的性能顺序> foreach > for 循环融合在一起。 因此,在适用时,我们默认在 for 循环中使用 foreach。Applicable 是指 foreach implementation is available,则用户尚未指定任何特定于 implementation 的 kwargs (例如,fused、foreach、differentiable),并且所有张量都是原生的。请注意,当 应该比 foreach 更快,实现更新,我们想给出 他们在到处拨动开关之前有更多的烘烤时间。我们总结了稳定性状态 对于下面第二个表中的每种实现,欢迎您尝试一下!

下表显示了每种算法的可用和默认实现:

算法

违约

有 foreach?

已融合?

阿达德尔塔

foreach

是的

阿达因子

for 循环

阿达格勒

foreach

是的

是(仅限 CPU)

亚当

foreach

是的

是的

亚当W

foreach

是的

是的

稀疏亚当

for 循环

阿达麦克斯

foreach

是的

ASGD

foreach

是的

LBFGS 公司

for 循环

纳丹

foreach

是的

RAdam

foreach

是的

RMS属性

foreach

是的

Rprop

foreach

是的

新币

foreach

是的

是的

下表显示了 fused implementations 的稳定性状态:

算法

中央处理器

CUDA 的

议员

阿达德尔塔

支持

支持

支持

阿达因子

支持

支持

支持

阿达格勒

试用版

支持

支持

亚当

试用版

稳定

试用版

亚当W

试用版

稳定

试用版

稀疏亚当

支持

支持

支持

阿达麦克斯

支持

支持

支持

ASGD

支持

支持

支持

LBFGS 公司

支持

支持

支持

纳丹

支持

支持

支持

RAdam

支持

支持

支持

RMS属性

支持

支持

支持

Rprop

支持

支持

支持

新币

试用版

试用版

试用版

如何调整学习率

提供了几种调整学习的方法 rate 基于 epoch 的数量。允许根据某些验证测量结果动态降低学习率。

学习率调度应在 optimizer 更新后应用;例如,您 应该这样编写你的代码:

例:

optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
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()

大多数学习率调度器都可以背靠背调用(也称为 链接调度器)。结果是,每个调度程序都在 other 的 Adobe,则根据前一个 Bean 获得的学习率。

例:

optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
scheduler1 = ExponentialLR(optimizer, gamma=0.9)
scheduler2 = MultiStepLR(optimizer, milestones=[30,80], gamma=0.1)

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()
    scheduler1.step()
    scheduler2.step()

在文档的许多地方,我们将使用以下模板来引用 scheduler 算法。

>>> scheduler = ...
>>> for epoch in range(100):
>>>     train(...)
>>>     validate(...)
>>>     scheduler.step()

警告

在 PyTorch 1.1.0 之前,学习率调度器应该在之前被调用 优化器的更新;1.1.0 以突破性的方式改变了这种行为。如果您使用 优化器更新之前的学习率调度器(调用 ) (调用 ),这将跳过学习率计划的第一个值。 如果升级到 PyTorch 1.1.0 后无法重现结果,请检查 如果您在错误的时间打电话。scheduler.step()optimizer.step()scheduler.step()

lr_scheduler。LRScheduler

调整优化期间的学习率。

lr_scheduler。LambdaLR

设置初始学习率。

lr_scheduler。乘法 LR

将每个参数组的学习率乘以指定函数中给定的因子。

lr_scheduler。StepLR

每 step_size 个 epoch 每 gamma 衰减每个参数组的学习率。

lr_scheduler。多步 LR

一旦纪元数达到其中一个里程碑,则按 gamma 衰减每个参数组的学习率。

lr_scheduler。常数LR

将每个参数组的学习率乘以一个小的常数因子。

lr_scheduler。线性LR

通过线性改变小的乘法因子来衰减每个参数组的学习率。

lr_scheduler。指数LR

每个 epoch 按 gamma 衰减每个参数组的学习率。

lr_scheduler。多项式 LR

在给定total_iters中使用多项式函数衰减每个参数组的学习率。

lr_scheduler。余弦退火LR

使用余弦退火计划设置每个参数组的学习率。

lr_scheduler。链式调度器

链接学习率计划程序列表。

lr_scheduler。顺序LR

包含预期在优化过程中按顺序调用的计划程序列表。

lr_scheduler。ReduceLROnPlateau

当指标停止改进时降低学习率。

lr_scheduler。CyclicLR

根据循环学习率策略 (CLR) 设置每个参数组的学习率。

lr_scheduler。一周期LR

根据 1cycle 学习率策略设置每个参数组的学习率。

lr_scheduler。CosineAnnealingWarmRestarts

使用余弦退火计划设置每个参数组的学习率。

权重平均(SWA 和 EMA)

实现随机权重平均 (SWA) 和指数移动平均线 (EMA),实现 SWA 学习率调度器,并且是用于更新 SWA/EMA 批处理的实用函数 训练结束时的标准化统计。

SWA 已在 平均权重导致更广泛的最优值和更好的泛化 中提出。

EMA 是一种广为人知的技术,它通过减少所需的权重更新次数来减少训练时间。它是 Polyak 平均法的变体,但在迭代中使用指数权重而不是相等的权重。

构建平均模型

AveragedModel 类用于计算 SWA 或 EMA 模型的权重。

您可以通过运行以下命令来创建 SWA 平均模型:

>>> averaged_model = AveragedModel(model)

EMA 模型是通过指定参数来构建的,如下所示:multi_avg_fn

>>> decay = 0.999
>>> averaged_model = AveragedModel(model, multi_avg_fn=get_ema_multi_avg_fn(decay))

Decay 是一个介于 0 和 1 之间的参数,用于控制平均参数的衰减速度。如果未提供给 ,则默认值为 0.999。

返回一个函数,该函数将以下 EMA 方程应用于权重:

Wt+1均线=αWt均线+(1α)WtW^\textrm{EMA}_{t+1} = \alpha W^\textrm{EMA}_{t} + (1 - \alpha) W^\textrm{model}_t

其中 alpha 是 EMA 衰减。

此处的模型可以是任意对象。 将跟踪 参数的运行平均值。更新这些 averages,你应该在 optimizer.step() 之后使用这个函数:modelaveraged_modelmodelupdate_parameters()

>>> averaged_model.update_parameters(model)

对于 SWA 和 EMA,此调用通常在 optimizer 之后立即完成。对于 SWA,通常会在训练开始时跳过某些步骤。step()

自定义平均策略

默认情况下,计算 提供的参数,但您也可以将自定义平均函数与 OR 参数一起使用:avg_fnmulti_avg_fn

  • avg_fn允许定义一个对每个参数元组(平均参数、模型参数)进行操作的函数,并应返回新的平均参数。

  • multi_avg_fn允许同时定义对参数列表元组(平均参数列表、模型参数列表)的更有效操作,例如使用函数。此函数必须就地更新平均参数。torch._foreach*

在以下示例中,使用参数计算指数移动平均线:ema_modelavg_fn

>>> ema_avg = lambda averaged_model_parameter, model_parameter, num_averaged:\
>>>         0.9 * averaged_model_parameter + 0.1 * model_parameter
>>> ema_model = torch.optim.swa_utils.AveragedModel(model, avg_fn=ema_avg)

在以下示例中,使用 more efficient 参数计算指数移动平均线:ema_modelmulti_avg_fn

>>> ema_model = AveragedModel(model, multi_avg_fn=get_ema_multi_avg_fn(0.9))

SWA 学习率计划

通常,在 SWA 中,学习率设置为较高的常量值。 是一个 学习率调度器,将学习率退火到一个固定值,然后保持它 不断。例如,下面的代码创建一个调度程序,该调度程序对 每个参数组内 5 个 epoch 的学习率从其初始值到 0.05:SWALR

>>> swa_scheduler = torch.optim.swa_utils.SWALR(optimizer, \
>>>         anneal_strategy="linear", anneal_epochs=5, swa_lr=0.05)

您还可以通过设置 来将余弦退火使用到固定值而不是线性退火。anneal_strategy="cos"

处理批量归一化

update_bn()是一个实用程序函数,允许计算 SWA 模型的 batchnorm 统计信息 在训练结束时,在给定的 DataLoader 上:loader

>>> torch.optim.swa_utils.update_bn(loader, swa_model)

update_bn()将 the 应用于 DataLoader 中的每个元素并计算激活 模型中每个批量归一化层的统计信息。swa_model

警告

update_bn()假设 DataLoader 中的每个批次都是一个张量或一个 张量,其中第一个元素是应应用网络的张量。 如果您的数据加载器具有不同的结构,您可以通过对数据集的每个元素执行前向传递来更新 的批量规范化统计信息。loaderswa_modelswa_modelswa_model

综上所述:SWA

在下面的示例中,是累积权重平均值的 SWA 模型。 我们训练模型总共 300 个 epoch,然后切换到 SWA 学习率计划 并开始收集 epoch 160 时参数的 SWA 平均值:swa_model

>>> loader, optimizer, model, loss_fn = ...
>>> swa_model = torch.optim.swa_utils.AveragedModel(model)
>>> scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=300)
>>> swa_start = 160
>>> swa_scheduler = SWALR(optimizer, swa_lr=0.05)
>>>
>>> for epoch in range(300):
>>>       for input, target in loader:
>>>           optimizer.zero_grad()
>>>           loss_fn(model(input), target).backward()
>>>           optimizer.step()
>>>       if epoch > swa_start:
>>>           swa_model.update_parameters(model)
>>>           swa_scheduler.step()
>>>       else:
>>>           scheduler.step()
>>>
>>> # Update bn statistics for the swa_model at the end
>>> torch.optim.swa_utils.update_bn(loader, swa_model)
>>> # Use swa_model to make predictions on test data
>>> preds = swa_model(test_input)

综上所述:EMA

在下面的示例中,是 EMA 模型,该模型以 0.999 的衰减率累积权重的指数衰减平均值。 我们训练模型总共 300 个 epoch,并立即开始收集 EMA 平均值。ema_model

>>> loader, optimizer, model, loss_fn = ...
>>> ema_model = torch.optim.swa_utils.AveragedModel(model, \
>>>             multi_avg_fn=torch.optim.swa_utils.get_ema_multi_avg_fn(0.999))
>>>
>>> for epoch in range(300):
>>>       for input, target in loader:
>>>           optimizer.zero_grad()
>>>           loss_fn(model(input), target).backward()
>>>           optimizer.step()
>>>           ema_model.update_parameters(model)
>>>
>>> # Update bn statistics for the ema_model at the end
>>> torch.optim.swa_utils.update_bn(loader, ema_model)
>>> # Use ema_model to make predictions on test data
>>> preds = ema_model(test_input)

swa_utils。平均模型

实施随机权重平均 (SWA) 和指数移动平均线 (EMA) 的平均模型。

swa_utils。斯瓦勒

将每个参数组中的学习率退火为固定值。

torch.optim.swa_utils。get_ema_multi_avg_fndecay=0.999[来源]

获取跨多个参数应用指数移动平均线 (EMA) 的函数。

torch.optim.swa_utils。update_bnloadermodeldevice=None[来源]

更新 BatchNorm running_mean,running_var模型中的缓冲区。

它在加载器中执行一次数据传递以估计激活 模型中 BatchNorm 层的统计信息。

参数
  • loadertorch.utils.data.DataLoader) – 用于计算 激活统计信息 on。每个数据批次应为 tensor 或第一个元素为 Tensor 的列表/元组 包含数据。

  • modeltorch.nn.Module) – 我们寻求更新 BatchNorm 的模型 统计学。

  • devicetorch.device可选) – 如果设置,则数据将在传递到 之前传输到。devicemodel

>>> loader, model = ...
>>> torch.optim.swa_utils.update_bn(loader, model)

注意

update_bn 实用程序假定每个数据批次都是一个张量或张量列表或元组;在后一种情况下,它 假定应该在第一个 元素。loadermodel.forward()

文档

访问 PyTorch 的全面开发人员文档

查看文档

教程

获取面向初学者和高级开发人员的深入教程

查看教程

资源

查找开发资源并解答您的问题

查看资源