此文整理总结github上的一个资料,结尾附上链接。对于工程应用很有现实参考,带入实际工作场景中会有不少的收获。
这份文档旨在帮助工程师和研究人员系统性地优化深度学习模型的性能。它涵盖了从项目启动到模型部署的各个环节,包括:
总而言之,这份文档提供了一个全面且实用的指南,帮助深度学习从业者有效地优化模型性能,并提高工作效率。
总结: 从成熟的模型架构开始,并根据需求进行调整。
建议:
总结: 从针对手头问题类型的最常用的优化器开始。
建议:
总结: BatchSize 决定训练速度,并且不应该被直接用于调整验证集性能。通常来说,可用硬件支持的最大
Batch Size 是较为理想的数值。
原因:
选择 BatchSize 的步骤:
总结: 在开始超参数调整之前,必须确定起点。这包括指定 模型配置(例如层数),优化器超参数(例如学习率),以及训练步数。
原则:
机器学习开发的最终目标是最大化模型的效用。尽管不同应用场景的开发流程有所不同(例如时间长度、可用计算资源、模型类型等),基本步骤和原则都是相似的。
接下来的指南中我们做出了这些假设:
总结:从简单的配置开始,循序渐进,同时进一步了解问题。确保任何改进都有据可循,以避免增加不必要的复杂度。我们的最终目标是找到一种训练配置来最大化我们模型的性能。
综上所述,我们的增量调优策略需要重复以下四个步骤:
本节的其余部分将更详细地讲解增量调优策略
总结:大多数时候,我们的目标是更深入地理解问题。
- 避免仅因历史原因而表现良好的不必要更改。
- 确定验证集效果对哪些超参数最敏感,哪些超参数交互最多,因此需要一起重新调整,以及哪些超参数对其他变化相对不敏感,因此可以在未来的实验中固定住。
- 发现潜在的新方向,例如在出现过拟合问题时使用新的正则化器。
- 确定无效的方向并将其删除,从而降低后续实验的复杂度。
判断超参数的优化空间是否已经饱和。- 围绕最佳值缩小我们的搜索空间,以提高调整效率。
最终,我们可以集中提升验证集效果,即便我们无法从新的实验中进一步了解问题的结构了。
总结:根据实验目标,将超参数分为三类:目标超参数、冗余超参数和固定超参数。创建一系列研究以比较
目标超参数的不同值,同时优化冗余超参数。注意选择冗余超参数的搜索空间,以平衡资源成本与科学价值。
对于给定的目标,所有超参数都将是目标超参数、冗余超参数或固定超参数。
举个例子,如果我们的目标是 “确定更深的模型是否会减少验证集错误”,那么模型层数就是目标超参数。
学习率是一个冗余超参数,如果我们要公平对比不同深度的模型,我们必须分别调整学习率(通常情况下最优学习率和模型结构有关)。
激活函数是一个固定超参数。我们可能通过过去的实验发现最优激活函数和模型深度无关。或者我们接受实验得到的最优深度的仅在某个激活函数上有效。或者我们也可以将激活函数作为一个冗余超参数和深度一起调优。
一个超参数是目标超参数、冗余超参数还是固定超参数是根据实验目标来决定的。
比如,激活函数的选择可以是一个目标超参数(对于当前问题,ReLU 或 tanh 是更好的选择吗?),一个冗余超参数(允许使用不同的激活函数,最好的 5 层模型是否优于最好的 6 层模型?),或一个固定超参数(对于一个由 ReLU 构成的网络,在特定位置添加批标准化是否有帮助?)。
在设计新一轮实验时,我们根据实验目的确定目标超参数。
- 如果有无限的计算资源,我们会将所有非目标超参数保留为冗余超参数,这样我们从实验中得出的结论就不会受到固定超参数的限定。
- 然而,冗余超参数越多,我们没能充分针对每个目标超参数调优冗余超参数的风险就越高,从而我们从实验中得出错误结论的风险也越高。
- 如下文所述,我们可以通过增加计算资源来应对这种风险,但通常我们的最大资源预算低于调整所有非目标超参数所需的计算资源。
- 当我们判断将一个冗余超参数转换为固定超参数所带来的限制少于调优它所需的计算资源时,我们可以进行这种转换。
一个冗余超参数和目标超参数的相互影响越多,固定这个参数所带来的限制就越多。例如,权重衰减强度的最佳值通常取决于模型大小,因此固定权重衰减的强度来比较不同的模型大小,往往得不出有效的结论。
尽管超参数的类型取决于实验目标,但对于某些类别的超参数,我们有以下经验法则:
- 它们很少是目标超参数,因为像 “训练流程的最佳学习率是多少?” 这样的目标没有什么意义——最优学习率很容易随着下一次训练流程的改变而改变。
- 尽管当资源有限或有强力的证据表明它们不影响目标超参数时,我们可能固定其中一些参数,但通常应该假设优化器超参数必须单独调整,以在不同设置之间进行公平比较目标超参数。
- 如果我们的实验目标涉及在两个或多个不同的优化器之间进行公平比较(例如 “确定哪个优化器在给定的步数中产生最低的验证错误”),那么它就是一个目标超参数。
- 或者,我们可能出于各种原因将其设为固定超参数,包括(1)先前的实验表明最好的优化器和当前的目标超参数无关;(2)当前优化器的训练曲线更容易理解 (3) 当前优化器比其他优化器使用更少的内存。
例如,dropout 增加了代码的复杂性,因此在决定是否包含它时,我们会将 “no dropout” 与 “dropout”作为一个目标超参数,而将 dropout 率作为一个冗余超参数。
如果我们决定根据这个实验将 dropout 添加到我们的训练流程中,那么在未来的实验中,dropout率将是一个冗余超参数。
例如,网络层数通常是一个目标或固定的超参数,因为它往往会对训练速度和内存使用产生巨大影响。
- 例如,假设我们想知道 Nesterov momentum 和 Adam 中哪个优化器的验证错误率更低。目标超参数是optimizer,它的值是 {“Nesterov_momentum”, “Adam”}。值 optimizer=“Nesterov_momentum” 引入了冗余/固定超参数 {learning_rate, momentum},但值 optimizer=“Adam” 引入了冗余/固定超参数 {learning_rate, beta1, beta2, epsilon}。
- 仅针对目标超参数的某些值存在的超参数称为条件超参数。
- 我们不应该仅仅因为两个条件超参数具有相同的名称就认为它们是相同的!在上面的示例中,learning_rate对optimizer=“Nesterov_momentum” 与 optimizer=“Adam” 是不同的条件超参数. 它在两种算法中的作用相似(尽管不完全相同),但在每个优化器中运行良好的值范围通常相差几个数量级。
- 一项研究指定了一组要运行的超参数配置以供后续分析。每个配置称为 “试验”
- 创建研究通常涉及几个方面:选择试验所需的超参数变量,选择这些超参数的取值范围(“搜索空间”),选择试验次数,以及选择自动搜索算法。或者,我们可以通过手动指定一组超参数配置来创建研究。
- 例如,如果我们的目标是从 Nesterov、momentum 和 Adam 中选择最佳优化器,我们可以创建一个研究,并设置 optimizer=“Nesterov_momentum” 和冗余超参数为 {learning_rate, momentum}。然后创建另一项研究,并设置 optimizer=“Adam” 和冗余超参数为 {learning_rate, beta1, beta2,epsilon}。最后通过比较两个研究中的最优试验来比较这两个优化器。
- 我们可以使用任何无梯度优化算法,包括贝叶斯优化或进化算法等方法,来优化冗余超参数。但是,在探索阶段,我们更偏向使用准随机算法,因为这些方法在探索阶段有多种优势。在探索结束后,我们会优先选择最先进的贝叶斯优化方法。
- 采用这种方法时,条件超参数可能会是一个问题,因为很难指定对应的搜索空间,除非所有目标超参数值都有相同的冗余超参数集。
- 在这种情况下,我们更加偏好使用 Quasi-Random-Search 算法,因为它确保我们能相对均匀的采样目标超参数值。无论搜索算法如何,我们都需要确保它均匀搜索目标超参数。
在设计一项研究或一系列研究时,我们需要分配有限的预算,以充分满足以下三个要求:
- 比较足够多目标超参数的不同值。
- 在足够大的搜索空间上调整冗余超参数。
- 对冗余超参数的搜索空间进行足够密集的采样。
这三个必要条件,确保我们能从实验中获得足够多的经验。
总结:除了尝试实现每组实验的原始科学目标之外,还要检查其他问题的清单,如果发现问题,请修改实验并重新运行。
然而,如果我们提出正确的问题,我们通常会发现在一组给定的实验能够朝着最初的目标取得很大进展之前需要纠正的问题。如果我们不问这些问题,我们可能会得出不正确的结论。
由于运行实验的成本很高,我们还希望借此机会从每组实验中提取其他有用的见解,即使这些见解与当前目标并不直接相关。
- 搜索空间够大吗?
- 我们是否从搜索空间中采样了足够多的点?
- 每项研究中有多少试验是不可行(即出现分歧的试验、得到非常糟糕的损失值,或者因为违反某些隐式约束而根本无法运行)?当研究中很大一部分点是不可行时,我们应该尝试调整搜索空间以避免对这些点进行采样,这有时需要重新参数化搜索空间。在某些情况下,大量不可行点可能表示训练代码中存在错误。
- 模型是否存在优化问题?
- 我们可以从最佳试验的训练曲线中学到什么?例如,最好的试验是否具有与有问题的过度拟合一致的训练曲线?
一旦我们回答了上述问题,我们就可以继续评估实验为我们最初的目标提供的证据(例如,评估改变是否有用)。
有两种类型的工作模式:受计算限制的和不受计算限制的。
在这种情况下,如果我们能以某种方式延长训练时间或提高训练效率,我们应该看到较低的训练损失,并且通过适当的调整,改善验证损失。换句话说,加快训练速度就等于改善训练效果,而” 最佳” 训练时间总是” 我们愿意等待的时间” 范围内。
然而,当工作模式受计算限制时,并不意味我们只能通过更长/更快的训练来改善结果。
不管一个给定的工作负载是否是计算约束,使用增加梯度方差(跨Batch)的方法通常会导致较慢的训练进度,从而可能增加达到特定验证损失所需的训练步骤。高梯度方差可能是由以下原因造成的。 使用了较小的Batch Size、使用了数据增强技术、添加了一些类型的正则化(例如dropout)
- 通过运行更多的短时间的实验,我们可以更快地找到最佳的模型和优化器超参数,而不必浪费大量的计算资源和时间在不优秀的超参数上。最后,我们可能会运行少量的长时间(”production length” 指模型在生产环境中运行的时间, 也就是预期的长时间训练) 的实验来在最佳超参数点上获得最终模型。这样,我们就可以更有效地使用我们的资源来调整最有可能在生产环境中表现良好的模型。
- 我们的训练时间越长,我们对模型的理解就会越深入,这样我们就可以更好的了解模型的性能和限制,因此我们可以更确定哪些参数是最有可能在生产环境中表现良好的参数。但是,当我们的训练时间越长,我们能完成的实验就会越少,因为我们的耐心和计算资源有限。
- 当我们只训练~10% 的production length 时,我们可能能够回答很多问题,但是在这个时间限制下的结论不一定适用于20% 的production length 的实验,更不用说100% 了。这是因为训练模型的时间越长,模型就会越来越接近其最佳性能,而在较短的训练时间内得出的结论可能不能完全适用于长时间训练后的模型。
- 我们可以想做多少轮就做多少轮,但通常1-3 轮是最实用的。
- 从本质上讲,在进行调整时要在两个方面进行平衡:相关性和彻底性。相关性指的是调整结果与最终长时间运行之间的相似性,而彻底性则指调整结果的详尽程度。因此,在进行调整时,我们应该尽量使用快速转换时间的试验来获得尽可能多的问题理解,同时保证这些结论与最终长时间运行相关。这样可以在有限的时间和资源内获得最大的理解,并尽可能地减少对最终长时间运行的影响。
- 一旦给定的每次试验时间限制中产生了有用的见解,我们就可以增加训练时间并继续调整,以确保它们在长时间运行中仍然适用。
- 第一轮:进行短时间的训练来找到较佳的模型和优化器超参数
- 第二轮:在较佳的超参数上进行少量长时间的训练来得到最终模型 从Round i → Round i+1 的最大问题是如何调整学习率衰减计划。在进行调整时,最大的问题是如何调整学习率衰减计划。在调整学习率衰减计划时的一个常见问题是使用了太小的学习率,如果学习率过小,模型的收敛速度会变慢,可能会需要更多的训练步骤才能达到最优状态。这可能会增加训练时间并增加计算资源的需求。
遗憾的是,在短时间和不完整训练中找到的超参数在增加训练长度后仍然是好选择的保证是没有的。但是,对于某些类型的超参数,它们通常具有足够的相关性,因此第一轮非常有用。
我们期望在短运行中找到的哪些超参数值会转移到更长的训练运行中?对于这一切,我们需要更多的研究。但是根据已有的结论我们可以提出一些猜测,以下是作者的猜测,按转移概率的降序排列:
- 极有可能转移
在第一轮调参中,使用较少的训练步数可以解决早期训练的不稳定性。也许这些超参数是最能保证转移的选择。- 可能转移
模型架构- 模型架构上的显著胜利通常会转移,但可能有很多例外。- 可能会转移
- 优化算法/优化器超参数—我们认为这将” 松散” 转移。它明显比上面的东西弱。
- 数据增强方法
- 正则化:如果不可能完美地拟合训练集,则模型可能处于正则化不太可能有太大的帮助。
- 不太可能转移
学习率衰减计划:不太可能完美迁移。
例如,如果是线性计划,则保持第一轮中衰减大小的固定值,并在开始时延长恒定的lr 期。 对于余弦衰减,只需保留第一轮的基础lr 并增大max_train_steps。
总结:输入管道性能受限的原因及干预措施与具体任务高度相关,使用性能分析工具并注意常见的一些问题。
- 数据未与训练进程存放在同一位置,从而导致I/O 延迟(通过网络读取训练数据时可能会发生这种情况)。
- 昂贵的在线数据预处理(考虑进行一次性离线预处理并保存)。
- 无意间的同步屏障干扰数据管道预读取。例如,在CommonLoopUtils(link) 中同步设备和主机之间的数据时。
- 例如使用tf.data.Dataset.prefetch 之类的工具对输入管道预读取数据。
- 尽可能早地在管道中删除不必要的特征和元数据。
- 通过使用tf.dataservice 来增加输入管道生成数据的进程的数量。
总结:使用比训练时更大的batch size 进行评估。在固定步长间隔进行评估,而不是固定的时间间隔。(注:如100 个epoch 评估一次,而不是10 分钟评估一次)。
我们可以通过多种方式来评估模型的性能。
- 样本量
- 确保定期作业使用的采样数据集的性能与整个离线评估集的性能相似,确保采样集与完整数据集之间没有偏差。
- 用于定期评估的数据集应该足够小,以便很容易生成整个模型的预测,但也应该足够大,以便可以准确地测量模型的改进(即不被大量标签噪声影响)。
- 它应该足够大,以适应顺序试验中的多个这样的评估,并仍然产生准确的估计。也就是说,避免在多轮评估中对验证集过度适应,从而影响模型对留出集的表现。然而,这种考虑很少是一个实际的问题。
- 不平衡的数据集
- 对于不平衡的数据集,在稀有类别样本上的表现往往会有噪音。
- 对于每个类别只有少量样本的数据集,记录正确预测样本的数量,可以更深入地了解准确性改进
总结:运行固定步长的训练,并回顾性地从中选择最佳检查点。
总结:在跟踪不同的实验时,一定要注意一些要点,比如研究中检查点的最佳性能,以及对研究的简短描述。
实验名称
实验配置存储位置的链接
实验的注释或简短描述
运行次数
最佳模型在验证集上的表现
训练所需的配置和运行命令
总结:在日志记录、评估、RNG(随机数生成器)、检查点和数据分片方面,多主机训练非常容易引入错误!
这是一个开放性问题。目前尚不清楚如何构建一组严格的实验来自信地回答最佳的LR 衰减方案是什么。
虽然我们不知道最好的方案是什么,但我们相信尝试一些(非恒定的)方案很重要并且调整它很重要。
在优化过程中,不同的学习率在不同的时间效果最好。有某种衰减方案可以使模型更有可能达到良好的学习率。
我们的偏好是linear decay 或cosine decay,其他一些方案可能也不错。
正如之前讨论的那样, 对搜索空间以及应该从搜索空间中采样数量做出概括性陈述是非常困难的。请注意,并非Adam 中的所有超参数都一样重要。以下经验法则对应于研究中试验次数的不同“预算”。
如果在一次研究中,训练次数试验次数小于10,那么只需要对基本学习率进行调整
如果试验次数在10 到25 次之间,那么需要对学习率以及β1 进行调整。
如果试验次数在25 次以上,那么需要对学习率、β1 以及ϵ 进行调整。
如果可以运行的试验次数大于25 次,还需要额外调整β2。
总结:如果在优化模型时遇到困难,那么在尝试其他东西之前解决这些问题很重要。诊断和纠正训练失败是一个活跃的研究领域。
初始化/训练早期中存在的不稳定。
训练中期突然出现的不稳定。
进行一次学习率扫描(不考虑学习率衰减的固定学习率),并找到最佳的学习率lr*.
绘制学习率略高于lr* 的训练损失曲线。
如果学习率大于lr* 的训练损失曲线显示不稳定(误差在训练期间上升而不下降),那么修复不稳定性可能会得到更好的训练结果(说明我们最佳的学习率比较临界)。
注意:某些模型会在非常早期的阶段显示出不稳定的情况,随后出现恢复,这会导致出现缓慢但稳定的训练(这可能会成为问题)。为了检查出这一问题,我们可以使用lr = 2 * current best 来进行一次仅包含500 次训练的计划,但每执行一次训练都要进行一次评估。
对于早期和中期训练中不稳定情况都有好处,可能会解决一些学习率预热无法解决的问题。
例如,如果模型中尚未包含残差连接和归一化,则添加它们。 归一化应该是残差之前的最后一个操作。例如,x +Norm(f(x))。
在warmup_steps 的过程中,将数值从0 提升到base_learning_rate。post_warmup_steps 的过程中,以一个恒定的速率进行训练。
因此,对于,每个base_learning_rate 来说,我们需要对warmup_steps 以及post_warmup_steps 进行调优。通常将post_warmup_steps 设定为warmup_steps 的两倍就可以了。
warmup_steps 应该以几个不同的数量级进行扫描。例如,在样本学习中可以以[10, 103, 104,105] 这样的数量级进行尝试。最大的搜索值不应超过max_train_steps 的10%。
如果梯度范数|g| 大于梯度截断的阈值λ,那么就需要进行g′ = λ × g 。此处的g′ 是新的梯度。
梯度范数与步骤数量的关系图
聚合所有步数的梯度范数直方图
欢迎点赞,收藏,关注,支持小生,打造一个好的遥感领域知识分享专栏。
同时欢迎私信咨询讨论学习,咨询讨论的方向不限于:地物分类/语义分割(如水体,云,建筑物,耕地,冬小麦等各种地物类型的提取),变化检测,夜光遥感数据处理,目标检测,图像处理(几何矫正,辐射矫正(大气校正),图像去噪等),遥感时空融合,定量遥感(土壤盐渍化/水质参数反演/气溶胶反演/森林参数(生物量,植被覆盖度,植被生产力等)/地表温度/地表反射率等反演)以及高光谱数据处理等领域以及深度学习,机器学习等技术算法讨论,以及相关实验指导/论文指导等多方面。
参考:
遥感图像处理专栏
深度学习调参