深度学习调参技巧

2023-11-04


深度学习调参技巧

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

学习率是一个非常非常重要的超参数,这个参数呢,面对不同规模、不同batch-size、不同优化方式、不同数据集,其最合适的值都是不确定的,我们无法光凭经验来准确地确定lr的值,我们唯一可以做的,就是在训练中不断寻找最合适当前状态的学习率。

比如下图利用fastai中的lr_find()函数寻找合适的学习率,根据下方的学习率-损失曲线得到此时合适的学习率为1e-2。
在这里插入图片描述
推荐一篇fastai首席设计师「Sylvain Gugger」的一篇博客:How Do You Find A Good Learning Rate

以及相关的论文Cyclical Learning Rates for Training Neural Networks

二、learning-rate与batch-size的关系

一般来说,越大的batch-size使用越大的学习率。

原理很简单,越大的batch-size意味着我们学习的时候,收敛方向的confidence越大,我们前进的方向更加坚定,而小的batch-size则显得比较杂乱,毫无规律性,因为相比批次大的时候,批次小的情况下无法照顾到更多的情况,所以需要小的学习率来保证不至于出错。

可以看下图损失Loss与学习率Lr的关系:
在这里插入图片描述
在显存足够的条件下,最好采用较大的batch-size进行训练,找到合适的学习率后,可以加快收敛速度。

另外,较大的batch-size可以避免batch normalization出现的一些小问题,参考如下Pytorch库Issue

三、权重初始化

权重初始化相比于其他的trick来说在平常使用并不是很频繁。

因为大部分人使用的模型都是预训练模型,使用的权重都是在大型数据集上训练好的模型,当然不需要自己去初始化权重了。只有没有预训练模型的领域会自己初始化权重,或者在模型中去初始化神经网络最后那几个全连接层的权重。

常用的权重初始化算法是「kaiming_normal」或者「xavier_normal」。
相关论文:

四,dropout

dropout是指在深度学习网络的训练过程中,对于神经网络单元,按照一定的概率将其暂时从网络中丢弃。注意是「暂时」,对于随机梯度下降来说,由于是随机丢弃,故而每一个mini-batch都在训练不同的网络。

Dropout类似于bagging ensemble减少variance。也就是投通过投票来减少可变性。通常我们在全连接层部分使用dropout,在卷积层则不使用。但「dropout」并不适合所有的情况,不要无脑上Dropout。

Dropout一般适合于全连接层部分,而卷积层由于其参数并不是很多,所以不需要dropout,加上的话对模型的泛化能力并没有太大的影响。
在这里插入图片描述
我们一般在网络的最开始和结束的时候使用全连接层,而hidden layers则是网络中的卷积层。所以一般情况,在全连接层部分,采用较大概率的dropout而在卷积层采用低概率或者不采用dropout。

五,多模型融合

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

  • 同样的参数,不同的初始化方式
  • 不同的参数,通过cross-validation,选取最好的几组
  • 同样的参数,模型训练的不同阶段,即不同迭代次数的模型。
  • 不同的模型,进行线性融合. 例如RNN和传统模型.
    提高模型性能和鲁棒性大法:probs融合 和 投票法。
    假设这里有model 1, model 2, model 3,可以这样融合:
    在这里插入图片描述
    第三个方式的启发来源于,如果一个model的随机种子没有固定,多次预测得到的结果可能不同。

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

六、差分学习率与迁移学习

首先说下迁移学习,迁移学习是一种很常见的深度学习技巧,我们利用很多预训练的经典模型直接去训练我们自己的任务。虽然说领域不同,但是在学习权重的广度方面,两个任务之间还是有联系的。
在这里插入图片描述
由上图,我们拿来「model A」训练好的模型权重去训练我们自己的模型权重(「Model B」),其中,modelA可能是ImageNet的预训练权重,而ModelB则是我们自己想要用来识别猫和狗的预训练权重。

那么差分学习率和迁移学习有什么关系呢?我们直接拿来其他任务的训练权重,在进行optimize的时候,如何选择适当的学习率是一个很重要的问题。

