优化深度学习训练技术

社区文章 发布于 2024 年 12 月 3 日

Lingvanex 专注于机器翻译,并提供创新解决方案,帮助用户和企业有效克服语言障碍。我们的机器翻译技术确保不同语言间通信的准确性、速度和便利性,为个人和公司提供高质量的翻译服务。

本文深入探讨了几种旨在提高训练效率和有效性的先进技术。我们将讨论有助于模型参数逐步调整的方法,这可以带来更稳定的学习过程。通过微调模型权重的更新方式和时间,这些技术旨在增强收敛性并最终产生更好的结果。此外,本文还将涵盖学习率管理策略,学习率在决定模型学习速度方面起着关键作用。了解如何随时间调整这些学习率可以显著影响训练动态,并产生更快、更准确的模型。

最后,我们将探讨检查点管理的重要性,它通过平均多次训练会话的权重来更好地利用已训练模型。这有助于减轻过拟合的影响,并确保模型保留其训练过程中学到的最佳特征。

指数移动平均

在 Transformer 模型的默认配置文件中,参数 moving_average_decay 未设置。将 moving_average_decay 参数设置为接近 1 的值(根据 TensorFlow 文档)后,下一步是计算模型权重的指数移动平均。根据文档,将 moving_average_decay 应用于模型权重可以显著改善模型结果。

moving_average_decay 算法如下:

  • 在每个训练步骤中,计算并应用梯度后,初始化 MovingAverage 类;
  • 初始化 MovingAverage 后,调用更新模型权重的函数;
  • 模型权重按以下方式更新:
  • 计算 衰减 系数:decay = 1 - min(0.9999, (1.0 + training_step) / (10.0 + training_step))
  • 对每个模型权重应用以下算法:shadow_weight = previous_weight - (previous_weight - current_weight) * decay (在第一个训练步骤,previous_weight = current_weight)
  • 每个训练步骤后的平滑权重存储在 MovingAverage 类 中;训练权重替换为平滑权重仅在保存模型检查点时发生。

image/png

简化调用序列

  • def call() 类 Trainer 模块 training.py
  • def init() 类 MovingAverage 模块 training.py
  • def _update_moving_average() 类 Trainer 模块 training.py
  • def update() 类 MovingAverage 模块 training.py

学习率衰减机制

学习率衰减 机制使用在 NoamDecayScheduleWrapper 类中初始化的变量。在每个训练步骤后,ScheduleWrapper 类中发生以下转换:
  • 使用 tf.math.maximum 函数计算 step 变量 → tf.maximum(step - step_start, 0) = 1;
  • 通过整数除法 → step //= step_duration = 1 // 1 = 1,将 step 变量调整为 step_duration 值;
  • 将上一步调整后的 step 变量传递给 NoamDecay 类

NoamDecay 类中发生以下转换:

  1. 计算 step 变量 → step = step + 1 = 2;
  2. 中间值 a:使用 tf.math.pow 函数将 model_dim 值提升到 -0.5 次方,这等效于一除以 model_dim 的平方根 → 1 / sqrt(4) = 0.5;
  3. 中间值 b:使用 tf.pow 函数 将上述获得的 step 值提升到 -0.5 次方,这等效于一除以 step 的平方根 → 1 / sqrt(2) = 0.7071;
  4. 中间值 c:使用 tf.pow 函数,将 warmup_steps 值 提升到 -1.5 次方并乘以 step 值 → (1 / 8000^1.5) * 2 = 0.000001397 * 2 = 0.000002795;
  5. 使用 tf.math.minimum 函数,确定两个中间值 bc 的最小值 → min(b, c) → 0.000002795;
  6. 将得到的最小值乘以中间值 a 和 scale → 0.0000027951 * 0.5 * 2 = 0.000002795;
  7. 中间转换的完整周期如下所示 (scale * tf.pow(model_dim, -0.5) * tf.minimum(tf.pow(step, -0.5), step * tf.pow(warmup_steps, -1.5)));
  8. 上面获得的值 0.000002795 返回到 ScheduleWrapper 类

ScheduleWrapper 类 中,定义了系数的最终值:learning rate = tf.maximum(learning_rate, minimum_learning_rate) → learning rate = max(0.000002795, 0.0001) = 0.000002795 = 0.0001。这是输出到训练日志的值:Step = 1; Learning rate = 0.000100; Loss = 3.386743

使用上述算法,我们将绘制一个模型维度为 768 且训练器配置文件中指定参数 学习率 = 2 的优化器 学习率 值变化图。

image/png

现在,我们将绘制一个模型维度为 768 且训练器配置文件中指定参数 学习率 = 6 的优化器 学习率 值变化图。

image/png

从图中我们可以得出结论,随着 warmup_steps 值减小,优化器 学习率 迅速增加,而随着配置文件中 学习率 增加,可以实现更高的优化器 学习率 值,这有助于在大模型维度下实现更快的学习。

您还可以使用 start_decay_steps 参数影响 学习率 的变化,即我们可以指定训练开始后多少步应用 warmup_steps 机制和后续衰减。

下图显示,当 start_decay_steps = 10,000 时,模型在前 1 万步以固定的 学习率 值(等于最小值)进行训练,在 1 万步之后,带有衰减的 warmup_steps 机制开始工作。

image/png

decay_step_duration 参数可用于增加 warmup_steps 机制的持续时间并减慢衰减率。

image/png

简化调用序列

  • def call() 类 ScheduleWrapper 模块 schedules/lr_schedules.py
  • def call() 类 NoamDecay 模块 schedules/lr_schedules.py
  • def call() 类 ScheduleWrapper 模块 schedules/lr_schedules.py

检查点平均机制

检查点是模型在某个训练步骤的状态。训练模型的检查点存储训练期间更改的模型权重、每个层的优化器变量(在某个训练步骤的优化器状态)和计算图。一个简单网络的计算图示例如图 6 所示——计算图。优化器以红色突出显示,常规变量为蓝色,优化器槽变量为橙色。其他节点以黑色突出显示。槽变量是优化器状态的一部分,但为特定变量创建。例如,上面的“m”边对应于 Adam 优化器为每个变量跟踪的动量。

训练结束时,模型目录中的 最后检查点 被读取并恢复,数量等于 average_last_checkpoints 参数。

根据训练模型的架构,所有模型层的权重都初始化为零。

接下来在循环中,对于每个恢复的检查点,读取权重;每个层的权重除以 average_last_checkpoints 参数中指定的检查点数量,并将结果值通过 variable.assign_add(value / num_checkpoints) 函数添加到上面初始化的权重中(embeddings 层仅与 embeddings 层求和,依此类推)。

我们示例模型中小层的平均机制,平均最后两个检查点。

image/png

结论

总之,本文讨论的技术为优化深度学习模型训练提供了宝贵的见解。通过实施权重调整、学习率管理和检查点平均策略,实践者可以显著提高模型性能和稳定性。这些方法不仅有助于更流畅的训练过程,还有助于实现更好的收敛性和泛化能力。最终,通过理解和应用这些概念,研究人员可以改进其工作流程,从而获得更高效、更有效的机器学习解决方案。

社区

注册登录发表评论