深度学习中的学习率设置技巧与实现详解


❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️

👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博相关......)👈

深度学习中的学习率设置技巧与实现详解

(封面图由文心一格生成)

深度学习中的学习率设置技巧与实现详解

深度学习中的学习率是一个非常重要的超参数,对模型的训练和结果影响极大。在深度学习模型中,学习率决定了参数更新的步长,因此合理设置学习率对于优化算法的收敛速度、模型的训练效果以及泛化性能都有很大的影响。本文将介绍深度学习中的学习率设置技巧,包括常用的学习率衰减方法、自适应学习率方法以及学习率预热等。

1. 常用的学习率衰减方法

1.1 学习率衰减

学习率衰减是一种常见的优化算法,它可以随着训练的进行,逐渐减小学习率,从而使得模型在训练初期能够快速地收敛,而在训练后期能够更加稳定地更新参数。学习率衰减的方法有很多种,包括Step Decay、Exponential Decay、Polynomial Decay等。

Step Decay是一种常见的学习率衰减方法,它是在训练的过程中,根据固定的步数对学习率进行逐步地降低。例如,假设初始学习率为0.1,每隔10个epoch将学习率降低10倍,那么当训练到第11个epoch时,学习率将变为0.01,当训练到第21个epoch时,学习率将变为0.001,以此类推。这种方法简单易行,但是需要手动设置衰减的步数和衰减的幅度,不太灵活。

Exponential Decay是一种常见的指数衰减方法,它可以根据训练的epoch数来逐渐减小学习率。具体而言,Exponential Decay方法的学习率衰减规则如下:

α = α 0 ⋅ e − k t \alpha=\alpha_0 · e^{-kt} α=α0ekt

其中, α 0 \alpha_0 α0表示初始学习率, k k k为衰减系数, t t t表示训练的epoch数。随着训练的进行, t t t会不断增大,因此学习率会不断减小。Exponential Decay方法可以通过设置不同的 k k k值来控制学习率的衰减速度,从而达到更好的训练效果。

Polynomial Decay是一种常见的多项式衰减方法,它可以通过多项式函数来逐渐减小学习率。具体而言,Polynomial Decay方法的学习率衰减规则如下:
α = α ⋅ ( 1 − t T ) p \alpha=\alpha\cdot (1 - \frac{t}{T})^p α=α(1Tt)p
其中, α 0 \alpha_0 α0表示初始学习率, p p p为多项式的幂次数, t t t表示训练的epoch数, T T T为总的训练epoch数。随着训练的进行, t t t会不断增大,因此学习率会不断减小,同时随着 p p p的增大,学习率的衰减速度也会加快。

1.2 余弦退火

余弦退火(Cosine Annealing)是一种新兴的学习率衰减方法,它通过余弦函数来逐渐减小学习率,从而达到更好的训练效果。具体而言,余弦退火方法的学习率衰减规则如下:
α = α 0 ⋅ 1 + cos ⁡ ( π ⋅ t T ) 2 \alpha = \alpha_0 \cdot \frac{1 + \cos(\frac{\pi \cdot t}{T})}{2} α=α021+cos(Tπt)

其中, α 0 \alpha_0 α0表示初始学习率, t t t表示训练的epoch数, T T T为总的训练epoch数。随着训练的进行, t t t会不断增大,因此学习率会不断减小,同时余弦函数的周期也会不断缩小,从而使得学习率在训练过程中逐渐降低。

1.3 One Cycle Learning Rate

One Cycle Learning Rate是一种比较新的学习率衰减方法,它通过在训练初期使用一个较大的学习率,从而快速地收敛到一个局部最优解,然后在训练后期使用一个较小的学习率,从而逐步地优化模型。具体而言,One Cycle Learning Rate方法的学习率变化规则如下:

  • 在训练初期,使用较大的学习率(如初始学习率的10倍),从而快速地收敛到一个局部最优解;
  • 然后在训练中期,使用较小的学习率,从而逐步地优化模型;
  • 最后在训练后期,再次使用较小的学习率,从而让模型更加稳定。
    One Cycle Learning Rate方法可以有效地提高模型的训练速度和泛化性能,但是需要仔细调整超参数,否则容易导致模型的过拟合。