一般地,我们设计的神经网络(如下图)一般分为三个部分,输入层,隐含层和输出层,随着层数的增加,神经网络学习到的特征越抽象。因此,下图中的卷积层和全连接层的学习率也应该设置的不一样,一般来说,卷积层设置的学习率应该更低一些,而全连接层的学习率可以适当提高。
在这里插入图片描述
这就是差分学习率的意思,在不同的层设置不同的学习率,可以提高神经网络的训练效果,具体的介绍可以查看下方的连接。
在这里插入图片描述
上面的示例图来自:https://towardsdatascience.com/transfer-learning-using-differential-learning-rates-638455797f00

七、多尺度训练

多尺度训练是一种「直接有效」的方法,通过输入不同尺度的图像数据集,因为神经网络卷积池化的特殊性,这样可以让神经网络充分地学习不同分辨率下图像的特征,可以提高机器学习的性能。

也可以用来处理过拟合效应,在图像数据集不是特别充足的情况下,可以先训练小尺寸图像,然后增大尺寸并再次训练相同模型,这样的思想在Yolo-v2的论文中也提到过:
在这里插入图片描述
需要注意的是:多尺度训练并不是适合所有的深度学习应用,多尺度训练可以算是特殊的数据增强方法,在图像大小这一块做了调整。如果有可能最好利用可视化代码将多尺度后的图像近距离观察一下,「看看多尺度会对图像的整体信息有没有影响」,如果对图像信息有影响的话,这样直接训练的话会误导算法导致得不到应有的结果。

八、Cross Validation 交叉验证

在李航的统计学方法中说到,交叉验证往往是对实际应用中「数据不充足」而采用的,基本目的就是重复使用数据。在平常中我们将所有的数据分为训练集和验证集就已经是简单的交叉验证了,可以称为1折交叉验证。「注意,交叉验证和测试集没关系,测试集是用来衡量我们的算法标准的,不参与到交叉验证中来。」

交叉验证只针对训练集和验证集。

交叉验证是Kaggle比赛中特别推崇的一种技巧,我们经常使用的是5-折(5-fold)交叉验证,将训练集分成5份,随机挑一份做验证集其余为训练集,循环5次,这种比较常见计算量也不是很大。还有一种叫做leave-one-out cross validation留一交叉验证,这种交叉验证就是n-折交叉,n表示数据集的容量,这种方法只适合数据量比较小的情况,计算量非常大的情况很少用到这种方法。

九、优化算法

按理说不同的优化算法适合于不同的任务,不过我们大多数采用的优化算法还是是adam和SGD+monmentum。

Adam 可以解决一堆奇奇怪怪的问题(有时 loss 降不下去,换 Adam 瞬间就好了),也可以带来一堆奇奇怪怪的问题(比如单词词频差异很大,当前 batch 没有的单词的词向量也被更新;再比如Adam和L2正则结合产生的复杂效果)。用的时候要胆大心细,万一遇到问题找各种魔改 Adam(比如 MaskedAdam[14], AdamW 啥的)抢救。

但看一些博客说adam的相比SGD,收敛快,但泛化能力差,更优结果似乎需要精调SGD。
adam是不需要特别调lr,sgd要多花点时间调lr和initial weights。

十、训练技巧

要做梯度归一化,即算出来的梯度除以minibatch size

clip c(梯度裁剪): 限制最大梯度,其实是value = sqrt(w12+w22….),如果value超过了阈值,就算一个衰减系系数,让value的值等于阈值: 5,10,15

dropout对小数据防止过拟合有很好的效果,值一般设为0.5
小数据上dropout+sgd在我的大部分实验中,效果提升都非常明显.因此可能的话,建议一定要尝试一下。

dropout的位置比较有讲究, 对于RNN,建议放到输入->RNN与RNN->输出的位置.关于RNN如何用dropout,可以参考这篇论文:http://arxiv.org/abs/1409.2329

除了gate之类的地方,需要把输出限制成0-1之外,尽量不要用sigmoid,可以用tanh或者relu之类的激活函数.
sigmoid函数在-4到4的区间里,才有较大的梯度。之外的区间,梯度接近0,很容易造成梯度消失问题。
输入0均值,sigmoid函数的输出不是0均值的。

rnn的dim和embdding size,一般从128上下开始调整. batch size,一般从128左右开始调整. batch size合适最重要,并不是越大越好.

word2vec初始化,在小数据上,不仅可以有效提高收敛速度,也可以可以提高结果.

尽量对数据做shuffle

