热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

pytorch学习笔记十三:学习率的调整策略

在上一节的优化器中有很多超参数,例如学习率和动量等,其中一个重要的参数是学习率,它控制着参数更新步伐的大小,在模型的训练过程

在上一节的优化器中有很多超参数,例如学习率和动量等,其中一个重要的参数是学习率,它控制着参数更新步伐的大小,在模型的训练过程中,学习率不是一成不变的,可以调整和变化。

一、为什么要调整学习率

在模型训练时,一般开始的时候会设置大一点的学习率,这样可以较快的达到最优点附近,然后降低学习率,缓慢的去收敛到最优值。举个栗子:
在这里插入图片描述
参数更新公式:
wi+1=wi−LR∗grad(wi)w_{i+1}=w_{i}-LR*grad(w_{i})wi+1=wiLRgrad(wi)
如果设置过大的学习率,有可能会跳过最优值,或者在最优值附近震荡。所以设置学习率小一点,来达到最优值,这时就需要一个学习率调整策略来控制学习率。下面就来学习一下pytorch中学习率的调整策略。

二、pytorch中的学习率调整策略


1、StepLR

在这里插入图片描述
功能:等间隔调整学习率
step_size表示调整间隔数,gamma表示调整系数,调整方式就是lr*gamma,gamma一般是0.1-0.5,last_epoch保证能够从断点处继续训练。pytorch中的实现为:

if (self.last_epoch == 0) or (self.last_epoch % self.step_size != 0):return [group['lr'] for group in self.optimizer.param_groups]
return [group['lr'] * self.gammafor group in self.optimizer.param_groups]

可以发现通过当前epoch是否能够被整除来调整学习率。例如设置step_size=50,那么就是每50个epoch调整一次学习率,调整方式是lr*gamma,下面从代码来看一下这种学习率的调整策略:

# 设置每50个epoch调整学习率,lr=0.1*lr
scheduler_lr = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.1) # 设置学习率下降策略lr_list, epoch_list = list(), list()
for epoch in range(max_epoch):# 获取当前lr,新版本用 get_last_lr()函数,旧版本用get_lr()函数,具体看UserWarninglr_list.append(scheduler_lr.get_last_lr())epoch_list.append(epoch)for i in range(iteration):loss = torch.pow((weights - target), 2)loss.backward()optimizer.step()optimizer.zero_grad()scheduler_lr.step()plt.plot(epoch_list, lr_list, label="Step LR Scheduler")
plt.xlabel("Epoch")
plt.ylabel("Learning rate")
plt.legend()
plt.show()

运行结果:
在这里插入图片描述

2、MultiStepLR

在这里插入图片描述
功能:按给定间隔调整学习率
参数:
milestones:设定调整时刻数;
gamma:调整系数
调整方式:lr = lr * gamma
这个和上面的不同点在于,学习率调整的间隔可以自己设置,比如构建一个list,milestones=[50, 125, 150],意思是在第50个epoch、第125个epoch、第150个epoch调整一次学习率,学习率变为原来的 lr * gamma,在pytorch内部实现代码为:

if self.last_epoch not in self.milestones:return [group['lr'] for group in self.optimizer.param_groups]
return [group['lr'] * self.gamma ** self.milestones[self.last_epoch]for group in self.optimizer.param_groups]

下面用代码来演示一下:

milestones = [50, 125, 150]
scheduler_lr = optim.lr_scheduler.MultiStepLR(optimizer, milestones=milestones, gamma=0.1)lr_list, epoch_list = list(), list()
for epoch in range(max_epoch):lr_list.append(scheduler_lr.get_lr())epoch_list.append(epoch)for i in range(iteration):loss = torch.pow((weights - target), 2)loss.backward()optimizer.step()optimizer.zero_grad()scheduler_lr.step()plt.plot(epoch_list, lr_list, label="Multi Step LR Scheduler\nmilestones:{}".format(milestones))
plt.xlabel("Epoch")
plt.ylabel("Learning rate")
plt.legend()
plt.show()

输出结果:
在这里插入图片描述

3、ExponentialLR

在这里插入图片描述
功能:调整学习率按指数衰减
参数:
gamma:指数的底
调整方式:lr = lr * gamma **epoch

gamma = 0.95
scheduler_lr = optim.lr_scheduler.ExponentialLR(optimizer, gamma=gamma)lr_list, epoch_list = list(), list()
for epoch in range(max_epoch):lr_list.append(scheduler_lr.get_lr())epoch_list.append(epoch)for i in range(iteration):loss = torch.pow((weights - target), 2)loss.backward()optimizer.step()optimizer.zero_grad()scheduler_lr.step()plt.plot(epoch_list, lr_list, label="Exponential LR Scheduler\ngamma:{}".format(gamma))
plt.xlabel("Epoch")
plt.ylabel("Learning rate")
plt.legend()
plt.show()

