训练吞吐量 =每秒处理的样本数量
124 | 125 |或者,我们可以估计每步时间 :
126 | 127 |每步时间 =(Batch Size)/(训练吞吐量)
128 | 129 | - 当加速器内存未饱和时,如果Batch Size加倍,训练吞吐量也应该加倍(或至少接近加倍)。等效地,随着Batch Size的增加,每步的时间应该是恒定的(或至少接近恒定的)。 130 | - 如果与上述情况不符,那么训练工作流可能存在瓶颈,例如 I/O 或计算节点间的同步。有必要在开始下一步前对此进行诊断和矫正。 131 | - 如果训练吞吐量到某个Batch Size之后就不再增加,那么我们只考虑使用该Batch Size(即使硬件支持更大的Batch Size) 132 | - 使用更大Batch Size的所有好处都假定训练吞吐量增加。如果没有,请修复瓶颈或使用较小的Batch Size。 133 | - 使用**梯度积累**技术可以支持的更大的Batch Size。但其不提供任何训练吞吐量优势,故在应用工作中通常应避免使用它。 134 | - 每次更改模型或优化器时,可能都需要重复这些步骤(例如,不同的模型架构可能允许更大的Batch Size)。 135 | 136 |训练时间 =(每步时间)x(总步数)
144 | 145 | - 对于所有可行的Batch Size,我们通常可以认为每步的时间近似恒定(实际上,增加Batch Size通常会产生一些开销)。 146 | - Batch Size越大,达到某一性能目标所需的步数通常会减少(前提是在更改Batch Size时重新调整所有相关超参数;[Shallue et al. 2018](https://arxiv.org/abs/1811.03600))。 147 | - 例如,将Batch Size翻倍可能会使训练步数减半。这称为**完美缩放**。 148 | - 完美缩放适用于Batch Size在临界值之前,超过该临界总步数的减少效果将会下降。 149 | - 最终,增加Batch Size不会再使训练步数减少(永远不会增加)。 150 | - 因此,最小化训练时间的Batch Size通常是最大的Batch Size,也同时减少了所需的训练步数。 151 | - Batch Size取决于数据集、模型和优化器,除了通过实验为每个新问题找到它之外,如何计算它是一个悬而未决的问题。🤖 152 | - 比较Batch Size时,请注意效果(epoch)预算(运行所有实验,固定训练样本的数量达到设定的效果所花的时间)和步数预算(运行设定步数的试验)之间的区别。 153 | - 将Batch Size与效果预算进行比较只会涉及到完美缩放的范围,即使更大的Batch Size仍可能通过减少所需的训练步数来提供有意义的加速。 154 | - 通常,可用硬件支持的最大Batch Size将小于临界Batch Size。因此,一个好的经验法则(不运行任何实验)是使用尽可能大的Batch Size。 155 | - 如果最终增加了训练时间,那么使用更大的Batch Size就没有意义了。 156 | 157 |
399 |
400 |
401 |
图 1:不良的搜索空间边界和可接受的搜索空间边界示例。
407 | 408 | - [Figure 1](#figure-1)中的图表显示错误率(越低越好)与初始学习率的关系。 409 | - 如果最佳点聚集在搜索空间的边缘(在某个维度上),则可能需要扩展搜索空间边界,直到最佳观察点不再靠近边界。 410 | - 通常,一项研究将包括“不可行”的试验,这些试验会产生分歧或得到非常糟糕的结果(在上图中用红色 X 标记)。 411 | - 如果所有试验对于大于某个阈值的学习率都是不可行的,并且如果表现最好的试验在该区域的边缘具有学习率,则模型[可能遇到了稳定性问题,从而无法获得更高的学习率](#how-can-optimization-failures-be-debugged-and-mitigated)。 412 | 413 |
471 |
472 |
图 2:研究在 ImageNet 上训练的 ResNet-50 的最佳权重衰减值的isolation图。
478 | 479 | - 通常,一组实验的目标是比较目标超参数的不同值。 480 | - 例如,我们可能想要确定导致最佳验证误差的权重衰减值。 481 | - **isolation图**是基本超参数轴图的特例。isolation图上的每个点对应着在优化某些(或全部)冗余超参数上最佳试验的性能。 482 | - 换句话说,我们绘制了在"优化掉"冗余超参数后模型的性能。 483 | - isolation图可以更轻松地在目标超参数的不同值之间进行同类比较。 484 | - 例如,[图2](#图2)显示了在ImageNet上训练的ResNet-50的特定配置(学习率)下产生最佳验证性能的权重衰减值。 485 | - 如果我们的目标是确定是否要加入权重衰减,那么我们会将此图中的最佳点与没有权重衰减的Baseline进行比较。为了公平比较,Baseline的学习率也应该同样得到很好的调整。 486 | - 当我们正在考虑为一个连续的超参数来绘制isolation图时,并且我们是使用Quasi-Random-Search(近似随机搜索)产生的超参数的不同值时,我们可以通过对基本超参数轴图的X轴值进行分桶,并在分桶定义的每个垂直切片中取最佳试验来近似绘制隔离图。 487 | 488 |
855 |
856 |
Figure 3: ResNet-50 在 ImageNet 上进行了 100 次试验调整。 通过自举,模拟了不同数量的调整预算。 上面绘制了每个试验预算的最佳性能的箱线图。 859 | 860 | - 这个问题没有办法笼统地回答,但是我们可以看具体的例子。 861 | - 正如Figure 3所示那样, 研究中的试验次数会对结果产生重大影响。 862 | - 请注意,当对6个试验进行抽样时,与对20个试验进行抽样时的四分位间距有多大的区别。 863 | - 即使进行了20次试验,运气特别好和运气特别差的研究之间的差异也可能大于使用固定超参数在不同随机种子上重新训练该模型之间的典型差异,对于此工作量可能约为 +/- 0.1% 的验证误差的概率约为 23%。 864 | 865 |
874 |
875 |
Figure 4: 在 WideResnet 中更改单个残差块 (2x2 -> 1x1) 中的步幅会导致训练不稳定。 这不会降低在低学习率下的性能,但由于不稳定的影响,高学习率不再能很好地进行训练。 使用1000步的学习率预热可以解决这种特殊的不稳定情况,允许以 0.1 的最大学习率进行稳定训练。
879 | 880 | #### 识别不稳定的训练任务 881 | 882 | - 当学习率过大时,任何训练任务都会变得不稳定,但当不稳定迫使我们使用太小的学习率时,这才会是问题 883 | - 这里至少有两种类型的不稳定的训练任务值得需要进行区分: 884 | 1. 初始化/训练早期中存在的不稳定。 885 | 2. 训练中期突然出现的不稳定。 886 | - 我们可以采用系统的方法来找出训练任务中存在的稳定性问题. 887 | 1. 进行一次学习率扫描(不考虑学习率衰减的固定学习率),并找到最佳的学习率 lr*. 888 | 2. 绘制学习率略高于 lr* 的训练损失曲线。 889 | 3. 如果学习率大于 lr* 的训练损失曲线显示不稳定(误差在训练期间上升而不下降),那么修复不稳定性可能会得到更好的训练结果(说明我们最佳的学习率比较临界)。 890 | - 在训练过程中记录全损失梯度的 L2 范数的变化(全损失梯度的 L2 范数是指在深度学习中,对于每个参数的梯度进行平方并相加后再取平方根的过程,反映了损失函数在当前状态下沿着梯度方向的变化程度。当前状态下的梯度向量越大,说明当前状态下的模型参数需要更大的更新量才能更好的逼近最优解),如果我们发现全损失梯度的 L2 范数异常值非常大,这可能表明模型参数在某一时刻发生了非常大的变化,导致训练过程中出现不稳定性(例如误差上升而不下降)。 这可以告诉我们该如何选择梯度/更新剪辑。 891 | 892 | **注意:** 某些模型会在非常早期的阶段显示出不稳定的情况,随后出现恢复,这会导致出现缓慢但稳定的训练(这可能会成为问题)。 **常见的评估方法可能会因为评估不够频繁而错过这些问题!** 893 | 894 | 为了检查出这一问题,我们可以使用 `lr = 2 * current best` 来进行一次仅包含500次训练的计划,但每执行一次训练都要进行一次评估。 895 | 896 |
897 |
899 |
Figure 5: 该图展示的是训练开始时频繁更新评估的结果。如果怀疑模型受到早期训练不稳定的影响,则很有用。
902 | 903 | #### 常见不稳定模式的潜在修复方式 904 | 905 | - 使用学习率预热 906 | - 最适合用于早期训练不稳定的情况。 907 | - 使用梯度截断 908 | - 对于早期和中期训练中不稳定情况都有好处,可能会解决一些学习率预热无法解决的问题。 909 | - 尝试使用新的优化器 910 | - Adam 有时可以处理一些 Momentum 无法处理的不稳定影响。这也是该领域的一个活跃研究领域。 911 | - 确保使用最佳实践/初始化: 912 | - 例如,如果模型中尚未包含残差连接和归一化,则添加它们。 913 | - 归一化应该是残差之前的最后一个操作。例如, x +Norm(f(x))。 914 | - 众所周知,Norm(x + f(x)) 会引起问题。(译注:Norm相当于白化,意在降低层参数的训练敏感性,而残差大大增加了训练参的敏感性,所有在残差前的f(x)归一化有助于降低不稳定性) 915 | - 尝试将残差调控因子初始化为 0 (例如,[ReZero init所示](https://arxiv.org/abs/2003.04887))$\boldsymbol{x}_{i+1}=\boldsymbol{x}_i+\alpha_i F\left(\boldsymbol{x}_i\right)$. 916 | - 降低学习率 917 | - 这是最终手段。 918 | 919 | #### 学习率预热 920 | 921 |
922 |
924 |
Figure 6: 预热期间不稳定的示例(注意横轴的刻度是以对数的形式展示)。 在这种情况下,成功训练需要4万次的预热。
926 | 927 | 928 | ##### 何时对学习率进行预热 929 | 930 |
931 |
932 |
Figure 7a: 表现出训练不稳定性的模型的超参数轴图示例。 最佳学习率处于可行的边缘。 “不可行”试验被定义为产生 NaN 或异常高的损失值的试验。
935 | 936 |
937 |
938 |
Figure 7b: 模型训练损失中不稳定的学习率
941 | 942 | - Figure 7a 展示的是一个超参数轴图,该图表明模型正在经历训练不稳定,因为最佳学习率恰好位于可行的边缘。 943 | - Figure 7b展示了以5-10倍的峰值学习率来训练模型中产生的训练损失是如何通过双重检查的。如果该图展示的训练损失在稳步下降后突然上升(例如,如图中10000步处展示的那样),那么该模型可能存在着优化不稳定性的情况。 944 | ##### 如何对学习率进行预热 945 | 946 |
947 |
948 |
Figure 8: 学习率预热对解决训练不稳定性的有益影响
951 | 952 | - 在上面的内容中,我们假设从业者已经确定了让模型变得不稳定的学习率。也就是 `unstable_base_learning_rate`。 953 | - 预热的过程涉及了预先安排一个学习率计划,这个计划会将学习率从0提升到某个稳定的 `base_learning_rate`,这至少比 `unstable_base_learning_rate`要大一个数量级。 954 | 默认设置是尝试使用 `unstable_base_learning_rate` 10倍大小的 `base_learning_rate`。值得注意的是,对于使用例如100倍 955 | `unstable_base_learning_rate`这样的数值,那么可能需要重新运行整个过程。具体安排如下: 956 | - 在`warmup_steps`的过程中,将数值从0提升到 `base_learning_rate`。 957 | - `post_warmup_steps`的过程中,以一个恒定的速率进行训练。 958 | - 我们的目标是找到最少的 `warmup_steps`,以此来让我们获得远高于`unstable_base_learning_rate`的峰值学习率。 959 | - 因此,对于,每个 `base_learning_rate`来说, 我们需要对 `warmup_steps` 以及`post_warmup_steps`进行调优。 通常将 `post_warmup_steps` 设定为`warmup_steps`的两倍就可以了。 960 | - 预热可以独立于现有的衰减计划进行调整。 961 | `warmup_steps` 应该以几个不同的数量级进行扫描。例如,在样本学习中可以以[10, 103, 104,105]这样的数量级进行尝试。最大的搜索值不应超过`max_train_steps`的10%。 962 | - 一旦建立了不会破坏以 `base_learning_rate` 进行训练的`warmup_steps`,就应该将其应用于Baseline模型。 963 | 本质上,我们将这个安排添加到现有安排上,并使用上面讨论中选择的最佳检查点来将这个实验与Baseline进行比较。例如,如果我们一开始的`max_train_steps`的值是10000, 964 | 并进行了1000次`warmup_steps`。那么,新的训练过程总共应当进行了11000次。 965 | - 如果稳定训练需要较长的`warmup_steps`(大于`max_train_steps`的5%),则可能需要增加`max_train_steps`来解决这个问题。 966 | - 在整个工作量的范围中并不存在真正意义上的`标准`值。有些模型可能只需要100次训练,然而有些模型则可能需要4万次以上的训练,尤其是Transformer类。 967 | 968 | #### 梯度截断 969 | 970 |
971 |
972 |
Figure 9: 梯度截断纠正早期训练不稳定性的图示。
975 | 976 | - 当出现较大或离群的梯度问题时,梯度截断会变得非常有用。 977 | - 梯度截断可以修复早期训练中出现的不稳定性(早期较大的梯度范数),或中期训练中出现的不稳定性(训练中期突然出现的梯度尖峰)。 978 | - 有时,较长的预热时间可以纠正梯度截断无法纠正的不稳定性: 请查看[之前的章节](#如何对学习率进行预热)。 979 | - 🤖 在预热的时候,进行梯度截断会发生什么? 980 | - 理想的截断阈值要刚好高于“典型的”梯度范数。 981 | - 下面是一个关于如何进行梯度截断的案例: 982 | - 如果梯度范数 $\left | g \right |$ 大于梯度截断的阈值 $\lambda$,那么就需要进行 ${g}'= \lambda \times \frac{g}{\left | g \right |}$。此处的 ${g}'$是新的梯度。 983 | - 在训练期间记录下未截断梯度范数。 默认情况下会生成: 984 | - 梯度范数与步骤数量的关系图 985 | - 聚合所有步数的梯度范数直方图 986 | - 根据梯度范数的第90百分位数选择梯度截断阈值。 987 | - 这个阈值的大小与工作量有关。但90%是一个很好的选择。但如果这个奏效,那么可以对其进行调优。 988 | - 🤖 那么,某种适应性策略会怎么样呢? 989 | - 如果我们尝试梯度截断并且不稳定问题仍然存在,那么我们可以更努力地尝试(例如,阈值更小)。 990 | - 极端激进的梯度截断本质上是一种降低学习率的奇怪方式。 如果我们发现自己使用了非常激进的截断,那么我们可能应该只降低学习率。 991 | - 我们通常会认为以某种方式将超过 50% 的更新剪裁为“极其激进”。 992 | - 如果我们需要进行极其激进的梯度截断来处理我们的不稳定问题,那么我们不妨降低学习率。 993 | 994 |