草庐IT

深度学习--超参数(持续更新)

Kevin404ar 2024-01-13 原文

目录

超参数(Hyperparameter)


一.模型参数和超参数的区别

  • 模型参数(Parameter):模型内部的配置变量,模型可以根据数据可以自动学习出的变量,自行根据数据进行驱动调整。
    比如,深度学习的权重,偏差等。
  • 超参数:也是机器学习算法中的调优参数(tuning parameters)或框架参数,模型外部的配置,不需要数据来驱动,而是在训练前或者训练中人为进行设定和调整,一般需要为它根据已有或现有的经验指定“正确”的值。超参数不同,模型是不同的

机器学习中一直说的“调参”,实际上不是调“参数”,而是调“超参数”。

 

二.分类

(一)网络参数

1.网络层与层之间的交互方式(相加、相乘或者串接等)

2.卷积核数量和卷积核尺寸

卷积核的核参数是模型参数

3.神经网络层数(也称深度)layers

3.1 深层神经网络隐藏层数

4.隐藏层神经元个数hidden units

5.输出神经元的编码方式

6.神经元激活函数

(二)优化参数

1.学习率α(learning rate)

1.1 学习因子下降参数(learning rate decay)

2.批样本数量(batch size)

(1)说明:

  • 一个大的batch,可以充分利用矩阵、线性代数库来进行计算的加速,batch越小,则加速效果可能越不明显
  • Batch太小还会导致更新进入局部最小值
  • Batch太大了,权重的更新就会不那么频繁,导致优化过程太漫长

(2)选取:

  • 根据数据集规模、设备计算能力去选取。
  • 因此,要采用一些可接受的(但不一定是最佳的)其他超参数值,然后尝试许多不同的小批量大小
  • 绘制准确度与时间的关系(这是实际运行时间,而不是循环次数)
  • 在快速的性能提升中选择最小的批量大小,之后可以继续优化其他超参数

3.不同优化器的参数

3.1 动量梯度下降算法参数: β \beta β
3.2 Adagrad算法参数: ε \varepsilon ε
3.3 Adadelta算法参数: β \beta β ε \varepsilon ε
3.4 Adam算法参数: β 1 \beta_{1} β1 β 2 \beta_{2} β2 ε \varepsilon ε

4.损失函数及其可调参数

(三)正则化参数

1.正则化系数η

增大η会导致更小的权值w,表示网络的复杂度更低;对数据的拟合较好,而在实际应用中,也验证了这一点。

2.权重衰减系数

3.丢弃法比率(dropout)

Dropout
通过修改NN中隐藏层的神经元个数来防止NN的过拟合

(四)其他

1.迭代次数epoch

No-improvement-in-n规则:

  • 在训练的过程中,记录最佳的validation accuracy
  • 当连续10次epoch(或者更多次)没达到最佳accuracy时,你可以认为“不再提高”,此时使用early stopping
  • n即epoch的次数,可以根据实际情况取10、20、30…

2.k近邻法中的k(最相近的点的个数)

3.k均值聚类中的簇数

4.决策树模型中树的数量和树的深度

5.矩阵分解中潜在因素的数量

6.聚类方法里面类的个数

7.话题模型里面话题的个数

8.参加训练模型的数据规模

方案:

  • 从数据源头采集更多数据
  • 复制原有数据并加上随机噪声
  • 重采样
  • 根据当前数据集估计数据分布参数,使用该分布产生更多数据
     

三.超参数调优

(一)优化原因

  • 本质上,这是模型优化寻找最优解和正则项之间的关系。网络模型优化调整的目的是为了寻找到全局最优解(或者相比更好的局部最优解),而正则项又希望模型尽量拟合到最优。两者通常情况下,存在一定的对立,但两者的目标是一致的,即最小化期望风险。模型优化希望最小化经验风险,而容易陷入过拟合,正则项用来约束模型复杂度。所以如何平衡两者之间的关系,得到最优或者较优的解就是超参数调整优化的目的。

为什么要做学习率调整?
学习率可以说是模型训练最为重要的超参数。通常情况下,一个或者一组优秀的学习率既能加速模型的训练,又能得到一个较优甚至最优的精度。过大或者过小的学习率会直接影响到模型的收敛。我们知道,当模型训练到一定程度的时候,损失将不再减少,这时候模型的一阶梯度接近零,对应Hessian 矩阵通常是两种情况:

  1. 正定,即所有特征值均为正,此时通常可以得到一个局部极小值,若这个局部极小值接近全局最小则模型已经能得到不错的性能了,但若差距很大,则模型性能还有待于提升,通常情况下后者在训练初最常见
  2. 特征值有正有负,此时模型很可能陷入了鞍点,若陷入鞍点,模型性能表现就很差

以上两种情况在训练初期以及中期,此时若仍然以固定的学习率,会使模型陷入左右来回的震荡或者鞍点,无法继续优化。所以,学习率衰减或者增大能帮助模型有效的减少震荡或者逃离鞍点。

 

