# torch.optim

1.  [如何使用 optimizer](#how-to-use-an-optimizer)
    *   [构建](#constructing-it)
    *   [为每个参数单独设置选项](#per-parameter-options)
    *   [进行单次优化](#taking-an-optimization-step)
    *   [optimizer.step（）](#optimizer.step（）)
    *   [optimizer.step(closure)](#optimizer.step(closure))
2.  [算法](#algorithms)
3.  [如何调整学习率](#how-to-adjust-learning-rate)

* * *

`torch.optim`是实现各种优化算法的包。最常用的方法都已经支持，接口很常规，所以以后也可以很容易地集成更复杂的方法。

#### 如何使用 optimizer

要使用`torch.optim`，您必须构造一个`optimizer`对象。这个对象能保存当前的参数状态并且基于计算梯度更新参数

#### 构建

要构造一个`Optimizer`，你必须给它一个包含参数（必须都是`Variable`对象）进行优化。然后，您可以指定`optimizer`的参 数选项，比如学习率，权重衰减等。

例子：

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

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

`Optimizer`也支持为每个参数单独设置选项。若想这么做，不要直接传入`Variable`的`iterable`，而是传入`dict 的 iterable`。每一个`dict`都分别定 义了一组参数，并且包含一个`param`键，这个键对应参数的列表。其他的键应该`optimizer`所接受的其他参数的关键字相匹配，并且会被用于对这组参数的 优化。

> 注意：
> 
> 您仍然可以将选项作为关键字参数传递。它们将被用作默认值，在不覆盖它们的组中。当您只想改变一个选项，同时保持参数组之间的所有其他选项一致时，这很有用。

例如，当我们想指定每一层的学习率时，这是非常有用的：

```py
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`将会被用于所有的参数。

#### 进行单次优化

所有的`optimizer`都会实现`step()`更新参数的方法。它能按两种方式来使用：

#### optimizer.step()

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

例子

```py
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`需要重复多次计算函数，因此你需要传入一个闭包去允许它们重新计算你的模型。这个闭包会清空梯度， 计算损失，然后返回。

例子：

```py
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) 
```

#### 算法

```py
class torch.optim.Optimizer(params, defaults) 
```

所有优化的基类.

参数：

1.  params (iterable) —— 可迭代的`Variable` 或者 `dict`。指定应优化哪些变量。
2.  defaults-(dict)：包含优化选项的默认值的 dict（一个参数组没有指定的参数选项将会使用默认值）。

```py
load_state_dict(state_dict) 
```

加载`optimizer`状态

参数：

1.  state_dict (dict) —— `optimizer`的状态。应该是`state_dict()`调用返回的对象。

```py
state_dict() 
```

将优化器的状态返回为一个`dict`。

它包含两个内容：

1.  state - 持有当前`optimization`状态的`dict`。它包含了 优化器类之间的不同。
2.  param_groups - 一个包含了所有参数组的`dict`。

```py
step(closure) 
```

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

参数：

1.  closure (callable,可选) – 重新评估模型并返回损失的闭包。hon zero_grad()

清除所有优化过的`Variable`的梯度。

```py
class torch.optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-06, weight_decay=0) 
```

实现`Adadelta`算法。

[ADADELTA](https://arxiv.org/abs/1212.5701)中提出了一种[自适应学习速率法](https://arxiv.org/abs/1212.5701)。

参数：

1.  params (iterable) – 用于优化的可以迭代参数或定义参数组
2.  rho (float, 可选) – 用于计算平方梯度的运行平均值的系数（默认值：0.9）
3.  eps (float, 可选) – 增加到分母中以提高数值稳定性的术语（默认值：1e-6）
4.  lr (float, 可选) – 将 delta 应用于参数之前缩放的系数（默认值：1.0）
5.  weight_decay (float, 可选) – 权重衰减 (L2 范数)（默认值: 0）

```py
step(closure) 
```

执行单个优化步骤。

参数：

1.  closure (callable,可选) – 重新评估模型并返回损失的闭包。

```py
class torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0) 
```

实现 Adagrad 算法。

在[在线学习和随机优化的自适应子梯度方法](http://jmlr.org/papers/v12/duchi11a.html)中被提出。

参数：

1.  params (iterable) – 用于优化的可以迭代参数或定义参数组
2.  lr (float, 可选) – 学习率（默认: 1e-2）
3.  lr_decay (float, 可选) – 学习率衰减（默认: 0）
4.  weight_decay (float, 可选) – 权重衰减（L2 范数）（默认: 0）

```py
step(closure) 
```

执行单个优化步骤。

参数：

1.  closure (callable,可选) – 重新评估模型并返回损失的闭包。

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

实现 Adam 算法。

它在[Adam: A Method for Stochastic Optimization](https://arxiv.org/abs/1412.6980)中被提出。

参数：

1.  params (iterable) – 用于优化的可以迭代参数或定义参数组
2.  lr (float, 可选) – 学习率（默认：1e-3）
3.  betas (Tuple[float, float], 可选) – 用于计算梯度运行平均值及其平方的系数（默认：0.9，0.999）
4.  eps (float, 可选) – 增加分母的数值以提高数值稳定性（默认：1e-8）
5.  weight_decay (float, 可选) – 权重衰减（L2 范数）（默认: 0）

```py
step(closure) 
```

执行单个优化步骤。

参数：

1.  closure (callable,可选) – 重新评估模型并返回损失的闭包。

```py
class torch.optim.Adamax(params, lr=0.002, betas=(0.9, 0.999), eps=1e-08, weight_decay=0) 
```

实现`Adamax`算法（Adam 的一种基于无穷范数的变种）。

它在[Adam: A Method for Stochastic Optimization](https://arxiv.org/abs/1412.6980)中被提出。

参数：

1.  params (iterable) – 用于优化的可以迭代参数或定义参数组
2.  lr (float, 可选) – 学习率（默认：2e-3）
3.  betas (Tuple[float, float], 可选) – 用于计算梯度以及梯度平方的运行平均值的系数
4.  eps (float, 可选) – 增加分母的数值以提高数值稳定性（默认：1e-8）
5.  weight_decay (float, 可选) – 权重衰减（L2 范数）（默认: 0）

```py
step(closure=None) 
```

执行单个优化步骤。

参数：

1.  closure (callable,可选) – 重新评估模型并返回损失的闭包。

```py
class torch.optim.ASGD(params, lr=0.01, lambd=0.0001, alpha=0.75, t0=1000000.0, weight_decay=0) 
```

实现平均随机梯度下降。

它在[Acceleration of stochastic approximation by averaging](http://dl.acm.org/citation.cfm?id=131098)中被提出。

参数：

1.  params (iterable) – 用于优化的可以迭代参数或定义参数组
2.  lr (float, 可选) – 学习率（默认：1e-2）
3.  lambd (float, 可选) – 衰减期（默认：1e-4）
4.  alpha (float, 可选) – eta 更新的指数（默认：0.75）
5.  t0 (float, 可选) – 指明在哪一次开始平均化（默认：1e6）
6.  weight_decay (float, 可选) – 权重衰减（L2 范数）（默认: 0）

```py
step(closure) 
```

执行单个优化步骤。

参数：

1.  closure (callable,可选) – 重新评估模型并返回损失的闭包。

```py
class torch.optim.LBFGS(params, lr=1, max_iter=20, max_eval=None, tolerance_grad=1e-05, tolerance_change=1e-09, history_size=100, line_search_fn=None) 
```

实现 L-BFGS 算法。

> 警告: 这个 optimizer 不支持为每个参数单独设置选项以及不支持参数组（只能有一个） 现在所有参数必须在单个设备上。将来会有所改善。
> 
> 注意: 这是一个内存高度密集的 optimizer（它要求额外的`param_bytes * (history_size + 1)` 个字节）。如果它不适应内存，尝试减小 history size，或者使用不同的算法。

参数：

1.  lr (float) – 学习率（默认：1）
2.  max_iter (int) – 每个优化步骤的最大迭代次数（默认：20）)
3.  max_eval (int) – 每个优化步骤的最大函数评估次数（默认：max * 1.25）
4.  tolerance_grad (float) – 一阶最优的终止容忍度（默认：1e-5）
5.  tolerance_change (float) – 功能值/参数更改的终止公差（默认：1e-9）
6.  history_size (int) – 更新历史记录大小（默认：100）

```py
step(closure) 
```

执行单个优化步骤。

参数：

1.  closure (callable,可选) – 重新评估模型并返回损失的闭包。

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

实现`RMSprop`算法。

由`G. Hinton`在他的[课程中提出](http://www.cs.toronto.edu/~tijmen/csc321/slides/lecture_slides_lec6.pdf).

中心版本首次出现在[Generating Sequences With Recurrent Neural Networks](https://arxiv.org/pdf/1308.0850v5.pdf).

参数：

1.  params (iterable) – 用于优化的可以迭代参数或定义参数组
2.  lr (float, 可选) – 学习率（默认：1e-2）
3.  momentum (float, 可选) – 动量因子（默认：0）
4.  alpha (float, 可选) – 平滑常数（默认：0.99）
5.  eps (float, 可选) – 增加分母的数值以提高数值稳定性（默认：1e-8）
6.  centered (bool, 可选) – 如果为 True，计算中心化的 RMSProp，通过其方差的估计来对梯度进行归一化
7.  weight_decay (float, 可选) – 权重衰减（L2 范数）（默认: 0）

```py
step(closure) 
```

执行单个优化步骤。

参数：

1.  closure (callable,可选) – 重新评估模型并返回损失的闭包。

```py
class torch.optim.Rprop(params, lr=0.01, etas=(0.5, 1.2), step_sizes=(1e-06, 50)) 
```

实现弹性反向传播算法。

参数：

1.  params (iterable) – 用于优化的可以迭代参数或定义参数组
2.  lr (float, 可选) – 学习率（默认：1e-2）
3.  etas (Tuple[float, float], 可选) – 一对（etaminus，etaplis）, 它们是乘数增加和减少因子（默认：0.5，1.2）
4.  step_sizes (Tuple[float, float], 可选) – 允许的一对最小和最大的步长（默认：1e-6，50）

```py
step(closure) 
```

执行单个优化步骤。

参数：

1.  closure (callable,可选) – 重新评估模型并返回损失的闭包。

```py
class torch.optim.SGD(params, lr=, momentum=0, dampening=0, weight_decay=0, nesterov=False) 
```

实现随机梯度下降算法（momentum 可选）。

Nesterov 动量基于[On the importance of initialization and momentum in deep learning](http://www.cs.toronto.edu/~hinton/absps/momentum.pdf)中的公式.

参数：

1.  params (iterable) – 用于优化的可以迭代参数或定义参数组
2.  lr (float) – 学习率
3.  momentum (float, 可选) – 动量因子（默认：0）
4.  weight_decay (float, 可选) – 权重衰减（L2 范数）（默认：0）
5.  dampening (float, 可选) – 动量的抑制因子（默认：0）
6.  nesterov (bool, 可选) – 使用 Nesterov 动量（默认：False）

例子：

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

提示：

> 带有动量/Nesterov 的 SGD 的实现稍微不同于 Sutskever 等人以及其他框架中的实现。 考虑到 Momentum 的具体情况，更新可以写成 v=ρ∗v+g p=p−lr∗v 其中，p、g、v 和ρ分别是参数、梯度、速度和动量。 这是在对比 Sutskever et. al。和其他框架采用该形式的更新 v=ρ∗v+lr∗g p=p−v Nesterov 版本被类似地修改。

```py
step(closure) 
```

执行单个优化步骤。

参数：

1.  closure (callable,可选) – 重新评估模型并返回损失的闭包。

#### 如何调整学习率

`torch.optim.lr_scheduler` 提供了几种方法来根据 epoches 的数量调整学习率。 `torch.optim.lr_scheduler.ReduceLROnPlateau`允许基于一些验证测量来降低动态学习速率。

```py
class torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1) 
```

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

参数：

1.  optimizer (Optimizer) – 包装的优化器。
2.  lr_lambda (function or list) – 一个函数来计算一个乘法因子给定一个整数参数的`epoch`，或列表等功能，为每个组`optimizer.param_groups`。
3.  last_epoch (int) – 最后一个时期的索引。默认: -1.

例子：

```py
>>> # 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):
>>>     scheduler.step()
>>>     train(...)
>>>     validate(...) 
```

```py
class torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1) 
```

将每个参数组的学习速率设置为每个 step_size 时间段由 gamma 衰减的初始 lr。当 last_epoch = -1 时，将初始 lr 设置为 lr。

1.  optimizer (Optimizer) – 包装的优化器。
2.  step_size (int) – 学习率衰减期。
3.  gamma (float) – 学习率衰减的乘积因子。默认值:-0.1。
4.  last_epoch (int) – 最后一个时代的指数。默认值:1。

例子：

```py
>>> # Assuming optimizer uses lr = 0.5 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):
>>>     scheduler.step()
>>>     train(...)
>>>     validate(...) 
```

```py
class torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=-1) 
```

一旦时间的数量达到一个里程碑,则将每个参数组的学习率设置为伽玛衰减的初始值。当 last_epoch=-1 时，将初始 lr 设置为 lr。

参数：

1.  optimizer (Optimizer) – 包装的优化器。
2.  milestones (list) – 时期指标的列表。必须增加。
3.  gamma (float) – 学习率衰减的乘积因子。 默认: -0.1.
4.  last_epoch (int) – 最后一个时代的指数。 默认: -1.

例子：

```py
>>> # Assuming optimizer uses lr = 0.5 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):
>>>     scheduler.step()
>>>     train(...)
>>>     validate(...) 
```

```py
class torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma, last_epoch=-1) 
```

将每个参数组的学习速率设置为每一个时代的初始 lr 衰减。当 last_epoch=-1 时，将初始 lr 设置为 lr。

1.  optimizer (Optimizer) – 包装的优化器。
2.  gamma (float) – 学习率衰减的乘积因子。
3.  last_epoch (int) – 最后一个指数。默认: -1.

```py
class torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10, verbose=False, threshold=0.0001, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08) 
```

当指标停止改善时，降低学习率。当学习停滞不前时，模型往往会使学习速度降低 2-10 倍。这个调度程序读取一个指标量，如果没有提高 epochs 的数量，学习率就会降低。

1.  optimizer (Optimizer) – 包装的优化器。
2.  mode (str) – min, max 中的一个. 在最小模式下，当监测量停止下降时，lr 将减少; 在最大模式下，当监控量停止增加时，会减少。默认值：'min'。
3.  factor (float) – 使学习率降低的因素。 new_lr = lr * factor. 默认: 0.1.
4.  patience (int) –epochs 没有改善后，学习率将降低。 默认: 10.
5.  verbose (bool) – 如果为 True，则会向每个更新的 stdout 打印一条消息。 默认: False.
6.  threshold (float) – 测量新的最优值的阈值，只关注显着变化。 默认: 1e-4.
7.  threshold*mode (str) – rel, abs 中的一个. 在 rel 模型, dynamic_threshold = best* ( 1 + threshold ) in ‘max’ mode or best_ ( 1 - threshold ) 在最小模型. 在绝对值模型中, dynamic_threshold = best + threshold 在最大模式或最佳阈值最小模式. 默认: ‘rel’.
8.  cooldown (int) – 在 lr 减少后恢复正常运行之前等待的时期数。默认的: 0.
9.  min_lr (float or list) – 标量或标量的列表。对所有的组群或每组的学习速率的一个较低的限制。 默认: 0.
10.  eps (float) – 适用于 lr 的最小衰减。如果新旧 lr 之间的差异小于 eps，则更新将被忽略。默认: 1e-8.

```py
>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> scheduler = torch.optim.ReduceLROnPlateau(optimizer, 'min')
>>> for epoch in range(10):
>>>     train(...)
>>>     val_loss = validate(...)
>>>     # Note that step should be called after validate()
>>>     scheduler.step(val_loss) 
```

### 译者署名

| 用户名 | 头像 | 职能 | 签名 |
| --- | --- | --- | --- |
| [Song](https://ptorch.com) | ![](img/2018033000352689884.jpeg) | 翻译 | 人生总要追求点什么 |