2. 自适应学习率方法

除了学习率衰减方法之外,深度学习中还有很多自适应学习率方法,包括Adagrad、Adadelta、Adam等。这些方法都是基于梯度信息来自适应地调整学习率,从而在训练过程中更加稳定和高效。

2.1 Adagrad

Adagrad是一种自适应学习率方法,它可以根据参数梯度的大小来动态地调整学习率。具体而言,Adagrad方法的学习率更新规则如下:

其中, α 0 \alpha_0 α0表示初始学习率, g i g_i gi表示参数的梯度, ϵ \epsilon ϵ是一个非常小的常数,用于防止分母为0。Adagrad方法的优点在于它可以根据参数的梯度大小自适应地调整学习率,从而更好地适应不同的数据分布和参数更新。但是Adagrad方法也有一些缺点,比如需要存储梯度平方和的累积值,导致内存占用较大;另外,由于学习率是逐渐减小的,因此可能会导致模型在后期训练时收敛速度变慢。

2.2 Adadelta

Adadelta是一种自适应学习率方法,它可以根据参数梯度的大小和历史梯度信息来动态地调整学习率Adadelta方法的优点在于它可以动态地调整学习率,并且不需要存储梯度平方和的累积值,因此内存占用较小。但是Adadelta方法也有一些缺点,比如需要手动设置一些超参数,例如平均梯度的衰减率和初始的平均梯度值等。

2.3 Adam

Adam是一种自适应学习率方法,它可以根据参数梯度的大小和历史梯度信息来动态地调整学习率,并且还可以适应不同的数据分布和参数更新。具体而言,Adam方法的学习率更新规则如下:
m t = β 1 ⋅ m t − 1 + ( 1 − β 1 ) ⋅ g t v t = β 2 ⋅ v t − 1 + ( 1 − β 2 ) ⋅ g t 2 m ^ t = m t 1 − β 1 t v ^ t = v t 1 − β 2 t Δ x t = − α v ^ t + ϵ ⋅ m ^ t \begin{aligned}m_t &= \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g_t \\ v_t &= \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g_t^2 \\ \hat{m}_t &= \frac{m_t}{1 - \beta_1^t} \\ \hat{v}_t &= \frac{v_t}{1 - \beta_2^t} \\ \Delta x_t &= -\frac{\alpha}{\sqrt{\hat{v}_t}+\epsilon} \cdot \hat{m}_t\end{aligned} mtvtm^tv^tΔxt=β1mt1+(1β1)gt=β2vt1+(1β2)gt2=1β1tmt=1β2tvt=v^t +ϵαm^t

其中, g t g_t gt表示参数的梯度, m t m_t mt v t v_t vt分别表示梯度的一阶和二阶矩, β 1 \beta_1 β1 β 2 \beta_2 β2是衰减率, m ^ t \hat{m}_t m^t v ^ t \hat{v}_t v^t分别表示修正后的一阶和二阶矩, α \alpha α表示初始学习率, ϵ \epsilon ϵ是一个非常小的常数,用于防止分母为0。
Adam方法的优点在于它不仅可以动态地调整学习率,还可以适应不同的数据分布和参数更新,从而在训练过程中更加稳定和高效。但是Adam方法也有一些缺点,比如需要手动设置一些超参数,例如衰减率和初始学习率等。
三、学习率预热
学习率预热是一种常见的训练技巧,它可以在训练初期使用一个较小的学习率,从而避免模型在训练初期过度更新参数,导致模型不稳定。具体而言,学习率预热的方法是在训练前先使用一个较小的学习率进行一些预热操作,例如在训练初期进行一些预热的epoch,然后再逐步地增加学习率,从而使得模型更加稳定和高效。
学习率预热的方法可以有效地避免模型在训练初期过度更新参数,导致模型不稳定,同时也可以加速模型的收敛速度,提高训练效率和泛化性能。

