(一). torch.nn.init
torch.nn.init.calculate_gain(nonlinearity, param=None)
:返回给定非线性函数的推荐增益值
参数
(1)nonlinearity :非线性函数(nn.functional名称)
(2)param:非线性函数的可选参数
import torch
from torch import nn
gain = nn.init.calculate_gain('leaky_relu', 0.2) # leaky_relu with negative_slope=0.2
print(gain)
# 1.3867504905630728
torch.nn.init.uniform_(tensor, a=0.0, b=1.0)
:从均匀分布 U ( a , b ) U(a, b) U(a,b)中生成值,填充输入的张量
参数:
(1)tensor - n 维的 torch.Tensor
(2)a - 均匀分布的下界
(3)b - 均匀分布的上界
import torch
from torch import nn
w = torch.Tensor(3, 5)
torch.nn.init.uniform_(w, a=0, b=1)
print(w)
# tensor([[0.0101, 0.5684, 0.7960, 0.2908, 0.6355],
# [0.3007, 0.0232, 0.8758, 0.0279, 0.9806],
# [0.0808, 0.1687, 0.9116, 0.6530, 0.8266]])
torch.nn.init.normal_(tensor, mean=0, std=1)
:从给定均值和标准差的正态分布 N ( m e a n , s t d ) N(mean, std) N(mean,std)中生成值,填充输入的张量或变量
参数:
(1)tensor – n 维的 torch.Tensor
(2)mean – 正态分布的均值
(3)std – 正态分布的标准差
import torch
from torch import nn
w = torch.Tensor(3, 5)
torch.nn.init.normal_(w, mean=0, std=1)
print(w)
# tensor([[ 0.4358, 0.9809, -0.0709, 1.9040, 1.6294],
# [-1.8014, 0.9467, 0.1288, 0.8142, 0.6511],
# [-0.6489, -0.7123, 0.9353, 0.6714, -0.3414]])
torch.nn.init.constant_(tensor, val)
:用 val 的值填充输入的张量或变量
参数:
(1)tensor – n 维的 torch.Tensor
(2)val – 用来填充张量的值
import torch
from torch import nn
w = torch.Tensor(3, 5)
torch.nn.init.constant_(w, 1)
print(w)
# tensor([[1., 1., 1., 1., 1.],
# [1., 1., 1., 1., 1.],
# [1., 1., 1., 1., 1.]])
torch.nn.init.eye_(tensor)
: 用单位矩阵来填充 2 维输入张量或变量。在线性层尽可能多的保存输入特性。
参数:
(1)tensor – 2 维的 torch.Tensor
import torch
from torch import nn
w = torch.Tensor(3, 5)
torch.nn.init.eye_(w)
print(w)
# tensor([[1., 0., 0., 0., 0.],
# [0., 1., 0., 0., 0.],
# [0., 0., 1., 0., 0.]])
torch.nn.init.dirac_(tensor)
:用 Dirac δ \delta δ 函数来填充{3, 4, 5}维输入张量或变量。在卷积层尽可能多的保存输入通道特性。
参数:
(1)tensor – {3, 4, 5}维的 torch.Tensor
import torch
from torch import nn
w = torch.Tensor(3, 16, 5, 5)
nn.init.dirac_(w)
print(w)
torch.nn.init.xavier_uniform_(tensor, gain=1)
:
用一个均匀分布生成值,填充输入的张量或变量。结果张量中的值采样自U(-a, a)
,其中 a = g a i n ∗ 6 ( f a n i n + f a n o u t ) a= gain * \sqrt{\frac{6}{(fan_{in} + fan_{out})}} a=gain∗(fanin+fanout)6. 该方法也被称为 Glorot initialisation。
参数:
(1)tensor – n 维的 torch.Tensor
(2)gain - 可选的缩放因子
import torch
from torch import nn
w = torch.Tensor(3, 5)
nn.init.xavier_uniform_(w)
print(w)
# tensor([[-0.6292, -0.4168, 0.0928, 0.4738, -0.7620],
# [ 0.0298, -0.2910, 0.7949, -0.1126, -0.0923],
# [ 0.0826, 0.6109, 0.6849, 0.3916, -0.6962]])
torch.nn.init.xavier_normal_(tensor, gain=1)
:
用一个正态分布生成值,填充输入的张量或变量。结果张量中的值采样自 N ( 0 , s t d 2 ) N(0,std ^2) N(0,std2),其中 s t d = g a i n ∗ 2 ( f a n i n + f a n o u t ) std= gain * \sqrt{\frac{2}{(fan_{in} + fan_{out})}} std=gain∗(fanin+fanout)2。
参数:
(1)tensor – n 维的 torch.Tensor
(2)gain - 可选的缩放因子
import torch
from torch import nn
w = torch.Tensor(3, 5)
nn.init.xavier_normal_(w, gain=nn.init.calculate_gain('relu'))
print(w)
# tensor([[ 0.3165, -0.7378, -0.6553, -0.3155, 0.1545],
# [ 1.4315, -1.3310, -0.2756, 0.0107, -1.0390],
# [ 0.6061, 0.5712, 0.2102, 1.3376, -1.0680]])
torch.nn.init.kaiming_uniform_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
:用一个均匀分布生成值,填充输入的张量或变量。结果张量中的值采样自U(-bound, bound)
,其中 b o u n d = g a i n ∗ 3 f a n _ m o d e bound =gain* \sqrt{\frac{3}{fan\_mode}} bound=gain∗fan_mode3。也被称为 He initialisation.
参数:
(1)tensor:n 维的 torch.Tensor
(2)a:leaky_relu的负斜率,只有在nonlinearity='leaky_relu'
时候起作用
(3)mode:fan_in
或者fan_out
。fan_in
保留forward传递中权重的方差大小,fan_out
保留backward传递中权重的方差大小
(4)nonlinearity:nn.functional名称,推荐使用relu
和leaky_relu
。
import torch
from torch import nn
w = torch.Tensor(3, 5)
nn.init.kaiming_uniform_(w, mode='fan_in', nonlinearity='relu')
print(w)
# tensor([[ 0.6609, -0.9657, -0.9692, -0.9983, 1.0530],
# [ 0.3954, -0.1553, -0.0448, -0.1166, -0.8168],
# [-0.1180, -0.4374, -0.5326, 0.8863, -0.8473]])
torch.nn.init.kaiming_normal_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
:
用一个正态分布生成值,填充输入的张量或变量。结果张量中的值采样自 N ( 0 , s t d 2 ) N(0,std ^2) N(0,std2),其中 s t d = g a i n f a n _ m o d e std= \frac{gain}{\sqrt{fan\_mode}} std=fan_modegain。
参数:
(1)tensor:n 维的 torch.Tensor
(2)a:leaky_relu的负斜率,只有在nonlinearity='leaky_relu'
时候起作用
(3)mode:fan_in
或者fan_out
。fan_in
保留forward传递中权重的方差大小,fan_out
保留backward传递中权重的方差大小
(4)nonlinearity:nn.functional名称,推荐使用relu
和leaky_relu
。
import torch
from torch import nn
w = torch.Tensor(3, 5)
nn.init.kaiming_normal_(w, mode='fan_out', nonlinearity='relu')
print(w)
# tensor([[-0.3567, -0.3236, 2.0115, 1.0598, 0.6319],
# [-0.3399, -0.7596, -1.5590, -1.0110, -0.3785],
# [ 1.4363, 0.6400, -0.7000, 1.1070, 1.4729]])
torch.nn.init.sparse_(tensor, sparsity, std=0.01)
:将 2 维的输入张量或变量当做稀疏矩阵填充,结果张量中的值采样自N(0,0.01)
,其中非零元素根据一个均值为 0,标准差为 std 的正态分布生成。
参数:
(1)tensor – n 维的 torch.Tensor
(2)sparsity - 每列中需要被设置成零的元素比例
(3)std - 用于生成非零值的正态分布的标准差
import torch
from torch import nn
w = torch.Tensor(3, 5)
nn.init.sparse(w, sparsity=0.1)
print(w)
# tensor([[ 0.0080, 0.0051, -0.0036, 0.0000, 0.0000],
# [ 0.0116, 0.0191, -0.0101, -0.0060, -0.0058],
# [ 0.0000, 0.0000, 0.0000, 0.0069, 0.0159]])
(二).torch.optim
torch.optim 是一个实现了各种优化算法的库。大多数常用的方法已经得到支持,接口也足够通用,因此将来也可以轻松集成更复杂的方法。
1.如何使用 optimizer
为了使用 torch.optim,你需要构建一个 optimizer 对象。这个对象能够保持当前参数状态并基于计算得到的梯度进行参数更新。
构建
为了构建一个 Optimizer,你需要给它一个包含了需要优化的参数(必须都是 Variable 对象)的 iterable。然后,你可以设置 optimizer 的参数选项,比如学习率,权重衰减,等等。
举例:
optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9)
optimizer = optim.Adam([var1, var2], lr = 0.0001)
注意:
如果你需要通过.cuda()将模型移动到GPU,请在为它构建优化器之前这样做。在.cuda()之后的模型参数与调用之前的参数是不同的对象。
通常,在构造和使用优化器时,应该确保优化参数位置的一致。
2.为每个参数单独设置选项
Optimizer 也支持单独设置每个参数选项。若想这么做,不要直接传入 Variable 的 iterable,而是传入 dict 的 iterable。每一个 dict 都分别定 义了一组参数,并且包含一个 params 键值,这个键对应参数的列表。其他的键应该与 optimizer 所接受的关键字参数相匹配,并且会被用于对这组参数的优化。
注意:
您仍然可以将选项作为关键字参数传递。在未重写这些选项的组中,它们会被用作默认值。当你只想改动一个参数组的选项,但其他参数组的选项不变时,这是非常有用的。
例如,当我们想指定每一层的学习率时,这是非常有用的:
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
将会被用于所 有的参数。
3.进行单次优化
所有的 optimizer 都实现了 step()方法,这个方法会更新所有的参数。它能按两种方式来使用:
optimizer.step()
这是大多数 optimizer 所支持的简化版本。一旦梯度被如 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
需要重复多次计算函数,因此你需要传入一个闭包(closure)去允许它们重新计算你的模型。这个闭包应当清空梯度, 计算损失,然后返回。
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)
4. 基类torch.optim.Optimizer(params, defaults)
所有优化器的基类。
参数
(1)params (iterable)
:一个可迭代的torch.Tensor
或者dict
,指定哪些张量需要优化。
(2)defaults – (dict)
:包含优化器选项默认值的字典(当参数组没有指定它们时使用)
属性
(1)Optimizer.add_param_group(param_group)
:向优化器的参数组添加一个参数组。这在微调预训练网络时很有用,因为可以使冻结层可训练并随着训练的进行添加到优化器中。
(2)Optimizer.load_state_dict(state_dict)
:加载优化器状态。state_dict (dict)
-优化器状态。应该是调用state_dict()返回的对象。
(3)Optimizer.state_dict()
:以字典的形式返回优化器的状态。它包含两个条目:1)state:保持当前优化器状态的字典。不同的优化器它的内容是不同的。2)param_groups:包含所有参数组的字典
(4)Optimizer.step(closure)
:执行单个优化步骤(参数更新)。closure:重新评估模型并返回损失的闭包。大多数优化器都是可选的。除非另有说明,否则该函数不应修改参数的.grad字段。
(5)Optimizer.zero_grad(set_to_none=False)
:设置所有优化的torch.Tensor
的梯度置为0。
5. 算法
torch.optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-06,weight_decay=0)
实现 Adadelta 算法。
参数:
(1)params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dict
(2)rho (float, 可选)
– 用于计算平方梯度的运行平均值的系数(默认:0.9)
(3)eps (float, 可选)
– 为了增加数值计算的稳定性而加到分母里的项(默认:1e-6)
(4)lr (float, 可选)
– 在 delta 被应用到参数更新之前对它缩放的系数(默认:1.0)
(5)weight_decay (float, 可选)
– 权重衰减(L2 惩罚)(默认: 0)torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0)
实现 Adagrad 算法。
参数:
(1)params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dict
(2)lr (float, 可选)
– 学习率(默认: 1e-2)
(3)lr_decay (float, 可选)
– 学习率衰减(默认: 0)
(4)weight_decay (float, 可选)
– 权重衰减(L2 惩罚)(默认: 0)torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08,weight_decay=0)
参数:
(1)params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dict
(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)torch.optim.AdamW(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0.01, amsgrad=False)
实现AdamW算法。
参数:
(1)params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的dict
(2)lr (float, 可选)
– 学习率(默认:1e-3
)
(3)betas (Tuple[float, float], 可选)
– 用于计算梯度以及梯度平方的运行平均值的系数(默认:0.9,0.999
)
(4)eps (float, 可选)
– 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8
)
(5)weight_decay (float, 可选)
– 权重衰减(默认:1e-2
)
(6)amsgrad (boolean, 可选)
– 是否使用该算法的AMSGrad
变体torch.optim.SparseAdam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08)
实现了适用于稀疏张量的lazy版本Adam算法。
参数:
(1)params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的dict
(2)lr (float, 可选)
– 学习率(默认:1e-3
)
(3)betas (Tuple[float, float], 可选)
– 用于计算梯度以及梯度平方的运行平均值的系数(默认:0.9,0.999
)
(4)eps (float, 可选)
– 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8
)torch.optim.Adamax(params, lr=0.002, betas=(0.9, 0.999), eps=1e-08,weight_decay=0)
实现 Adamax 算法(Adam 的一种基于无穷范数的变种)。
参数:
(1)params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dict
(2)lr (float, 可选)
– 学习率(默认:2e-3)
(3)betas (Tuple[float, float], 可选)
– 用于计算梯度以及梯度平方的运行平均值的系数
(4)eps (float, 可选)
– 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)
(5)weight_decay (float, 可选)
– 权重衰减(L2 惩罚)(默认: 0)torch.optim.ASGD(params, lr=0.01, lambd=0.0001, alpha=0.75, t0=1000000.0,weight_decay=0)
实现平均随机梯度下降算法。
参数:
(1)params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dict
(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)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)torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0,momentum=0, centered=False)
实现 RMSprop 算法。
参数:
(1)params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dict
(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)torch.optim.Rprop(params, lr=0.01, etas=(0.5, 1.2), step_sizes=(1e-06,50))
实现弹性反向传播算法。
参数:
(1)params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dict
(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)torch.optim.SGD(params, lr=, monentum=0, dampening=0, weight_decay=0,nesterov=False)
实现随机梯度下降算法(momentum 可选)。
参数:
(1)params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dict
(2)lr (float)
– 学习率
(3)momentum (float, 可选)
– 动量因子(默认:0)
(4)weight_decay (float, 可选)
– 权重衰减(L2 惩罚)(默认:0)
(5)dampening (float, 可选)
– 动量的抑制因子(默认:0)
(6)nesterov (bool, 可选)
– 使用 Nesterov 动量(默认:False)
6.如何调整学习率
torch.optim.lr_scheduler
提供了几种基于epoch调整学习率的方法。
torch.optim.lr_scheduler.ReduceLROnPlateau
允许基于一些验证指标动态降低学习率。
学习率策略应在优化器更新后应用;例如,你应该这样写你的代码:
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()
大多数学习率策略程序可以被称为背靠背(也称为链式策略)。结果表明,每个学习率策略都是根据前一个学习率策略所获得的学习率依次应用的。
model = [Parameter(torch.randn(2, 2, requires_grad=True))]
optimizer = SGD(model, 0.1)
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 = ...
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
注意
PyTorch 1.1.0之后,如果您在优化器更新(调用optimizer.step())之前使用学习率策略(调用scheduler.step()),这将跳过学习率策略的第一个值。如果您在升级到PyTorch 1.1.0之后无法复制结果,请检查是否在错误的时间调用了scheduler.step()。
下面列举了常用的学习略策略
torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1, verbose=False)
设置每个参数组的学习速率为初始lr乘以给定函数。当last_epoch=-1时,将lr设置为初始lr。
参数
(1)optimizer (Optimizer)
——优化器。
(2)lr_lambda(函数或列表)
-一个函数,它计算在optimizer.param_groups中每个组使用的学习率策略。
(3)last_epoch (int)
-最后一个epoch的索引。默认值:-1。
(4)verbose (bool)
-如果为True,则为每个更新向stdout打印一条消息。默认值:False。
# 假设优化器有两组.
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()
属性
(1)get_last_lr()
:返回当前学习率策略上一次计算的学习率。
(2)load_state_dict(state_dict)
:加载学习率策略状态。当保存或加载学习率策略时,请确保也保存或加载优化器的状态。
(3)print_lr(is_verbose, group, lr, epoch=None)
:显示当前学习速率。
(4)state_dict()
:以字典的形式返回学习率策略的状态。
torch.optim.lr_scheduler.MultiplicativeLR(optimizer, lr_lambda, last_epoch=-1, verbose=False)
将每个参数组的学习率乘以指定函数中给定的因子。当last_epoch=-1时,将初始lr设置为lr。
参数
(1)optimizer (Optimizer)
——优化器。
(2)lr_lambda(函数或列表)
-一个函数,它计算在optimizer.param_groups中每个组使用的学习率策略。
(3)last_epoch (int)
-最后一个epoch的索引。默认值:-1。
(4)verbose (bool)
-如果为True,则为每个更新向stdout打印一条消息。默认值:False。
lmbda = lambda epoch: 0.95
scheduler = MultiplicativeLR(optimizer, lr_lambda=lmbda)
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
属性
(1)get_last_lr()
:返回当前学习率策略上一次计算的学习率。
(2)load_state_dict(state_dict)
:加载学习率策略状态。当保存或加载学习率策略时,请确保也保存或加载优化器的状态。
(3)print_lr(is_verbose, group, lr, epoch=None)
:显示当前学习速率。
(4)state_dict()
:以字典的形式返回学习率策略的状态。
torch.optim.lr_scheduler.StepLR(optimizer, step_size, gamma=0.1, last_epoch=-1, verbose=False)
每隔step_size个epoch用gamma衰减每个参数组的学习率。请注意,这种衰减可以与该学习率策略外部对学习率的其他变化同时发生。当last_epoch=-1时,将初始lr设置为lr。
参数
(1)optimizer (Optimizer)
:优化器。
(2)step_size (int)
:学习率衰减的周期。
(3)gamma (float)
:学习率衰减的乘法因子。默认值:0.1。
(4)last_epoch (int)
:最后一个epoch的索引。默认值:-1。
(5)verbose (bool)
:如果为True,则为每个更新向stdout打印一条消息。默认值:False。
# 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()
属性
(1)get_last_lr()
:返回当前学习率策略上一次计算的学习率。
(2)load_state_dict(state_dict)
:加载学习率策略状态。当保存或加载学习率策略时,请确保也保存或加载优化器的状态。
(3)print_lr(is_verbose, group, lr, epoch=None)
:显示当前学习速率。
(4)state_dict()
:以字典的形式返回学习率策略的状态。
torch.optim.lr_scheduler.MultiStepLR(optimizer, milestones, gamma=0.1, last_epoch=-1, verbose=False)
一旦epoch数达到一个里程碑,每个参数组的学习率就用gamma
衰减。请注意,这种衰减可以与该学习率策略外部对学习率的其他变化同时发生。当last_epoch=-1时,将初始lr设置为lr。
参数
(1)optimizer (Optimizer)
:优化器。
(2)milestones (list)
:epoch数目列表,必须递增。
(3)gamma (float)
:学习率衰减的乘法因子。默认值:0.1。
(4)last_epoch (int)
:最后一个epoch的索引。默认值:-1。
(5)verbose (bool)
:如果为True,则为每个更新向stdout打印一条消息。默认值:False。
# 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()
属性
(1)get_last_lr()
:返回当前学习率策略上一次计算的学习率。
(2)load_state_dict(state_dict)
:加载学习率策略状态。当保存或加载学习率策略时,请确保也保存或加载优化器的状态。
(3)print_lr(is_verbose, group, lr, epoch=None)
:显示当前学习速率。
(4)state_dict()
:以字典的形式返回学习率策略的状态。
torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma, last_epoch=-1, verbose=False)
每个参数组的学习率用gamma
衰减。当last_epoch=-1时,将初始lr设置为lr。
参数
(1)optimizer (Optimizer)
:优化器。
(2)gamma (float)
:学习率衰减的乘法因子。默认值:0.1。
(3)last_epoch (int)
:最后一个epoch的索引。默认值:-1。
(4)verbose (bool)
:如果为True,则为每个更新向stdout打印一条消息。默认值:False。
scheduler = ExponentialLR(optimizer,gamma=0.1)
for epoch in range(100):
train(...)
validate(...)
scheduler.step()
属性
(1)get_last_lr()
:返回当前学习率策略上一次计算的学习率。
(2)load_state_dict(state_dict)
:加载学习率策略状态。当保存或加载学习率策略时,请确保也保存或加载优化器的状态。
(3)print_lr(is_verbose, group, lr, epoch=None)
:显示当前学习速率。
(4)state_dict()
:以字典的形式返回学习率策略的状态。
torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0, last_epoch=-1, verbose=False)
使用余弦退火策略设置每个参数组的学习率。
参数
(1)optimizer (Optimizer)
:优化器。
(2)T_max (int)
:最大迭代次数,半周期epoch数目。
(3)eta_min (float)
:最小学习率。默认值:0。
(4)last_epoch (int)
:最后一个epoch的索引。默认值:-1。
(5)verbose (bool)
:如果为True,则为每个更新向stdout打印一条消息。默认值:False。
属性
(1)get_last_lr()
:返回当前学习率策略上一次计算的学习率。
(2)load_state_dict(state_dict)
:加载学习率策略状态。当保存或加载学习率策略时,请确保也保存或加载优化器的状态。
(3)print_lr(is_verbose, group, lr, epoch=None)
:显示当前学习速率。
(4)state_dict()
:以字典的形式返回学习率策略的状态。torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_0, T_mult=1, eta_min=0, last_epoch=-1, verbose=False)
使用余弦退火策略设置每个参数组的学习率。每个restart后,T_0 = T_0 * T_mult。
参数
(1)optimizer (Optimizer)
:优化器。
(2)T_0 (int)
:初始restart的epoch数目。
(2)T_mult (int, optional)
: T 0 T_0 T0的增加因子,默认是1
(3)eta_min (float)
:最小学习率。默认值:0。
(4)last_epoch (int)
:最后一个epoch的索引。默认值:-1。
(5)verbose (bool)
:如果为True,则为每个更新向stdout打印一条消息。默认值:False。
属性
(1)get_last_lr()
:返回当前学习率策略上一次计算的学习率。
(2)load_state_dict(state_dict)
:加载学习率策略状态。当保存或加载学习率策略时,请确保也保存或加载优化器的状态。
(3)print_lr(is_verbose, group, lr, epoch=None)
:显示当前学习速率。
(4)state_dict()
:以字典的形式返回学习率策略的状态。
(5)step(epoch=None)
:可以在每次批处理更新后调用
import torch
import torch.nn as nn
from torch.optim.lr_scheduler import CosineAnnealingLR, CosineAnnealingWarmRestarts
import itertools
import matplotlib.pyplot as plt
initial_lr = 0.1
class model(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(in_channels=3, out_channels=3, kernel_size=3)
def forward(self, x):
pass
net = model()
optimizer = torch.optim.Adam(net.parameters(), lr=initial_lr)
scheduler = CosineAnnealingWarmRestarts(optimizer, T_0=5, T_mult=1)
lr_list = [] # 把使用过的lr都保存下来,之后画出它的变化
for epoch in range(1, 101):
# train
optimizer.zero_grad()
optimizer.step()
print("第%d个epoch的学习率:%f" % (epoch, optimizer.param_groups[0]['lr']))
lr_list.append(optimizer.param_groups[0]['lr'])
scheduler.step()
# 画出lr的变化
plt.plot(list(range(1, 101)), lr_list)
plt.xlabel("epoch")
plt.ylabel("lr")
plt.title("learning rate's curve changes as epoch goes on!")
plt.show()
# iters = len(dataloader)
# for epoch in range(20):
# for i, sample in enumerate(dataloader):
# inputs, labels = sample['inputs'], sample['labels']
# optimizer.zero_grad()
# outputs = net(inputs)
# loss = criterion(outputs, labels)
# loss.backward()
# optimizer.step()
# print("第%d个epoch的学习率:%f" % (epoch, optimizer.param_groups[0]['lr']))
# scheduler.step(epoch + i / iters)
当T_mult=1
时,如下图
当T_mult=2
时,如下图
当scheduler = CosineAnnealingLR(optimizer, T_max=100)
时,如下图(发现只有半个周期)
torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.1, patience=10, threshold=0.0001, threshold_mode='rel', cooldown=0, min_lr=0, eps=1e-08, verbose=False)
当一个指标停止改进时,降低学习率。模型通常将学习率降低2-10倍。这个学习率策略读取一个指标量,如果在“耐心”的epoch中没有看到指标改善,学习率就会降低。
参数
(1)optimizer (optimizer)
:包装的优化器。
(2)mode (str)
:要么是"min"要么是"max"。在"min"模式下,当监测的指标停止改进时,lr将减少;在"max"模式下,当监测的指标停止改进时,lr将减少。默认值:“min”。
(3)factor(float)
:降低学习率的因子。new_lr = lr *factor。默认值:0.1。
(4)patience (int)
:没有改进的epoch数,之后学习率会降低。例如,如果patience= 2,那么我们将忽略前2个没有任何改善的epoch,只会降低第3个epoch之后的LR。默认值:10。
(5)threshold (float)
:度量新的最优值的阈值,只关注重要的更改。。默认值:1e-4。
(6)threshold_mode (str)
: rel, abs中的一个。在rel模式中,当在’ max '模式dynamic_threshold = best * (1 + threshold),当在“min”模式,dynamic_threshold =best * (1 - threshold)。在abs模式下,“max”模式下dynamic_threshold = best + threshold, “min”模式下dynamic_threshold = best - threshold。默认值:rel。
(7)cooldown(int)
:减少lr后恢复正常操作所需等待的时间。默认值:0。
(8)min_lr (float or list)
:标量或标量列表。所有参数组或每组的学习率的下界。默认值:0。
(9)eps(float)
:适用于lr的最小衰减。如果新lr和旧lr之间的差小于eps,则忽略更新。默认值:1e-8。
(10)verbose (bool)
:如果为True,则为每个更新向stdout打印一条消息。默认值:False。
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)
当scheduler_1 = ReduceLROnPlateau(optimizer_1, mode='min', factor=0.1, patience=2)
时:
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, verbose=False)
根据周期学习率策略(CLR)设置各参数组的学习速率。该策略以恒定的频率在两个边界之间循环学习。两个边界之间的距离可以在每个迭代或每个周期的基础上缩放。
循环学习率策略是在每批后改变学习率。step应该在批数据被用于训练后调用。
这个类有三个内置的策略,如论文中所述:
1)“triangular”
:没有振幅缩放的基本三角循环。
2)“triangular2”
:一个基本的三角形循环,每个循环将初始振幅减半。
3)"exp_range"
:一个通过 gamma cycle iteration \text{gamma}^{\text{cycle iteration}} gammacycle iteration缩放初始振幅的循环。
参数
(1)optimizer (Optimizer):优化器。
(2)base_lr(float或list):初始学习率,即每个参数组在循环中的下边界。
(3)max_lr(float或list):每个参数组在周期中的上限学习率边界。功能上,它定义了周期振幅(max_lr - base_lr)。任何周期的lr是base_lr和某个幅度的缩放之和;因此,根据缩放函数,max_lr实际上可能无法达到。
(4)step_size_up (int):在增加的半个周期内的训练迭代次数。默认值:2000
(5)step_size_down (int):在递减的半个周期内的训练迭代次数。如果step_size_down为None,则设置为step_size_up。默认值:None
(6)mode (str):{triangle, triangular2, exp_range}之一。值对应于上面详述的策略。如果scale_fn不是None,则忽略此参数。默认值:“triangle”
(7)gamma (float): ’ exp_range ‘缩放函数中的常量:gamma**(循环迭代)默认值:1.0
(8)scale_fn(function) :由单个参数lambda函数定义的自定义缩放策略,其中0 <= scale_fn(x) <= 1对于所有x >= 0。如果指定,则忽略’ mode ‘。默认值:None
(9)scale_mode (str):{’ cycle ‘, ’ iterations ‘}。定义scale_fn是根据周期数还是周期迭代(周期开始后的训练迭代)进行计算。默认值:“cycle ”
(10)cycle_momentum (bool):如果为True,momentum在’ base_momentum ‘和’ max_momentum ‘之间循环与学习率成反比。默认值:True
(11)base_momentum(float或list):每个参数组循环中的较低momentum边界。注意,momentum的循环与学习率是相反的;在一个周期的峰值,momentum是’ base_momentum’,学习速率是’ max_lr ‘。默认值:0.8
(12)max_momentum(float或list):每个参数组在循环中的上动量边界。功能上,它定义了周期振幅(max_momentum - base_momentum)。任意周期的momentum是max_momentum和某个幅度的缩放之差;因此,base_momentum实际上可能不会达到。注意,momentum的循环与学习速率是相反的;在一个循环的开始,momentum是’ max_momentum ‘和学习率是’ base_lr '默认值:0.9
(13)last_epoch (int) :最后一批的索引。该参数用于恢复训练任务。因为step()应该在每个批之后而不是在每个epoch之后调用,所以这个数字表示计算的批总数,而不是计算的epoch总数。当last_epoch=-1时,从最开始开始调度。默认值:-1
verbose (bool):如果为True,则为每个更新向stdout打印一条消息。默认值:False。
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()
torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr, total_steps=None, epochs=None, steps_per_epoch=None, pct_start=0.3, anneal_strategy='cos', cycle_momentum=True, base_momentum=0.85, max_momentum=0.95, div_factor=25.0, final_div_factor=10000.0, three_phase=False, last_epoch=-1, verbose=False)
按照“1cycle”学习率策略设置各参数组的学习率。该策略将学习率从初始学习率退火到某个最大学习率,然后从该最大学习率退火到某个远低于初始学习率的最小学习率。
根据1cycle学习率策略,每批数据训练后,学习率都会发生变化。step应该在批数据被用于训练后调用。
这个学习率策略是不可链式操作的。
还请注意,循环中的总步数可以通过以下两种方式之一确定(按优先级顺序列出):
(1)显式地提供了total_steps的值。
(2)提供了epoch和steps_per_epoch。在本例中,总步数由total_steps = epochs * steps_per_epoch推断
您要么为total_steps提供一个值,要么同时为epoch和steps_per_epoch提供一个值。
参数
(1)optimizer (Optimizer):优化器。
(2)max_lr(float或list):每个参数组在周期中的上限学习率边界。
(3)total_steps (int):循环中的总步骤数。注意,如果这里没有提供值,那么必须通过提供epoch和steps_per_epoch的值来推断它。默认值:None
(4)epoch (int):要训练的epoch的数目。它与steps_per_epoch一起使用,以便在total_steps没有提供值的情况下推断循环中的总步骤数。默认值:None
(5)steps_per_epoch (int):每个epoch要训练的步数。如果没有提供total_steps的值,它将与epoch一起使用,以便推断周期中的总步骤数。默认值:None
(6)pct_start (float):增加学习率所花费的周期(以步数为单位)的百分比。默认值:0.3
(7)anneal_strategy (str): {’ cos ‘, ’ linear ‘}指定退火策略:“cos”表示余弦退火,“linear”表示线性退火。默认值:“cos”
(8)cycle_momentum (bool):如果为True,momentum在’ base_momentum ‘和’ max_momentum ‘之间的循环与学习率成反比。默认值:True
(9)base_momentum(float或list):每个参数组循环中的较低momentum边界。注意,momentum的循环与学习率是相反的;在一个周期的峰值,momentum是’ base_momentum’,学习速率是’ max_lr ‘。默认值:0.85
(10)max_momentum(float或list):每个参数组在循环中的上momentum边界。功能上,它定义了周期振幅(max_momentum - base_momentum)。注意,momentum的循环与学习率是相反的;在循环的开始,momentum是’ max_momentum ‘,学习速率是’ base_lr '默认值:0.95
(11)div_factor (float):通过initial_lr = max_lr/div_factor确定初始学习率。默认值:25
(12)final_div_factor (float):通过min_lr = initial_lr/final_div_factor确定最小学习率。默认值:1e4
(13)three_phase (bool):如果为True,根据“final_div_factor”来消除学习率。
(14)last_epoch (int):最后一批的索引。该参数用于恢复训练任务。因为step()应该在每个批之后而不是在每个epoch之后调用,所以这个数字表示计算的批总数,而不是计算的epoch总数。当last_epoch=-1时,从最开始开始使用学习率策略。默认值:-1
(15)verbose (bool):如果为True,则为每个更新向stdout打印一条消息。默认值:False。
data_loader = torch.utils.data.DataLoader(...)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, max_lr=0.01, steps_per_epoch=len(data_loader), epochs=10)
for epoch in range(10):
for batch in data_loader:
train_batch(...)
scheduler.step()
import torch
import torch.nn as nn
from torch.optim.lr_scheduler import ReduceLROnPlateau
import itertools
initial_lr = 0.1
class model(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(in_channels=3, out_channels=3, kernel_size=3)
def forward(self, x):
pass
net_1 = model()
# optimizer_1 = torch.optim.Adam(net_1.parameters(), lr = initial_lr)
# scheduler_1 = ReduceLROnPlateau(optimizer_1, mode='min', factor=0.1, patience=2)
optimizer_1 = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
#scheduler_1 = torch.optim.lr_scheduler.CyclicLR(optimizer_1, base_lr=0.01, max_lr=0.1)
scheduler_1 = torch.optim.lr_scheduler.OneCycleLR(optimizer_1, max_lr=0.01, total_steps=10000)
print("初始化的学习率:", optimizer_1.defaults['lr'])
lr_list = []
for epoch in range(1, 15):
# train
test = 2
optimizer_1.zero_grad()
optimizer_1.step()
print("第%d个epoch的学习率:%f" % (epoch, optimizer_1.param_groups[0]['lr']))
lr_list.append(optimizer_1.param_groups[0]['lr'])
scheduler_1.step(test)
# 画出lr的变化
plt.plot(list(range(1, 101)), lr_list)
plt.xlabel("epoch")
plt.ylabel("lr")
plt.title("learning rate's curve changes as epoch goes on!")
plt.show()
参考目录
https://blog.csdn.net/weixin_40920183/article/details/119814472
https://zhuanlan.zhihu.com/p/206467852
https://blog.csdn.net/qq_37612828/article/details/108213578