- 学习率是神经网络优化是的重要超参数,在梯度下降法中,学习率
α
\alpha
α非常关键,学习率过大会不收敛,学习率过小则收敛速度太慢,常用的学习率调整方法包括:学习率衰减、学习率预热、周期性学习率调整等,除此之外还有一些自适应学习率。
- 在pytorch中提供了相关算法的实现函数,挑几个比较有代表性的介绍学习一下:
学习率衰减
- 等间隔调整学习率:
torch.optim.lr_scheduler.StepLR(
optimizer, step_size, gamma=0.1, last_epoch=- 1, verbose=False)
- 参数意义
- optimizer : 优化器
- step_size: 迭代更新频率,echo
- gamma:学习率衰减率
- 使用方式:
class NNtese(nn.Module):
def __init__(self, inpDim, hidDim, outDim):
super(NNtest, self).__init__():
self.line1 = nn.Linear(inpDim, hidDim)
self.line2 = nn.Linear(hidDim, outDim)
def forward(self, x):
x = self.line1(x)
x = F.relu(x)
x = self.line2(x)
return x
def train(trainLaoder, vaildLoader, model, epoch):
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)
lossfunc = nn.MSELoss()
scheduler = torch.optim.lr_scheduler.StepLR(
optimizer, step_size=10, gamma=0.1)
for epoch in range(epoch):
for i, (x, y) in enumerate(trainLoader):
optimizer.zero_grad()
net.train()
pred = model(inputs)
traLoss = lossfunction(pred, y)
for i, (vx, vy) in enumerate(vaildLoader):
net.eval()
pred = model(inputs)
valLoss = lossfunction(pred, vy)
scheduler.step()
- 指数衰减调整学习率
* torch.optim.lr_scheduler.ExponentialLR(
optimizer, gamma, last_epoch=- 1, verbose=False)
- 指数衰减学习率与等间隔衰减学习率的使用方法和参数意义基本一致
学习率预热
- WarmUpLR预热学习率,以一定的比例线性降低学习率直到达到了指定的预热迭代次数
-
torch.optim.lr_scheduler.WarmUpLR(
optimizer, warmup_factor=0.3333333333333333, warmup_iters=5, warmup_method='linear', last_epoch=- 1, verbose=False)
- 参数说明:
- optimizer: 优化器
- warmup_factor:在迭代的第一轮学习率的衰减率,如果选择method为常数,则衰减率不变,如果选择的为“linear”,学习率默认按 0.33333衰减
- warmup_iters:预热的轮数
- warmup_method:迭代方式 可选 constant and linear.
周期性学习率
- 余弦衰减学习率
- 让学习率随着echo呈现出余弦变化的趋势
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AP4ffsDA-1630129305036)(en-resource://database/3242:1)]
torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max, eta_min=0, last_epoch=- 1, verbose=False)
- T_max: 为变化周期的一半
- eta_min:为学习率最小值
- 实现样例:
import torchfrom torchvision.models import AlexNetfrom torch.optim.lr_scheduler import CosineAnnealingLRimport matplotlib.pyplot as plt
model = AlexNet(num_classes=2)optimizer = torch.optim.Adam(model.parameters(),lr=0.1)scheduler = CosineAnnealingLR(optimizer,T_max=20)plt.figure()x = list(range(100))y = []for epoch in range(1,101):
optimizer.zero_grad()
optimizer.step()
print("第%d个epoch的学习率:%f" % (epoch,optimizer.param_groups[0]['lr']))
scheduler.step()
y.append(scheduler.get_lr()[0])
# 画出lr的变化 plt.plot(x, y)plt.xlabel("epoch")plt.ylabel("lr")plt.title("learning rate's curve changes as epoch goes on!")plt.show()
自适应学习率调整
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)
- 当某项指标(loss)不再发生变化时,调整学习率
- 参数说明:
- mode(str):有 min和max两种模式,min表示当指标不再降低(如监测loss),max表示当指标不再升高(如监测accuracy)。
- factor(float): 学习率调整倍数,即学习率更新为 lr = lr * factor
- patience(int):即忍受该指标多少个step不变化,当忍无可忍时,调整学习率
- threshold:用来控制当前指标与best指标的差异
- threshold_mode:选择判断指标是否达最优的模式,有两种模式,rel和abs。
- 当threshold_mode = rel,并且mode = max时,dynamic_threshold = best * ( 1 + threshold );
- 当threshold_mode = rel,并且mode = min时,dynamic_threshold = best * ( 1 - threshold );
- 当threshold_mode = abs,并且mode = max时,dynamic_threshold = best + threshold ;
- 当threshold_mode = abs,并且mode = max时,dynamic_threshold = best - threshold
- cooldown:学习率修改后等待多长时间再去“忍”,冷静期
- min_lr (float or list): 最小学习率,可以是一个值也可以是list,对应不同参数
- eps (float):学习率最小更改,若前后对比小于eps则不更改
- 实践:
- https://www.emperinter.info/2020/08/05/change-leaning-rate-by-reducelronplateau-in-pytorch/