一文总结调参技巧-程序员宅基地

技术标签: # 深度学习-深度学习基础知识  算法  计算机视觉  深度学习  神经网络  # 深度学习-论文笔记  

调参数是深度学习工作中,必不可少的一步。

“得参数者,得天下“

那么,调参的方法常见的有哪些?小编为您总结一番~

01寻找合适的学习率(learning rate)

学习率是一个非常非常重要的超参数在面对不同规模、不同batch-size、不同优化方式、不同数据集时,学习率的最合适的值都是不确定的,所以,我们无法光凭经验来准确地确定学习率的值。策略:在训练中不断寻找最合适当前状态的学习率。下图利用fastai中的lr_find()函数寻找合适的学习率,根据下方的学习率-损失曲线得到此时合适的学习率为1e-2。

推荐一篇fastai首席设计师「Sylvain Gugger」的一篇博客:How Do You Find A Good Learning Rate[1]以及相关的论文Cyclical Learning Rates for Training Neural Networks[2]。

02learning-rate与batch-size的关系

一般来说,越大的batch-size使用越大的学习率。越大的batch-size意味着我们学习的时候,收敛方向的confidence越大。小的batch-size则显得比较杂乱,毫无规律性,并且相比大批次,批次小的情况下无法照顾到更多的情况,则需要小的学习率来保证不至于出错。如下图损失Loss与学习率Lr的关系:

在显存足够的条件下,最好采用较大的batch-size进行训练,找到合适的学习率后,可以加快收敛速度。另外,较大的batch-size可以避免batch normalization出现的一些小问题,参考如下Pytorch库Issue

03权重初始化

权重初始化的适用并不频繁。大都适用的是预训练模型。但是对于没有预训练模型的领域,需要自己初始化权重,或者在模型中去初始化神经网络最后那几个全连接层的权重。常用的权重初始化算法是「kaiming_normal」或者「xavier_normal」。

相关论文:

Delving deep into rectifiers: Surpassing human-level performance on ImageNet classificationUnderstanding the difficulty of training deep feedforward neural networksXavier初始化论文He初始化论文

不初始化可能会减慢收敛速度,影响收敛效果。

总结几种初始化方法:uniform均匀分布初始化:

Xavier初始法,适用于普通激活函数(tanh, sigmoid):

He初始化,适用于ReLU:

normal高斯分布初始化, 其中stdev为高斯分布的标准差,均值设为0:

Xavier初始法,适用于普通激活函数 (tanh,sigmoid):

svd初始化:对RNN有比较好的效果。参考论文:https://arxiv.org/abs/1312.6120[8]

04Dropout

Dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络。Dropout一般适合于全连接层部分,而卷积层由于其参数并不是很多,所以不需要dropout,加上的话对模型的泛化能力并没有太大的影响。

05数据集处理

主要有「数据筛选」 以及 「数据增强」fastai中的图像增强技术为什么相对比较好[9]

06难例挖掘 hard-negative-mining

分析模型难以预测正确的样本,给出针对性方法。

07多模型融合

Ensemble是论文刷结果的终极核武器,深度学习中一般有以下几种方式

同样的参数,不同的初始化方式不同的参数,通过cross-validation,选取最好的几组同样的参数,模型训练的不同阶段,即不同迭代次数的模型。不同的模型,进行线性融合. 例如RNN和传统模型.提高模型性能和鲁棒性大法:probs融合 和 投票法。

假设这里有model 1, model 2, model 3,可以这样融合:

1. model1 probs + model2 probs + model3 probs ==> final label

2. model1 label , model2 label , model3 label ==> voting ==> final label

3. model1_1 probs + ... + model1_n probs ==> mode1 label, model2 label与model3获取的label方式与1相同 ==> voting ==> final label

第三个方式的启发来源于,如果一个model的随机种子没有固定,多次预测得到的结果可能不同。

以上方式的效果要根据label个数,数据集规模等特征具体问题具体分析,表现可能不同,方式无非是probs融合和投票法的单独使用or结合。

08差分学习率与迁移学习