3. 代码实现

下面是使用PyTorch实现常见的学习率衰减方法和自适应学习率方法的代码示例:

3.1 Step Decay

import torch.optim as optim
optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9)
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)
for epoch in range(num_epochs):
	# train
	train_loss, train_acc = train(...)
	# update learning rate
	scheduler.step()
	# validation
	val_loss, val_acc = validate(...)
	# print results
	print('Epoch [{}/{}], Train Loss: {:.4f}, Train Acc: {:.4f}, Val Loss: {:.4f}, Val Acc: {:.4f}'.format(epoch+1, num_epochs, train_loss, train_acc, val_loss, val_acc))

3.2 Exponential Decay

import torch.optim as optim
optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9)
scheduler = optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.95)

for epoch in range(num_epochs):
	# train
	train_loss, train_acc = train(...)
	
	# update learning rate
	scheduler.step()
	
	# validation
	val_loss, val_acc = validate(...)
	
	# print results
	print('Epoch [{}/{}], Train Loss: {:.4f}, Train Acc: {:.4f}, Val Loss: {:.4f}, Val Acc: {:.4f}'.format(epoch+1, num_epochs, train_loss, train_acc, val_loss, val_acc))

3.3 Cosine Annealing

import torch.optim as optim

optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9)
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100)

for epoch in range(num_epochs):
    # train
    train_loss, train_acc = train(...)
    
    # update learning rate
    scheduler.step()
    
    # validation
    val_loss, val_acc = validate(...)
    
    # print results
    print('Epoch [{}/{}], Train Loss: {:.4f}, Train Acc: {:.4f}, Val Loss: {:.4f}, Val Acc: {:.4f}'.format(
        epoch+1, num_epochs, train_loss, train_acc, val_loss, val_acc))

3.4 Adagrad

import torch.optim as optim

optimizer = optim.Adagrad(net.parameters(), lr=0.1)

for epoch in range(num_epochs):
    # train
    train_loss, train_acc = train(...)
    
    # update learning rate
    optimizer.step()
    optimizer.zero_grad()
    
    # validation
    val_loss, val_acc = validate(...)
    
    # print results
    print('Epoch [{}/{}], Train Loss: {:.4f}, Train Acc: {:.4f}, Val Loss: {:.4f}, Val Acc: {:.4f}'.format(
        epoch+1, num_epochs, train_loss, train_acc, val_loss, val_acc))

3.5 Adadelta

import torch.optim as optim

optimizer = optim.Adadelta(net.parameters(), lr=0.1, rho=0.9, eps=1e-6)

for epoch in range(num_epochs):
    # train
    train_loss, train_acc = train(...)
    
    # update learning rate
    optimizer.step()
    optimizer.zero_grad()
    
    # validation
    val_loss, val_acc = validate(...)
    
    # print results
    print('Epoch [{}/{}], Train Loss: {:.4f}, Train Acc: {:.4f}, Val Loss: {:.4f}, Val Acc: {:.4f}'.format(
        epoch+1, num_epochs, train_loss, train_acc, val_loss, val_acc))

3.6 Adam

import torch.optim as optim

optimizer = optim.Adam(net.parameters(), lr=0.1, betas=(0.9, 0.99), eps=1e-8)

for epoch in range(num_epochs):
    # train
    train_loss, train_acc = train(...)
    
    # update learning rate
    optimizer.step()
    optimizer.zero_grad()
    
    # validation
    val_loss, val_acc = validate(...)
    
    # print results
    print('Epoch [{}/{}], Train Loss: {:.4f}, Train Acc: {:.4f}, Val Loss: {:.4f}, Val Acc: {:.4f}'.format(epoch+1, num_epochs, train_loss, train_acc, val_loss, val_acc))

4. 总结