(二)优化策略

1.照看(babysitting,又叫试错)

照看法被称为试错法或在学术领域称为研究生下降法。这种方法100%手动,遵循学习过程的所有步骤(从数据收集到特征图可视化),然后按顺序迭代超参数,直到耗尽时间或到截止日期或动机
 

2.自动化超参数搜索方法

说明:

  • 优秀的数据预处理
  • 合适的模型结构和功能
  • 优秀的训练策略和超参数
  • 合适的后处理操作
  • 严格的结果分析。AutoML的作用是帮助实现高效的模型构建和超参数调整
     
2.1 网格搜索/穷举搜索(grid search)

列出每个超参数的大致候选集合,利用这些集合进行逐项组合优化

  • 优点:效果较好
  • 缺点:计算时间会随着超参数的数量指数级的增长,效率低下

若有两类超参数,每类超参数有3个待探索的值,对它们进行笛卡尔积后得到9个超参数组合

 

2.2 随机搜索

对每个超参数定义一个分布函数来生成随机超参数

  • 优点:效率更高
  • 缺点:不保证一定能找到比较好的超参数
     

3.微调(fine-turn)

顾名思义指稍微调整参数即可得到优秀的性能

在小数据集上,通常微调的效果比从头训练要好很多,因为在于数据量较小的前提下,训练更多参数容易导致过度拟合

(1)方法:

  • 对最后的改动层使用较大的学习率,对未改动层以较小的学习率进行训练
  • 冻结除了顶部改动层以外的所有层参数

(2)微调为什么要先冻结底层,训练顶层?

  • 对顶层进行训练,可以防止顶层糟糕的初始化。
  • 越底层的特征通常是越通用的特征,越往上其整体的高层次语义越完备

(3)如何针对数据集选取微调的方法?

  • 数据和原数据集类似。只需修改最后的输出层,训练即可,训练过多参数容易过拟合
  • 数据和原数据集差异较大。可以在完成输出顶层的微调后,微调顶层往下一半的层数,进行微调
     

4.贝叶斯优化

 

(三)过程

  • 首先对搜索空间进行一个先验性的假设猜想,即假设一种选择超参的方式
  • 然后不断优化更新概率模型
  • 最终的目标是找到验证集上误差最小的一组超参数
     

(四)学习率调优

1.原因

学习率可以说是模型训练最为重要的超参数。通常情况下,一个或者一组优秀的学习率既能加速模型的训练,又能得到一个较优甚至最优的精度。过大或者过小的学习率会直接影响到模型的收敛。我们知道,当模型训练到一定程度的时候,损失将不再减少,这时候模型的一阶梯度接近零,对应Hessian 矩阵通常是两种情况:

  1. 正定,即所有特征值均为正,此时通常可以得到一个局部极小值,若这个局部极小值接近全局最小则模型已经能得到不错的性能了,但若差距很大,则模型性能还有待于提升,通常情况下后者在训练初最常见
  2. 特征值有正有负,此时模型很可能陷入了鞍点,若陷入鞍点,模型性能表现就很差

以上两种情况在训练初期以及中期,此时若仍然以固定的学习率,会使模型陷入左右来回的震荡或者鞍点,无法继续优化。所以,学习率衰减或者增大能帮助模型有效的减少震荡或者逃离鞍点
 

2.说明:

  • 其他超参数旨在提高测试集上的最终分类准确度,因此根据准确率选择它们。
  • 但是,学习率只是偶尔影响最终的分类准确性。
  • 它的主要目的是控制梯度下降中的步长,监测cost是检测步长是否过大的最佳方法。
  • 最后,训练早期阶段,高准确率往往意味着低差异,因此两者不会有太大差异。
     

3.自动调节:

  • 训练的过程中,记录最佳的accuracy,当连续10次epoch(或者更多次)没达到最佳accuracy时,可以认为“不再提高”
  • 可以选择让学习率减半(或1/10 ),让程序继续跑
  • 继续这个过程,直到learning rate变为原来的1/1024再终止程序
     

4.tensorflow调整策略

(1)exponential_decay

  • 指数衰减是最常用的衰减方式
  • 这种方式简单直接
  • 在训练初期衰减较大利于收敛,在后期衰减较小利于精调

(2)piecewise_constant

  • 分段设置学习率法
  • 可在不同阶段设置手动不同的学习率
  • 这种学习率重点在有利于精调

(3)polynomial_decay

  • 若power小于1,则是开1/power次方,为蓝色线;绿色线为power大于1
  • cycle决定是否在下降后重新上升的过程

 

5.差分学习(differential learning)

在训练期间为网络中的不同层设置不同的学习率的方法被称为差分学习


  • 前几个层通常会包含非常细微的数据细节,比如线条和边缘,不希望改变这些细节并倾向于保留它的信息
  • 相比之下,在后面的层中,比如图中绿色的层:我们可以获得嘴巴、鼻子等详细特征,不需要保留它们