迁移学习,一种很常见的深度学习技巧,利用很多预训练的经典模型直接去训练我们自己的任务。虽然说领域不同,但是在学习权重的广度方面,两个任务之间还是有联系的。

由上图,用「model A」训练好的模型权重训练我们自己的模型权重(「Model B」),其中,modelA可能是ImageNet的预训练权重,而ModelB则是我们自己想要用来识别猫和狗的预训练权重。

神经网络(如下图)一般分为三个部分,输入层,隐含层和输出层,随着层数的增加,神经网络学习到的特征越抽象。

因此,下图中的卷积层和全连接层的学习率也应该设置的不一样,一般来说,卷积层设置的学习率应该更低一些,而全连接层的学习率可以适当提高。

差分学习率:在不同的层设置不同的学习率,可以提高神经网络的训练效果,具体的介绍可以查看下方的连接。

余弦退火(cosine annealing)和热重启的随机梯度下降「余弦」就是类似于余弦函数的曲线,「退火」就是下降,「余弦退火」就是学习率类似余弦函数慢慢下降。「热重启」就是在学习的过程中,「学习率」慢慢下降然后突然再「回弹」(重启)然后继续慢慢下降。两个结合起来就是下方的学习率变化图

相关论文SGDR: Stochastic Gradient Descent with Warm Restarts

09尝试过拟合一个小数据集

这是一个经典的小trick了,但是很多人并不这样做,可以尝试一下。关闭正则化/随机失活/数据扩充,使用训练集的一小部分,让神经网络训练几个周期。确保可以实现零损失,如果没有,那么很可能什么地方出错了。

10多尺度训练

多尺度训练是一种「直接有效」的方法,通过输入不同尺度的图像数据集,因为神经网络卷积池化的特殊性,让神经网络充分地学习不同分辨率下图像的特征,可以提高机器学习的性能。处理过拟合效应,在图像数据集不是特别充足的情况下,可以先训练小尺寸图像,然后增大尺寸并再次训练相同模型,这样的思想在Yolo-v2的论文中也提到过:

多尺度训练并不是适合所有的深度学习应用,多尺度训练可以算是特殊的数据增强方法,在图像大小做了调整。

11Cross Validation 交叉验证

在李航的统计学方法中说到,交叉验证往往是对实际应用中「数据不充足」而采用的,基本目的就是重复使用数据。

交叉验证只针对训练集和验证集。交叉验证是Kaggle比赛中特别推崇的一种技巧,我们经常使用的是5-折(5-fold)交叉验证,将训练集分成5份,随机挑一份做验证集其余为训练集,循环5次,这种比较常见计算量也不是很大。还有一种叫做leave-one-out cross validation

留一交叉验证,这种交叉验证就是n-折交叉,n表示数据集的容量,(适合数据量比较小的情况)

12优化算法

按理说不同的优化算法适合于不同的任务,不过我们大多数采用的优化算法还是是adam和SGD+monmentum。Adam 可以解决 loss 降不下去的情况,但是Adam和L2正则结合会产生的复杂效果。adam的相比SGD,收敛快,但泛化能力差,更优结果似乎需要精调SGD。adam,adadelta等, 在小数据上,我这里实验的效果不如sgd, sgd收敛速度会慢一些,但是最终收敛后的结果,一般都比较好。如果使用sgd的话,可以选择从1.0或者0.1的学习率开始,隔一段时间,在验证集上检查一下,如果cost没有下降,就对学习率减半. 我看过很多论文都这么搞,我自己实验的结果也很好. 当然,也可以先用ada系列先跑,最后快收敛的时候,更换成sgd继续训练.同样也会有提升.据说adadelta一般在分类问题上效果比较好,adam在生成问题上效果比较好。adam收敛虽快但是得到的解往往没有sgd+momentum得到的解更好,如果不考虑时间成本的话还是用sgd吧。

adam是不需要特别调lr,sgd要多花点时间调lr和initial weights。

13数据预处理方式

zero-center ,常用.

PCA whitening,较少应用。