本文介绍了深度学习中常见的学习率设置技巧,包括学习率衰减方法和自适应学习率方法。学习率衰减方法可以根据训练的进展情况动态地调整学习率,从而提高模型的训练效率和泛化性能;自适应学习率方法可以根据参数梯度的大小和历史梯度信息来动态地调整学习率,从而在训练过程中更加稳定和高效。此外,学习率预热也是一种常见的训练技巧,它可以在训练初期使用一个较小的学习率,从而避免模型在训练初期过度更新参数,导致模型不稳定。

在代码实现方面,PyTorch提供了许多内置的学习率调度器和自适应学习率优化器,可以方便地实现各种学习率设置技巧。通过合理地选择和使用这些工具,可以帮助我们更加高效地训练深度学习模型,并获得更好的训练效果和泛化性能。


❤️觉得内容不错的话,欢迎点赞收藏加关注😊😊😊,后续会继续输入更多优质内容❤️

👉有问题欢迎大家加关注私戳或者评论(包括但不限于NLP算法相关,linux学习相关,读研读博相关......)👈

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/3622.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(五)Tomcat源码阅读:Engine组件分析

一、概述 在阅读源码之前我们需要对各个类的关系有一个清晰的了解,下面就是Engine各个类之间的关系,我们将会按照从上到下的顺序阅读源码。 二、阅读源码 1、Container (1)注释 Container可以处理请求并给予相应,并…

JavaScript-扫盲

文章目录1. 前言2. 第一个 JavaScript 程序3. javaScript 的基础语法3.1 变量3.2 数据类型3.3 运算符3.4 条件语句3.5 数组3.6 函数3.7 作用域3.8 对象4. WebAPI4.1 DOM 基本概念4.2 常用 DOM API4.3 事件4.4 操作元素4.5 网页版猜数字游戏4.6 留言版1. 前言 提问 java 和 java…

集合之CurrentHashMap 1.7总结

文章目录底层实现构造方法默认的三个参数什么是Unsafe类?它有什么作用?为什么CurrentHashMap 调用Unsafe方法不会报错?我们自己创建的对象调用会报错?CurrentHashMap的key,value可以为null吗?CurrentHashMa…

水风险指数定义及计算:水资源压力等

水风险指数(Water risk indicators) 水风险指数(Water risk indicators)是用来评估水资源可持续性和水相关风险的一种工具,可以通过多种指标来衡量。 1.1 水资源压力(water stress, WS) 定义…

leetcode -- 142. 环形链表 II

🐨目录📜1. 题目🔍2. 思路🔑2.1 链表是否带环🔑2.2 为何能追上🔑2.3 入口点的确定🔓3. 代码实现📡4. 题目链接📜1. 题目 给定一个链表的头节点 head,返回链表…

自定义类型 (位段、枚举、联合体)

文章目录📬位段🔎1.什么是位段🔎2.位段的内存分配🔎3.位段的跨平台问题📬枚举🔎1.枚举类型的定义🔎2.枚举的优点🔎3.枚举的使用📬联合(共用体)&am…

C/C++中for语句循环用法及练习

目录 语法 下面是 for 循环的控制流: 实例 基于范围的for循环(C11) 随堂笔记! C语言训练-计算1~N之间所有奇数之和 题目描述 输入格式 输出格式 样例输入 样例输出 环形方阵 干货直达 for 循环允许您编写一个执行特定次数的循环的重复控制结构。…

Go语言基础:数组定义及循环遍历

前言 大家好,我是沐风晓月,本文go语言入门-掌握go语言函数收录于《go语言学习专栏》专栏,此专栏带你从零开始学习go语言,持续更新中,欢迎点赞收藏。 🏠个人主页:我是沐风晓月 🧑个人…

Postman接口与压力测试实例

Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。它提供功能强大的 Web API & HTTP 请求调试。 1、环境变量和全局变量设置 环境变量可以使用在以下地方: URLURL paramsHeader valuesform-data/url-encoded valuesRaw body contentHelper fi…

RedgateClone启用并行工作流 crack