说明:

  • 微调整个模型太昂贵,因为有些网络可能超过100层。因此,通常是一次对模型的一层进行微调
  • 但是,这要求具有顺序性,妨碍了并行性,并且需要多次通过数据集,导致过度拟合小数据集
  • 已经证明差分学习方法能够在各种NLP分类任务中提高准确度和降低错误率
     

四.重要性排序

(一)学习率α,损失函数上的可调参数

  • 学习率:最重要的超参数,直接控制着训练中网络梯度更新的量级,直接影响着模型的有效容限能力
  • 损失函数上的可调参数:这些参数通常情况下需要结合实际的损失函数来调整,大部分情况下这些参数也能很直接的影响到模型的的有效容限能力。

这些损失一般可分成三类,

  1. 辅助损失结合常见的损失函数,起到辅助优化特征表达的作用。例如度量学习中的Center loss,通常结合交叉熵损失伴随一个权重完成一些特定的任务。这种情况下一般建议辅助损失值不高于或者不低于交叉熵损失值的两个数量级
  2. 多任务模型的多个损失函数,每个损失函数之间或独立或相关,用于各自任务,这种情况取决于任务之间本身的相关性
  3. 独立损失函数,这类损失通常会在特定的任务有显著性的效果。例如RetinaNet中的focal loss,其中的参数γ,α,对最终的效果会产生较大的影响。这类损失通常论文中会给出特定的建议值
     

(二)批样本数量,动量优化器的动量参数β

  • 批样本数量(batch size):批样本决定了数量梯度下降的方向。
  1. 过小的批样本数量,极端情况下,例如batch size为1,即每个样本都去修正一次梯度方向,样本之间的差异越大越难以收敛。若网络中存在批归一化(batchnorm),batch size过小则更难以收敛,甚至垮掉。这是因为数据样本越少,统计量越不具有代表性,噪声也相应的增加
  2. 过大的批样本数量,会使得梯度方向基本稳定,容易陷入局部最优解,降低精度
  3. 一般参考范围会取在[1:1024]之间,当然这个不是绝对的,需要结合具体场景和样本情况
  • 动量优化器(Gradient Descent with Momentum)的动量衰减参数β:计算梯度的指数加权平均数,并利用该值来更新参数,设置为 0.9 是一个常见且效果不错的选择
     

(三)网络参数,Adam优化器的超参数,权重衰减系数,丢弃法比率

这些参数重要性放在最后并不等价于这些参数不重要。而是表示这些参数在大部分实践中不建议过多尝试

  • 网络参数:通常情况下增加网络层数能增加模型的容限能力,但模型真正有效的容限能力还和样本数量和质量、层之间的关系等有关,所以一般情况下会选择先固定网络层数,调优到一定阶段或者有大量的硬件资源支持可以在网络深度上进行进一步调整
  • Adam优化器的超参数:Adam优化器中的β1,β2,ϵ,常设为 0.9、0.999、10−8就会有不错的表现
  • 权重衰减系数:通常会有个建议值,例如0.0005,使用建议值即可,不必过多尝试
  • 丢弃法比率(dropout):通常会在全连接层之间使用防止过拟合,建议比率控制在[0.2,0.5]之间

使用dropout时需要特别注意两点:

  1. 在RNN中,如果直接放在memory cell中,循环会放大噪声,扰乱学习。一般会建议放在输入和输出层
  2. 不建议dropout后直接跟上batchnorm,dropout很可能影响batchnorm计算统计量,导致方差偏移,这种情况下会使得推理阶段出现模型完全垮掉的极端情况
     

五.部分超参数合适的范围

超参数建议范围注意事项
卷积核尺寸[7x7],[5x5],[3x3],[1x1],[7x1,1X7]
初始学习率SGD:[1e-2, 1e-1]
momentum:[1e-3, 1e-2]
Adagrad:[1e-3, 1e-2]
Adadelta:[1e-2, 1e-1]
RMSprop:[1e-3, 1e-2]
Adam:[1e-3, 1e-2]
Adamax:[1e-3, 1e-2]
Nadam:[1e-3, 1e-2]
这些范围通常是指从头开始训练的情况。若是微调,初始学习率可在降低一到两个数量级
批样本数量[1,1024]当批样本数量过大(大于6000)或者等于1时,需要注意学习策略或者内部归一化方式的调整
损失函数部分超参数多个损失函数之间,损失值之间尽量相近,不建议超过或者低于两个数量级这是指多个损失组合的情况,不一定完全正确。单个损失超参数需结合实际情况
权重衰减系数[0, 1e-4]
丢弃法比率[0, 0.5]

以上未完待更新,仅供个人学习,侵权联系删除,如有错误或不足之处可指出,以便改进。

有关深度学习--超参数(持续更新)的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  3. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  4. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  5. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  6. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  7. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  8. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  9. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  10. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

随机推荐