torch.nn.init.calculate_gain(nonlinearity, param=None)
:返回给定非线性函数的推荐增益值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)中生成值,填充输入的张量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)中生成值,填充输入的张量或变量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 的值填充输入的张量或变量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 维输入张量或变量。在线性层尽可能多的保存输入特性。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}维输入张量或变量。在卷积层尽可能多的保存输入通道特性。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。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)
: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.nonlinearity='leaky_relu'
时候起作用fan_in
或者fan_out
。fan_in
保留forward传递中权重的方差大小,fan_out
保留backward传递中权重的方差大小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')
:nonlinearity='leaky_relu'
时候起作用fan_in
或者fan_out
。fan_in
保留forward传递中权重的方差大小,fan_out
保留backward传递中权重的方差大小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 的正态分布生成。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,你需要构建一个 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()之后的模型参数与调用之前的参数是不同的对象。
通常,在构造和使用优化器时,应该确保优化参数位置的一致。
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
将会被用于所 有的参数。
所有的 optimizer 都实现了 step()方法,这个方法会更新所有的参数。它能按两种方式来使用:
optimizer.step()
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)
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。
torch.optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-06,weight_decay=0)
params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dictrho (float, 可选)
– 用于计算平方梯度的运行平均值的系数(默认:0.9)eps (float, 可选)
– 为了增加数值计算的稳定性而加到分母里的项(默认:1e-6)lr (float, 可选)
– 在 delta 被应用到参数更新之前对它缩放的系数(默认:1.0)weight_decay (float, 可选)
– 权重衰减(L2 惩罚)(默认: 0)torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0)
params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dictlr (float, 可选)
– 学习率(默认: 1e-2)lr_decay (float, 可选)
– 学习率衰减(默认: 0)weight_decay (float, 可选)
– 权重衰减(L2 惩罚)(默认: 0)torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08,weight_decay=0)
params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dictlr (float, 可选)
– 学习率(默认:1e-3)betas (Tuple[float, float], 可选)
– 用于计算梯度以及梯度平方的运行平均值的系数(默认:0.9,0.999)eps (float, 可选)
– 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)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)
params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dict
lr (float, 可选)
– 学习率(默认:1e-3
)betas (Tuple[float, float], 可选)
– 用于计算梯度以及梯度平方的运行平均值的系数(默认:0.9,0.999
)eps (float, 可选)
– 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8
)weight_decay (float, 可选)
– 权重衰减(默认: 1e-2
)amsgrad (boolean, 可选)
– 是否使用该算法的AMSGrad
变体torch.optim.SparseAdam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08)
params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dict
lr (float, 可选)
– 学习率(默认:1e-3
)betas (Tuple[float, float], 可选)
– 用于计算梯度以及梯度平方的运行平均值的系数(默认:0.9,0.999
)eps (float, 可选)
– 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8
)torch.optim.Adamax(params, lr=0.002, betas=(0.9, 0.999), eps=1e-08,weight_decay=0)
params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dictlr (float, 可选)
– 学习率(默认:2e-3)betas (Tuple[float, float], 可选)
– 用于计算梯度以及梯度平方的运行平均值的系数eps (float, 可选)
– 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)weight_decay (float, 可选)
– 权重衰减(L2 惩罚)(默认: 0)torch.optim.ASGD(params, lr=0.01, lambd=0.0001, alpha=0.75, t0=1000000.0,weight_decay=0)
params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dictlr (float, 可选)
– 学习率(默认:1e-2)lambd (float, 可选)
– 衰减项(默认:1e-4)alpha (float, 可选)
– eta 更新的指数(默认:0.75)t0 (float, 可选)
– 指明在哪一次开始平均化(默认:1e6)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)
lr (float)
– 学习率(默认:1)max_iter (int)
– 每一步优化的最大迭代次数(默认:20))max_eval (int)
– 每一步优化的最大函数评价次数(默认:max * 1.25)tolerance_grad (float)
– 一阶最优的终止容忍度(默认:1e-5)tolerance_change (float)
– 在函数值/参数变化量上的终止容忍度(默认:1e-9)history_size (int)
– 更新历史的大小(默认:100)torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0,momentum=0, centered=False)
params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dictlr (float, 可选)
– 学习率(默认:1e-2)momentum (float, 可选)
– 动量因子(默认:0)alpha (float, 可选)
– 平滑常数(默认:0.99)eps (float, 可选)
– 为了增加数值计算的稳定性而加到分母里的项(默认:1e-8)centered (bool, 可选)
– 如果为 True,计算中心化的 RMSProp,并且用它的方差预测值对梯度进行归一化weight_decay (float, 可选)
– 权重衰减(L2 惩罚)(默认: 0)torch.optim.Rprop(params, lr=0.01, etas=(0.5, 1.2), step_sizes=(1e-06,50))
params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dictlr (float, 可选)
– 学习率(默认:1e-2)etas (Tuple[float, float], 可选)
– 一对(etaminus,etaplis), 它们分别是乘法的增加和减小的因子(默认:0.5,1.2)step_sizes (Tuple[float, float], 可选)
– 允许的一对最小和最大的步长(默认:1e-6,50)torch.optim.SGD(params, lr=, monentum=0, dampening=0, weight_decay=0,nesterov=False)
params (iterable)
– 待优化参数的 iterable 或者是定义了参数组的 dictlr (float)
– 学习率momentum (float, 可选)
– 动量因子(默认:0)weight_decay (float, 可选)
– 权重衰减(L2 惩罚)(默认:0)dampening (float, 可选)
– 动量的抑制因子(默认:0)nesterov (bool, 可选)
– 使用 Nesterov 动量(默认:False)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)
optimizer (Optimizer)
——优化器。lr_lambda(函数或列表)
-一个函数,它计算在optimizer.param_groups中每个组使用的学习率策略。last_epoch (int)
-最后一个epoch的索引。默认值:-1。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)
optimizer (Optimizer)
——优化器。lr_lambda(函数或列表)
-一个函数,它计算在optimizer.param_groups中每个组使用的学习率策略。last_epoch (int)
-最后一个epoch的索引。默认值:-1。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)
optimizer (Optimizer)
:优化器。step_size (int)
:学习率衰减的周期。gamma (float)
:学习率衰减的乘法因子。默认值:0.1。last_epoch (int)
:最后一个epoch的索引。默认值:-1。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)
gamma
衰减。请注意,这种衰减可以与该学习率策略外部对学习率的其他变化同时发生。当last_epoch=-1时,将初始lr设置为lr。optimizer (Optimizer)
:优化器。milestones (list)
:epoch数目列表,必须递增。gamma (float)
:学习率衰减的乘法因子。默认值:0.1。last_epoch (int)
:最后一个epoch的索引。默认值:-1。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。optimizer (Optimizer)
:优化器。gamma (float)
:学习率衰减的乘法因子。默认值:0.1。last_epoch (int)
:最后一个epoch的索引。默认值:-1。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)
optimizer (Optimizer)
:优化器。T_max (int)
:最大迭代次数,半周期epoch数目。eta_min (float)
:最小学习率。默认值:0。last_epoch (int)
:最后一个epoch的索引。默认值:-1。verbose (bool)
:如果为True,则为每个更新向stdout打印一条消息。默认值:False。get_last_lr()
:返回当前学习率策略上一次计算的学习率。load_state_dict(state_dict)
:加载学习率策略状态。当保存或加载学习率策略时,请确保也保存或加载优化器的状态。print_lr(is_verbose, group, lr, epoch=None)
:显示当前学习速率。state_dict()
:以字典的形式返回学习率策略的状态。torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizer, T_0, T_mult=1, eta_min=0, last_epoch=-1, verbose=False)
optimizer (Optimizer)
:优化器。T_0 (int)
:初始restart的epoch数目。T_mult (int, optional)
: T 0 T_0 T0的增加因子,默认是1eta_min (float)
:最小学习率。默认值:0。last_epoch (int)
:最后一个epoch的索引。默认值:-1。verbose (bool)
:如果为True,则为每个更新向stdout打印一条消息。默认值:False。get_last_lr()
:返回当前学习率策略上一次计算的学习率。load_state_dict(state_dict)
:加载学习率策略状态。当保存或加载学习率策略时,请确保也保存或加载优化器的状态。print_lr(is_verbose, group, lr, epoch=None)
:显示当前学习速率。state_dict()
:以字典的形式返回学习率策略的状态。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)
optimizer (optimizer)
:包装的优化器。mode (str)
:要么是"min"要么是"max"。在"min"模式下,当监测的指标停止改进时,lr将减少;在"max"模式下,当监测的指标停止改进时,lr将减少。默认值:“min”。factor(float)
:降低学习率的因子。new_lr = lr *factor。默认值:0.1。patience (int)
:没有改进的epoch数,之后学习率会降低。例如,如果patience= 2,那么我们将忽略前2个没有任何改善的epoch,只会降低第3个epoch之后的LR。默认值:10。threshold (float)
:度量新的最优值的阈值,只关注重要的更改。。默认值:1e-4。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。cooldown(int)
:减少lr后恢复正常操作所需等待的时间。默认值:0。min_lr (float or list)
:标量或标量列表。所有参数组或每组的学习率的下界。默认值:0。eps(float)
:适用于lr的最小衰减。如果新lr和旧lr之间的差小于eps,则忽略更新。默认值:1e-8。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)
“triangular”
:没有振幅缩放的基本三角循环。“triangular2”
:一个基本的三角形循环,每个循环将初始振幅减半。"exp_range"
:一个通过 gamma cycle iteration \text{gamma}^{\text{cycle iteration}} gammacycle iteration缩放初始振幅的循环。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)
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