RedgateClone启用并行工作流 crack RedgateClone允许您轻松创建用于开发和测试场景的数据库的一次性副本。通过使用生产数据库的克隆来降低成本并提高测试和发布的质量。Redgate克隆支持Microsoft SQL Server、Postgres、Oracle和MySQL数据库。 红门克隆的好处 最多可节省99%的…

CentOS从gcc 4.8.5 升级到gcc 8.3.1

gcc -v查看当前gcc版本。 sudo yum install centos-release-scl-rh安装centos-release-scl-rh。 sudo yum install devtoolset-8-build安装devtoolset-8-build。 显示“Complete!”表示安装成功。 sudo yum install devtoolset-8-gdb安装devtoolset-8-gdb。 显示“Comple…

[JAVA]一步接一步的一起开发-图书管理系统(非常仔细,你一定能看懂)[1W字+]

目录 1.想法 2.框架的搭构 2.1图书 2.1.1Book类 2.1.2BookList类 2.2用户 2.2.1User抽象类 2.2.2AdminUser类(管理者) 2.2.3NormalUser 2.3操作 操作接口 借阅操作 删除操作 查询操作 归还图书 展示图书 退出系统 2.4小结 3.主函数的编…

【python实操】年轻人,别用记事本保存数据了,试试数据库吧

为什么用数据库? 数据库比记事本强在哪? 答案很明显,你的文件很多时候都只能被一个人打开,不能被重复打开。当有几百万数据的时候,你如何去查询操作数据,速度上要快,看起来要清晰直接 数据库比我…

Azure OpenAI 官方指南03|DALL-E 的图像生成功能与安全过滤机制

2021年1月,OpenAI 推出 DALL-E。这是 GPT 模型在图像生成方面的人工智能应用。其名称来源于著名画家、艺术家萨尔瓦多 • 达利(Dal)和机器人总动员(Wall-E)。DALL-E 图像生成器,能够直接根据文本描述生成多…

蓝桥杯真题——模拟灌溉系统

尽量每天都自己写一遍模板,记住模板就好写了 以下内容直接在模板内进行 基本任务:要求“模拟智能灌溉系统”能够实现土壤湿度测量、土壤湿度和时间显示、湿度阈值设 定及存储等基本功能。通过电位器 Rb2 输出电压信号,模拟湿度传感器输出信号…

常见排序算法(C语言实现)

文章目录排序介绍插入排序直接插入排序希尔排序选择排序选择排序堆排序交换排序冒泡排序快速排序递归实现Hoare版本挖坑法前后指针版本非递归实现Hoare版本挖坑法前后指针版本快排的优化三值取中小区间优化归并排序递归实现非递归实现计数排序排序算法复杂度及稳定性分析不同算…

C语言——字符串函数(2)和内存函数

(一)strtok函数dilimiters参数是个字符串,定义了用作分隔符的字符集合第一个参数指定一个字符串,它包含了0个或者多个由dilimiters字符串中一个或者多个分隔符分割的标记。strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回…

第二章Vue组件化编程

文章目录模块与组件、模块化与组件化模块组件模块化组件化Vue中的组件含义非单文件组件基本使用组件注意事项使用 kebab-case使用 PascalCase组件的嵌套模板templateVueComponent一个重要的内置功能单文件组件Vue脚手架使用Vue CLI脚手架先配置环境初始化脚手架分析脚手架结构实…

vue路由的使用

地址&#xff1a; 入门 | Vue Router 一、导入vuerouter依赖包 注意&#xff0c;一定要先引入vue&#xff0c;再引入vue-router&#xff08;引入vue在引入vue-router的上面&#xff09;。不然会报错 <head><meta charset"utf-8"><title></ti…

算法:贪婪算法、分而治之

算法&#xff1a;贪婪算法、分而治之 文章目录1.贪婪算法计数硬币实例12.分而治之分割/歇征服/解决合并/合并实例23.动态规划对照实例34.基本概念算法数据定义数据对象内置数据类型派生数据类型基本操作1.贪婪算法 设计算法以实现给定问题的最佳解决方案。在贪婪算法方法中&am…