LSTM 的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

一轮加正则,一轮不加正则,反复进行。

在数据集很大的情况下,一上来就跑全量数据。建议先用 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。当你的模型还不错的时候,可以试着做数据增广和改损失函数锦上添花了。

本文参考资料

[1]
How Do You Find A Good Learning Rate: https://sgugger.github.io/how-do-you-find-a-good-learning-rate.html

[2]
Cyclical Learning Rates for Training Neural Networks: https://arxiv.org/abs/1506.01186

[3]
Pytorch库Issue: https://github.com/pytorch/pytorch/issues/4534

[4]
Delving deep into rectifiers: Surpassing human-level performance on ImageNet classification: https://www.cv-foundation.org/openaccess/content_iccv_2015/papers/He_Delving_Deep_into_ICCV_2015_paper.pdf

[5]
Understanding the difficulty of training deep feedforward neural networks: http://proceedings.mlr.press/v9/glorot10a.html

[6]
Xavier初始化论文: http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf

[7]
He初始化论文: https://arxiv.org/abs/1502.01852

[8]
https://arxiv.org/abs/1312.6120: https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1312.6120

[9]
fastai中的图像增强技术为什么相对比较好: https://oldpan.me/archives/fastai-1-0-quick-study

[10]
towardsdatascience.com/transfer-le…: https://towardsdatascience.com/transfer-learning-using-differential-learning-rates-638455797f00

[11]
机器学习算法如何调参?这里有一份神经网络学习速率设置指南: https://zhuanlan.zhihu.com/p/34236769

[12]
SGDR: Stochastic Gradient Descent with Warm Restarts: https://arxiv.org/abs/1608.03983

[13]
The nuts and bolts of building applications using deep learning: https://www.youtube.com/watch?v=F1ka6a13S9I

[14]
MaskedAdam: https://www.zhihu.com/question/265357659/answer/580469438

[15]
http://arxiv.org/abs/1409.2329: https://link.zhihu.com/?target=http%3A//arxiv.org/abs/1409.2329

[16]
http://jmlr.org/proceedings/papers/v37/jozefowicz15.pdf: https://link.zhihu.com/?target=http%3A//jmlr.org/proceedings/papers/v37/jozefowicz15.pdf

[17]
http://arxiv.org/abs/1505.00387: https://link.zhihu.com/?target=http%3A//arxiv.org/abs/1505.00387

[18]
关于训练神经网路的诸多技巧Tricks(完全总结版): https://juejin.im/post/5be5b0d7e51d4543b365da51

[19]
你有哪些deep learning(rnn、cnn)调参的经验?: https://www.zhihu.com/question/41631631

[20]
Bag of Tricks for Image Classification with Convolutional Neural Networks: https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1812.01187

[21]
Must Know Tips/Tricks in Deep Neural Networks: https://link.zhihu.com/?target=http%3A//lamda.nju.edu.cn/weixs/project/CNNTricks/CNNTricks.html

[22]
33条神经网络训练秘技: https://zhuanlan.zhihu.com/p/63841572

[23]
26秒单GPU训练CIFAR10: https://zhuanlan.zhihu.com/p/79020733

[24]
Batch Normalization: https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1502.03167%3Fcontext%3Dcs

[25]
Searching for Activation Functions: https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1710.05941

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深度学习调参技巧 的相关文章