14训练技巧

梯度归一化,即算出来的梯度除以minibatch sizeclip c(梯度裁剪): 限制最大梯度,其实是value = sqrt(w1^2+w2^2….),如果value超过了阈值,就算一个衰减系系数,让value的值等于阈值: 5,10,15dropout对小数据防止过拟合有很好的效果,值一般设为0.5小数据上dropout+sgd在我的大部分实验中,效果提升都非常明显.因此可能的话,建议一定要尝试一下。dropout的位置比较有讲究, 对于RNN,建议放到输入->RNN与RNN->输出的位置.关于RNN如何用dropout,可以参考这篇论文:http://arxiv.org/abs/1409.2329[15]除了gate之类的地方,需要把输出限制成0-1之外,尽量不要用sigmoid,可以用tanh或者relu之类的激活函数.sigmoid函数在-4到4的区间里,才有较大的梯度。之外的区间,梯度接近0,很容易造成梯度消失问题。输入0均值,sigmoid函数的输出不是0均值的。rnn的dim和embdding size,一般从128上下开始调整. batch size,一般从128左右开始调整. batch size合适最重要,并不是越大越好.word2vec初始化,在小数据上,不仅可以有效提高收敛速度,也可以可以提高结果.尽量对数据做shuffleLSTM 的forget gate的bias,用1.0或者更大的值做初始化,可以取得更好的结果,来自这篇论文(:http://jmlr.org/proceedings/papers/v37/jozefowicz15.pdf)实验设成1.0,可以提高收敛速度.实际使用中,不同的任务,可能需要尝试不同的值.Batch Normalization据说可以提升效果,(参考论文:Accelerating Deep Network Training by Reducing Internal Covariate Shift)如果你的模型包含全连接层(MLP),并且输入和输出大小一样,可以考虑将MLP替换成Highway Network,我尝试对结果有一点提升,建议作为最后提升模型的手段,原理很简单,就是给输出加了一个gate来控制信息的流动,(详细介绍请参考论文: http://arxiv.org/abs/1505.00387[17])来自@张馨宇的技巧:一轮加正则,一轮不加正则,反复进行。在数据集很大的情况下,一上来就跑全量数据。建议先用 1/100、1/10 的数据跑一跑,对模型性能和训练时间有个底,外推一下全量数据到底需要跑多久。在没有足够的信心前不做大规模实验。subword 总是会很稳定地涨点,只管用就对了。GPU 上报错时尽量放在 CPU 上重跑,错误信息更友好。例如 GPU 报 "ERROR:tensorflow:Model diverged with loss = NaN" 其实很有可能是输入 ID 超出了 softmax 词表的范围。在确定初始学习率的时候,从一个很小的值(例如 1e-7)开始,然后每一步指数增大学习率(例如扩大1.05 倍)进行训练。训练几百步应该能观察到损失函数随训练步数呈对勾形,选择损失下降最快那一段的学习率即可。补充一个rnn trick,仍然是不考虑时间成本的情况下,batch size=1是一个很不错的regularizer, 起码在某些task上,这也有可能是很多人无法复现alex graves实验结果的原因之一,因为他总是把batch size设成1。注意实验的可复现性和一致性,注意养成良好的实验记录习惯 ==> 不然如何分析出实验结论。超参上,learning rate 最重要,推荐了解 cosine learning rate 和 cyclic learning rate,其次是 batchsize 和 weight decay。当你的模型还不错的时候,可以试着做数据增广和改损失函数锦上添花了。参考

关于训练神经网路的诸多技巧Tricks\(完全总结版\)[18]你有哪些deep learning(rnn、cnn)调参的经验?[19]Bag of Tricks for Image Classification with Convolutional Neural Networks[20]trick 合集 1Must Know Tips/Tricks in Deep Neural Networks[21]trick 合集 233条神经网络训练秘技[22]trick 合集 326秒单GPU训练CIFAR10[23]工程实践Batch Normalization[24],虽然玄学,但是养活了很多炼丹师

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/a8039974/article/details/121699068

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签