输出结果:
在这里插入图片描述

4、CosineAnnealingLR

在这里插入图片描述
功能:余弦周期调整学习率
主要参数:
T_max:下降周期
eta_min:学习率下限
调整方式:在这里插入图片描述

t_max = 50
scheduler_lr = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=t_max, eta_min=0.)lr_list, epoch_list = list(), list()
for epoch in range(max_epoch):lr_list.append(scheduler_lr.get_lr())epoch_list.append(epoch)for i in range(iteration):loss = torch.pow((weights - target), 2)loss.backward()optimizer.step()optimizer.zero_grad()scheduler_lr.step()plt.plot(epoch_list, lr_list, label="CosineAnnealingLR Scheduler\nT_max:{}".format(t_max))
plt.xlabel("Epoch")
plt.ylabel("Learning rate")
plt.legend()
plt.show()

在这里插入图片描述

5、ReduceLRonPlateau

在这里插入图片描述
功能:监控指标,当指标不再变化则调整
主要参数:
mode : min/max 两种模式,观察max/min值这一指标
factor:调整系数
patience:“耐心” 接受几次不变化
cooldown:“冷却时间”,停止监控一段时间
verbose:是否打印日志
min_lr:学习率下限
eps:学习率衰减最小值

loss_value = 0.5
accuray = 0.9factor = 0.1
mode = "min"
patience = 10 # 当连续10次损失函数不下降时,执行 lr=lr*0。1
cooldown = 10 # 冷却10个epoch
min_lr = 1e-4
verbose = True # 打印结果日志scheduler_lr = optim.lr_scheduler.ReduceLROnPlateau(optimizer, factor=factor, mode=mode, patience=patience, cooldown=cooldown, min_lr=min_lr, verbose=verbose)for epoch in range(max_epoch):for i in range(iteration):# train(...)optimizer.step()optimizer.zero_grad()#if epoch == 5:# loss_value = 0.4scheduler_lr.step(loss_value) # 这里要传入监控的参数

输出结果:
在这里插入图片描述
上面是在前10个epoch中损失函数值一直保持不变,如果在第5个epoch中更新一下loss值,在来观察一下输出结果:
在这里插入图片描述
所以在冷却10个epoch之后学习率才会更新。

6、LambdaLR

在这里插入图片描述
功能:自定义调整策略。可以自定义学习率的更新策略,针对不同的参数组设置不同的学习率。这里的lr_lambda表示function或者list,下面从代码中了解一下:

lr_init = 0.1weights_1 = torch.randn((6, 3, 5, 5))
weights_2 = torch.ones((5, 5))optimizer = optim.SGD([{'params': [weights_1]},{'params': [weights_2]}], lr=lr_init)lambda1 = lambda epoch: 0.1 ** (epoch // 20)
lambda2 = lambda epoch: 0.95 ** epochscheduler = torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=[lambda1, lambda2])lr_list, epoch_list = list(), list()
for epoch in range(max_epoch):for i in range(iteration):# train(...)optimizer.step()optimizer.zero_grad()scheduler.step()lr_list.append(scheduler.get_lr())epoch_list.append(epoch)print('epoch:{:5d}, lr:{}'.format(epoch, scheduler.get_lr()))plt.plot(epoch_list, [i[0] for i in lr_list], label="lambda 1")
plt.plot(epoch_list, [i[1] for i in lr_list], label="lambda 2")
plt.xlabel("Epoch")
plt.ylabel("Learning Rate")
plt.title("LambdaLR")
plt.legend()
plt.show()

输出结果:
在这里插入图片描述
【总结】
pytorch中的学习率调整策略
有序调整:Step、MultiStep、 Exponential和CosineAnnealing, 需要事先知道学习率大体需要在多少个epoch之后调整的时候用
自适应调整:ReduceLROnPleateau, 这个非常实用,可以监控某个参数,根据参数的变化情况自适应调整
自定义调整:Lambda, 这个在模型的迁移中或者多个参数组不同学习策略的时候实用
学习率初始化策略
1、设置较小数:0.01, 0.001, 0.0001
2、搜索最大学习率:论文《Cyclical Learning Rates for Training Neural Networks》, 先让学习率从0开始慢慢的增大,然后观察acc, 训练准确率开始下降了,就把初始学习率定为那个数。
在这里插入图片描述
在这里插入图片描述


推荐阅读
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
author-avatar
jimscloudy
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有