如何使用一个优化器
为了使用torch.optim
,你必须构建一个优化对象,那将会保持现有的状态,并且基于计算的来更新参数。
为了构建一个优化器,你必须给定一个用来优化的参数的迭代器(所有应该是变量s)。然后,你能指定优化指定选项,例如学习率、权重衰减等。
注意:
If you need to move a model to GPU via .cuda()
, please do so before constructing optimizers for it. Parameters of a model after .cuda()
will be different objects with those before the call.In general, you should make sure that optimized parameters live in consistent locations when optimizers are constructed and used.
如果你通过.cuda()将一个模型移动到GPU,对它请在构建优化器之前这么做。.cuda()之后的模型参数与调用之前的参数是不同的对象。通常情况下,你应该确保使得优化在连续的位置上,当优化器构建和使用的时候。
例:
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
optimizer = optim.Adam([var1, var2], lr=0.0001)
Optimizer
s also support specifying per-parameter options. To do this, instead of passing an iterable of Variable
s, pass in an iterable of dict
s. Each of them will define a separate parameter group, and should contain a params
key, containing a list of parameters belonging to it. Other keys should match the keyword arguments accepted by the optimizers, and will be used as optimization options for this group.
Optimizers也支持预参数选项。这么做,代替传递一个可迭代的变量s,传入一个可迭代的字典s。它们的每一个都会定一个分离的参数组,并且应该包含一个参数键,包含一个属于它的参数列表。其余键应该匹配优化器接受的关键字参数,并将作为这个组的优化选项。
注意:
注意你依然能够传递关键字参数。它们将会被用作默认值,在不重写它们的组中。当你仅仅想改变一个单一的选项时这很有用,同时保持参数组之间的所有其他一致。例如,当需要指定每层的学习速率时,这是非常有用的:
optim.SGD([
{'params': model.base.parameters()},
{'params': model.classifier.parameters(), 'lr': 1e-3}
], lr=1e-2, momentum=0.9)
This means that model.base
’s parameters will use the default learning rate of 1e-2
, model.classifier
’s parameters will use a learning rate of 1e-3
, and a momentum of 0.9
will be used for all parameters.
这意味着model.base的参数将会使用默认的学习率1e-2,model.classifier的参数将会适应1e-3,对所有参数动量都设置为0.9。
所有优化器实现一个step()方法用来更新参数。它的使用方法有两种:
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)
一些优化算法例如联合提盒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.Optimizer
(params, defaults)[source]所有优化器的基类。
Warning
需要将参数指定为具有确定性排序、在运行之间保持一致的集合。不满足这些属性的对象的例子是集合和字典值的迭代器。
参数:
add_param_group
(param_group)[source]向Optimizer参数组加入一个参数组。当预先训练好的网络作为冻结层进行微调时,这是有用的,并且可以在训练过程中添加到优化器中。
参数:
load_state_dict
(state_dict)[source]载入优化器的状态。
参数:
state_dict
()[source]以字典的形式返回优化器的状态。
It contains two entries:
它包含两个部分:
step
(closure)[source]
执行一个单一的优化步骤(参数更新)。
参数:
zero_grad
()[source]清楚所有优化后的torch.Tensor的梯度。
torch.optim.Adadelta
(params, lr=1.0, rho=0.9, eps=1e-06, weight_decay=0)[source]实现Adadelta算法,实现这个算法的文章为:ADADELTA: An Adaptive Learning Rate Method
参数:
tep
(closure)[source]
执行一个单一的优化步骤(参数更新)。
参数:
torch.optim.Adagrad
(params, lr=0.01, lr_decay=0, weight_decay=0, initial_accumulator_value=0)[source]Implements Adagrad algorithm.
实现Adagrad算法,论文为:Adaptive Subgradient Methods for Online Learning and Stochastic Optimization
参数:
step
(closure)[source]执行一个单一的优化步骤(参数更新)。
参数:
torch.optim.Adam
(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)[source]实现Adam算法,论文为:Adam: A Method for Stochastic Optimization
Parameters
step
(closure)[source]执行一个单一的优化步骤(参数更新)。
参数:
torch.optim.AdamW
(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0.01, amsgrad=False)[source]实现AdamW算法。论文为:Adam: A Method for Stochastic Optimization,AdamW的变体为Decoupled Weight Decay Regularization。
Parameters
step
(closure)[source]执行一个单一的优化步骤(参数更新)。
参数:
torch.optim.SparseAdam
(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08)[source]实现了适合于稀疏张量的Adam算法的延迟版本。在这个变量中,只有梯度中出现的moments会被更新,并且只有梯度中的那些部分会被应用到参数中。
参数:
step
(closure)[source]执行一个单一的优化步骤(参数更新)。
参数:
torch.optim.Adamax
(params, lr=0.002, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)[source]实现了Adamax算法(基于无穷范数的Adam的变体)。实现的论文为:Adam: A Method for Stochastic Optimization
参数:
step
(closure)[source]执行一个单一的优化步骤(参数更新)。
参数:
torch.optim.ASGD
(params, lr=0.01, lambd=0.0001, alpha=0.75, t0=1000000.0, weight_decay=0)[source]实现平均随机梯度下降,实现论文为:Acceleration of stochastic approximation by averaging
参数:
step
(closure)[source]执行一个单一的优化步骤(参数更新)。
参数:
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)[source]实现L-BFGS算法,受https://www.cs.ubc.ca/~schmidtm/Software/minFunc.html启发。
警告:
这个优化器不支持每个参数选项和参数组(只能有一个)。
警告:
现在所有的参数都必须在单独的设备上。这点将来将会改进。
注意:
这是一个非常耗内存的优化器(它需要额外的param_bytes * (history_size + 1)bytes
)。如果它在内存在不匹配,尽力减少历史尺寸,或者使用不同的算法。
Parameters
step
(closure)[source]执行一个单一的优化步骤(参数更新)。
参数:
torch.optim.RMSprop
(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)[source]实现RMSprop算法,论文为:Generating Sequences With Recurrent Neural Networks
Parameters
step
(closure)[source]执行一个单一的优化步骤(参数更新)。
参数:
torch.optim.Rprop
(params, lr=0.01, etas=(0.5, 1.2), step_sizes=(1e-06, 50))[source]实现弹性反向传播算法。
参数:
step
(closure)[source]执行一个单一的优化步骤(参数更新)。
参数:
torch.optim.SGD
(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False)[source]实现动量可选的随机梯度下降算法。涅斯特洛夫动量是基于:On the importance of initialization and momentum in deep learning
参数:
例:
>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> optimizer.zero_grad()
>>> loss_fn(model(input), target).backward()
>>> optimizer.step()
Note
使用Momentum/Nesterov实现SGD与Sutskever等人以及其他一些框架中的实现有稍微的不同。考虑到Momentum的具体情况,更新可以写成:
其中p、g、v和\rho分别表示参数、梯度、速度和动量。这与Sutskever等和其他使用表单更新的框架形成了对比
涅斯特洛夫版本进行了类似的修改。
step
(closure)[source]执行一个单一的优化步骤(参数更新)。
参数:
torch.optim.lr_scheduler提供了几种基于epoch数调整学习速率的方法。torch.optim.lr_scheduler。ReduceLROnPlateau允许基于一些验证测量的动态学习率降低。优化器更新后应采用学习率调度;
例:你应该这样写代码:
>>> scheduler = ...
>>> for epoch in range(100):
>>> train(...)
>>> validate(...)
>>> scheduler.step()
警告:
在PyTorch 1.1.0之前,学习率调度器被期望在优化器更新之前被调用;1.1.0用BC-打断的方式改变这种行为。如果在优化器的更新之前使用学习率调度程序(调用scheduler.step()),这将跳过学习率调度的第一个值。如果在升级到PyTorch 1.1.0后无法重现结果,请检查是否在错误的时间调用scheduler.step()。
torch.optim.lr_scheduler.LambdaLR
(optimizer, lr_lambda, last_epoch=-1)[source]将每个参数组的学习率设置为给定函数的初始lr。当last_epoch=-1时,将初始lr设置为lr。
参数:
例:
>>> # 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()
load_state_dict
(state_dict)[source]加载策略状态。
参数:
state_dict (dict) – 调度的状态。应该是调用state_dict()返回的对象。
state_dict
()[source]以dict的形式返回调度程序的状态。它为self中的每个变量都包含一个条目。剩下的不是优化器。学习率lambda函数只有在它们是可调用对象时才会保存,而在它们是函数或lambdas时则不会保存。
torch.optim.lr_scheduler.StepLR
(optimizer, step_size, gamma=0.1, last_epoch=-1)[source]将每个参数组的学习速率设置为每个step_size epoch由gamma衰减的初始lr。当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)[source]将每个参数组的学习率设置为初始lr,一旦epoch的数量达到里程碑之一,就被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.ExponentialLR
(optimizer, gamma, last_epoch=-1)[source]将各参数组的学习率设为每历元gamma衰减的初始lr。当last_epoch=-1时,将初始lr设置为lr。
参数:
torch.optim.lr_scheduler.CosineAnnealingLR
(optimizer, T_max, eta_min=0, last_epoch=-1)[source]使用余弦退火调度设置每个参数组的学习率,其中\eta_{max}设置为初始lr, T_{cur}为SGDR中最后一次重启后的epoch数:
当上一个epoch=-1时,设置初始lr为lr。在SGDR: Stochastic Gradient Descent with Warm Restarts中提出。注意,这只实现了SGDR的余弦退火部分,而没有实现重启。
参数:
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)[source]当一个指标停止改进时降低学习率。一旦学习停滞,模型往往能将学习率降低2-10倍。这个调度器读取一个度量量,如果没有看到一个“patience”的epoch数的改进,学习率降低。
Parameters
例:
>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> scheduler = ReduceLROnPlateau(optimizer, 'min')
>>> for epoch in range(10):
>>> train(...)
>>> val_loss = validate(...)
>>> # Note that step should be called after validate()
>>> scheduler.step(val_loss)
torch.optim.lr_scheduler.CyclicLR
(optimizer, base_lr, max_lr, step_size_up=2000, step_size_down=None, mode='triangular', gamma=1.0, scale_fn=None, scale_mode='cycle', cycle_momentum=True, base_momentum=0.8, max_momentum=0.9, last_epoch=-1)[source]根据循环学习率策略(CLR)设置各参数组的学习率。 策略的周期是两个边界之间的学习率具有一个恒定的频率,如本文所述 Cyclical Learning Rates for Training Neural Networks. 这两个边界之间的距离可以按每次迭代或每个周期进行缩放。周期性学习率策略会在每批后改变学习率。步骤应在批处理已用于训练后调用。
这个类有三个内建策略,如论文所述:“三角形”:一个基本的无振幅缩放的三角形周期。
“triangular2”:
一种基本的三角形周期,每周期将初始振幅减半。
“exp_range”:
在每个周期迭代中以gamma**(周期迭代)衡量初始振幅的一种周期。这个实现改编自github repo: bckenstler/CLR。
参数:
例:
>>> optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
>>> scheduler = torch.optim.lr_scheduler.CyclicLR(optimizer, base_lr=0.01, max_lr=0.1)
>>> data_loader = torch.utils.data.DataLoader(...)
>>> for epoch in range(10):
>>> for batch in data_loader:
>>> train_batch(...)
>>> scheduler.step()
get_lr
()[source]计算批处理索引的学习率。这个函数自我处理。last_epoch作为最后一批索引。如果自我。如果为True,则该函数的副作用是更新优化器的动量。