文章目录
- 前言
- 一、LambdaLR
- 二、StepLR
- 三、MultiStepLR
- 四、ConstantLR
- 五、LinearLR
- 六、PolynomialLR
- 七、ChainedScheduler
- 八、ExponentialLR
- 九、CosineAnnealingLR
- 十、OneCycleLR
- 十一、ReduceLROnPlateau
- 十二、自定义学习率类函数
- 总结
前言
在深度学习中,学习率对模型的训练过程起着很重要的作用,影响着损失函数的变化速度。学习率越低,可以确保不会错过任何局部最小值,但是也意味着将花费更长的训练时间来进行收敛,特别是陷入局部最优的情况下。学习率越高,就容易错过全局最小值导致结果不收敛。
一般来说,batch-size的大小一般与学习率的大小成正比。batch-size越大一般意味着算法收敛方向的置信度越大,也可以选择较大的学习率来加快收敛速度。而小的batch-size规律性较差,需要小的学习率保证不出错。在显存允许的情况下,选择大的batch-size。
预设规则的学习率变化法:StepLR、Multi-StepLR、ConstantLR、LinearLR、PolynomialLR、ChainedScheduler
自适应的学习率变化法:ExponentialLR、CosineAnnealingLR、LambdaLR、OneCycleLR、ReduceLROnPlateau
一、LambdaLR
LambdaLR的优点是可以根据自定义的函数来调整学习率,灵活性比较高。可以根据具体任务和模型的需求来选择合适的函数,以提高模型的性能。
Tips:比较适合do some research
torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda, last_epoch=-1, verbose='deprecated')
基于一个lambda function来set the changes of lr。
example:
lambda1 = lambda epoch : epoch/10 #For each epoch, multiply epoch/10 * initial_lr
lr_scheduler = lr_scheduler.LambdaLR(optimizer,lambda1)
lr:
0.01
0.02
0.03
...
二、StepLR
StepLR可以在训练过程中根据设定的步长来调整学习率,模型收敛的更稳定。但固定represent 不够灵活,无法适应不同的训练情况。此外,如果步长设置得不合理,可能会导致模型在训练过程中出现震荡或过拟合的情况。
Tips:目前很少用这种方式了,简单测试还可以
torch.optim.StepLR(optimizer,step_size=30,gamma=0.1)
>>> # 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
三、MultiStepLR
MultiStepLR学习率调整策略比StepLR略灵活一些,可以根据设定的milestones(which epoch开始decay)来调整学习率,从而更好地适应不同的训练情况。同样,如果设置不合理,可能会导致模型在训练过程中出现震荡或过拟合的情况。
Tips:对于一些不复杂的模型或者较为简单的任务,MSLR还是挺常用的,个人觉得这种方式对于要求不是特别精细的任务,收敛还是挺快的
>>> scheduler = MultiStepLR(optimizer, milestones=[30,80,100], gamma=0.1)
>>> # 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
四、ConstantLR
看名字就知道是constant lr, 通过设置让某一段train process以一个固定值进行训练
Tips:个人觉得比较适合用来以固定lr进行微调
>>> # Assuming optimizer uses lr = 0.05 for all groups
>>> # lr = 0.025 if epoch == 0
>>> # lr = 0.025 if epoch == 1
>>> # lr = 0.025 if epoch == 2
>>> # lr = 0.025 if epoch == 3
>>> # lr = 0.05 if epoch >= 4
>>> scheduler = ConstantLR(optimizer, factor=0.5, total_iters=4)
五、LinearLR
LinearLR就是LR进行线性变化
Tips:简单模型测试可以用,蛮简单的策略
'''
设置end_factor < start_factor,学习率会以线性变化不断减小,反之则线性增加
start_lr = lr * start_factor,
end_lr = lr * end_factor
'''
>>> # Assuming optimizer uses lr = 0.05 for all groups
>>> # lr = 0.025 if epoch == 0
>>> # lr = 0.03125 if epoch == 1
>>> # lr = 0.0375 if epoch == 2
>>> # lr = 0.04375 if epoch == 3
>>> # lr = 0.05 if epoch >= 4
>>> scheduler = LinearLR(optimizer, start_factor=0.5, end_factor=1.0 ,total_iters=4)
六、PolynomialLR
Poly lr简单来说就是lr逐渐衰减到0的一个策略,每个epoch lr都会衰退,直到降至0。
Tips:该方式感觉很少见到,也不是很常用,具体收敛效果不是很了解
>>> # Assuming optimizer uses lr = 0.001 for all groups
>>> # lr = 0.001 if epoch == 0
>>> # lr = 0.00075 if epoch == 1
>>> # lr = 0.00050 if epoch == 2
>>> # lr = 0.00025 if epoch == 3
>>> # lr = 0.0 if epoch >= 4
>>> scheduler = PolynomialLR(optimizer, total_iters=4, power=1.0)
七、ChainedScheduler
该方式和自定义lr差不多,只不过先把每个epoch的lr变成一个list,按照该list 进行train
Tips:emm,可能有时候会用到
torch.optim.lr_scheduler.ChainedScheduler(schedulers)
八、ExponentialLR
指数衰减策略以使学习率在训练过程中逐渐减小,从而使模型更加稳定。此外,指数衰减策略的衰减因子需要根据具体情况进行调整。
Tips:指数lr在以前比较常用,感觉现在很少见到了,不过依然是一个比较好的方案
"""
new_lr = initial_lr * (gamam ** epoch)
"""
torch.optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.95, last_epoch=-1, verbose='deprecated')
九、CosineAnnealingLR
余弦退火策略的优点是可以使学习率在训练过程中逐渐减小,从而使模型更加稳定。与指数衰减策略相比,余弦退火策略的衰减速度更加缓慢,可以避免梯度爆炸的情况。此外,余弦退火策略可以根据当前epoch的索引和最大迭代次数计算出一个余弦因子,从而更好地适应不同的训练情况。
Tips:余弦退火应该是现在最常用的学习率策略之一了,其原理不复杂,参数设置简单且有效
"""
new_lr = lr = 0.5 * base_lr * (1 + cos(epoch / T_max * pi))
Tmax:极速下降到0的epoch
其中,lr表示当前的学习率,base_lr表示初始学习率,epoch表示当前的epoch数,T_max表示总的epoch数,pi表示圆周率。这个公式会根据当前的epoch数和总的epoch数来计算当前的学习率,学习率会在前半段逐渐增加,在后半段逐渐减小,最终回到初始学习率。这种学习率调整策略可以帮助模型在训练初期快速收敛,在训练后期避免过拟合。
"""
scheduler = lr_scheduler.CosineAnnealingLR(optimizer,T_max=150)
十、OneCycleLR
OneCycleLR可以在训练初期快速提高学习率,加速模型的收敛速度。训练后期逐渐降低学习率,避免过拟合,提高模型的泛化能力。
同时OneCycleLR学习率调整策略可以通过动态调整学习率来避免训练过程中出现梯度爆炸或梯度消失等问题,提高训练的稳定性。
OneCycleLR学习率调整策略可以通过调整超参数来适应不同的数据集和模型,提高模型的性能。但需要进行仔细的调参。
Tips:OneCycleLR也是目前很常用的策略之一,对于从0训练的模型效果很好,但是不建议使用该训练策略在已训练好的模型上进一步训练
"""
optimizer, 优化器
max_lr, 学习率最大值
total_steps=None, 总step次数
pct_start=0.3, 学习率上升的部分step数量的占比
div_factor=25.0, 初始学习率 = max_lr / div_factor
final_div_factor=10000.0, 最终学习率 = 初始学习率 / final_div_factor
"""
scheduler = torch.optim.OneCycleLR(optimizer, max_lr=0.8, total_steps=150, pct_start=0.3)
十一、ReduceLROnPlateau
在发现loss不再降低或者acc不再提高之后,降低学习率
Tips:ReduceLR个人觉得不是特别常用,主要其超参的设置较为复杂,如果设置的好,效果还是很棒的
'''
mode:'min’模式检测metric是否不再减小,'max’模式检测metric是否不再增大;
factor: 触发条件后lr*=factor;
patience:不再减小(或增大)的累计次数;
verbose:触发条件后print;
threshold:只关注超过阈值的显著变化;
threshold_mode:有rel和abs两种阈值计算模式,rel规则:max模式下如果超过best(1+threshold)为显著,min模式下如果低于best(1-threshold)为显著;abs规则:max模式下如果超过best+threshold为显著,min模式下如果低于best-threshold为显著;
cooldown:触发一次条件后,等待一定epoch再进行检测,避免lr下降过速;
min_lr:最小的允许lr;
eps:如果新旧lr之间的差异小与1e-8,则忽略此次更新。
'''
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)
十二、自定义学习率类函数
学习率调整策略需要继承_LRScheduler类,如下
class WarmupLR(_LRScheduler):
def __init__(self, optimizer, warmup_epochs, warmup_lr, last_epoch=-1):
self.warmup_epochs = warmup_epochs
self.warmup_lr = warmup_lr
super(WarmupLR, self).__init__(optimizer, last_epoch)
def get_lr(self):
if self.last_epoch < self.warmup_epochs:
return [self.warmup_lr + (base_lr - self.warmup_lr) * self.last_epoch / self.warmup_epochs
for base_lr in self.base_lrs]
else:
return [base_lr * self.gamma ** (self.last_epoch - self.warmup_epochs)
for base_lr in self.base_lrs]
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。