随机推荐

  • java设置断点,在Java中设置断点

    How does setting breakpoints in Java work Is it just based on the source file name and line number Does the class or met
  • 编写自动化软件+python

    前言 本文分为代码篇和实操篇 代码篇以 不高兴就喝水 的代码为原版和其他改版做对比 帮助学习了解 实操部分也分为原版的实操和改版的实操 学前准备 pyautogui库用法 https blog csdn net qingfengxd1 ar
  • Cgroups使用

    Cgroups使用 一 Cgroups介绍 linux内核提供了cgroups控制组 controlgroups 的功能 最初由google的工程师提出 后来被整合进Linux内核 Cgroups也是LXC LinuxContainer容器
  • SQL中group by的用法总结

    一 简介SQL语言 SQL语言 是结构化查询语言的简称 SQL语言是一种数据库查询和程序设计语言 用于存取数据以及查询 更新和管理关系数据库系统 同时也是数据库脚本文件的扩展名 SQL语言 是高级的非过程化编程语言 允许用户在高层数据结构上
  • Linux(CentOS7)安装docker

    CentOS7 安装Docker教程 docker官网安装步骤 1 卸载旧版本 sudo yum remove docker docker client docker client latest docker common docker l
  • css 划对号,css3画个圆圈里的对号

    效果如图 image png 基本思路 1先画一个圆 2画两个位于圆中间的小矩形 3旋转矩形 一个左旋45度 一个右旋45度 4利用absolute进行定位 demo2 width 40px height 40px border radiu
  • 爬虫 — 验证码反爬

    目录 一 超级鹰 二 图片验证模拟登录 1 页面分析 1 1 模拟用户正常登录流程 1 2 识别图片里面的文字 2 代码实现 三 滑块模拟登录 1 页面分析 2 代码实现 通过对比像素获取缺口位置 四 openCV 1 简介 2 代码 3
  • 目标检测实战项目『体验篇』

    本文建议阅读时间 8 min 什么是目标检测 目标检测 Object Detection 的任务是找出图像中所有感兴趣的目标 物体 确定它们的类别和位置 是计算机视觉领域的核心问题之一 由于各类物体有不同的外观 形状和姿态 加上成像时光照
  • 二维多孔介质图像的粒度分布研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 使用流域分割算法对岩石二维二值图像进行粒度
  • C # HTTP支持跨域请求

    修改响应的请求头 具体修改详见代码 private void httpPostRequestHandle while true try 等待请求连接 没有请求则GetContext处于阻塞状态 HttpListenerContext req
  • VS2022下载安装与基本使用(写C语言)

    最近遇到一种问题 就是想要写一写C语言的代码 但是网页编辑器功能不全 GCC需要安装Liunx系统 VS又体量太大过于复杂 用keil又需要连接硬件 所以比较纠结 工作中通常使用的是Keil 但是如果有时不方便使用硬件 怎么办呢 所以就想着
  • vue3无限轮播案例

  • 【参加CUDA线上训练营】CUDA进阶之路 - Chapter 8 - CUDA流和CUDA工具库

    8 1 CUDA Stream 前面的章节只介绍了核函数在GPU内部的执行流程 忽略了CPU与GPU之间的交互过程 可以看出 CPU与GPU之间的交互涉及两个操作 数据传输和核函数执行 CPU将任务添加到不同的队列中 GPU驱动程序则负责执
  • AD原理图突然变灰,无法编辑了,快速恢复方法介绍!

    在使用AD18画原理图的时候 不知道触发了什么功能 导致整个原理图界面变成了灰色 怎么办 不怕 请看下文 下面是正常操作时候的界面 下面是异常界面 咨询同事后 同事表示经常遇到这种情况 他们认为是软件卡死了 关闭再重新打开即可 不过鄙人不这
  • python第六七天作业

    作业1 求第n项的斐波那契数列的值 n gt 1 def fbnq n if n lt 1 return 1 if 1 n or 2 n return 1 return fbnq n 1 fbnq n 2 def main n int in
  • MemCache详细解读

    MemCache是什么 MemCache是一个自由 源码开放 高性能 分布式的分布式内存对象缓存系统 用于动态Web应用以减轻数据库的负载 它通过在内存中缓存数据和对象来减少读取数据库的次数 从而提高了网站访问的速度 MemCaChe是一个
  • printf 和 println 是 Java 中用于输出的两种不同的方法

    以下为ChatGPT输出 printf 和 println 是 Java 中用于输出的两种不同的方法 它们之间有以下几点差异 格式控制 printf 方法允许你使用格式字符串来控制输出的格式 你可以指定变量的类型 字段宽度 精度等 而 pr
  • openwrt查看系统的芯片方案

    拿到一款路由器 想要知道主芯片的方案 可以通过如下方法 方法一 查看cpuinfo 比如 root IceCreamBox cat proc cpuinfo system type Ralink MT7620A ver 2 eco 3 ma
  • mybatis查询返回的对象不为null,但是属性值为null

  • 深度学习调参技巧

    深度学习调参技巧 一 寻找合适的学习率 learning rate 二 learning rate与batch size的关系 三 权重初始化 四 dropout 五 多模型融合 六 差分学习率与迁移学习 七 多尺度训练 八 Cross V