为 Transformer 模型绘制训练和验证损失曲线

我们之前已经了解了如何为神经机器翻译任务训练 Transformer 模型。在继续对训练好的模型进行推理之前,我们先来探讨如何稍微修改训练代码,以便能够绘制在学习过程中生成的训练和验证损失曲线。 

训练和验证损失值提供了重要信息,因为它们能让我们更深入地了解学习性能如何随训练轮数(epochs)变化,并帮助我们诊断可能导致模型欠拟合或过拟合的学习问题。它们还会告诉我们,在推理阶段应该使用哪个训练轮次的模型权重。

在本教程中,您将学习如何绘制 Transformer 模型的训练和验证损失曲线。 

完成本教程后,您将了解:

  • 如何修改训练代码,以便在数据集的训练分割之外,还包含验证和测试分割
  • 如何修改训练代码,以存储计算出的训练和验证损失值,以及训练好的模型权重
  • 如何绘制已保存的训练和验证损失曲线

用我的书《使用注意力机制构建 Transformer 模型》来**启动您的项目**。它提供了**自学教程**和**可运行的代码**,指导您构建一个功能完备的 Transformer 模型,该模型可以
将句子从一种语言翻译成另一种语言的完整 Transformer 模型...

让我们开始吧。

绘制 Transformer 模型的训练和验证损失曲线
照片由 Jack Anstey 拍摄,保留部分权利。

教程概述

本教程分为四个部分;它们是

  • Transformer 架构回顾
  • 准备数据集的训练、验证和测试分割
  • 训练 Transformer 模型
  • 绘制训练和验证损失曲线

先决条件

本教程假设您已熟悉以下内容:

Transformer 架构回顾

回顾一下,我们已经知道 Transformer 架构遵循编码器-解码器结构。左侧的编码器负责将输入序列映射为一系列连续表示;右侧的解码器则接收编码器的输出以及前一个时间步的解码器输出来生成一个输出序列。

Transformer 架构的编码器-解码器结构
摘自“Attention Is All You Need

在生成输出序列时,Transformer 不依赖于循环和卷积。

您已经了解了如何训练完整的 Transformer 模型,现在您将学习如何生成并绘制训练和验证损失值,这将帮助您诊断模型的学习性能。 

想开始构建带有注意力的 Transformer 模型吗?

立即参加我的免费12天电子邮件速成课程(含示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

准备数据集的训练、验证和测试分割

为了能够包含数据的验证和测试分割,您需要修改准备数据集的代码,引入以下几行代码,它们的作用是:

  • 指定验证数据分割的大小。这反过来决定了训练和测试数据分割的大小,我们将数据按 80:10:10 的比例划分为训练集、验证集和测试集

  • 除了训练集外,将数据集分割为验证集和测试集

  • 通过分词、填充和转换为张量来准备验证数据。为此,您将把这些操作集合到一个名为 encode_pad 的函数中,如下面的完整代码清单所示。这将避免在对训练数据执行这些操作时出现过多的代码重复

  • 将编码器和解码器的分词器保存到 pickle 文件中,并将测试数据集保存到文本文件中,以便稍后在推理阶段使用

完整的代码清单现在更新如下

训练 Transformer 模型

我们将对训练 Transformer 模型的代码进行类似的修改,以

  • 准备验证数据集批次

  • 监控验证损失指标

  • 初始化字典以存储训练和验证损失,并最终将损失值存储在各自的字典中

  • 计算验证损失

  • 在每个 epoch 结束时保存训练好的模型权重。您将在推理阶段使用这些权重,以研究模型在不同 epoch 产生的结果差异。在实践中,更有效的方法是引入一个回调方法,根据训练期间监控的指标来停止训练过程,然后才保存模型权重

  • 最后,将训练和验证损失值保存到 pickle 文件中

修改后的代码清单现在变为

绘制训练和验证损失曲线

为了能够绘制训练和验证损失曲线,您首先需要加载之前训练 Transformer 模型时保存的、包含训练和验证损失字典的 pickle 文件。 

然后,您将从各自的字典中检索训练和验证损失值,并将它们绘制在同一张图上。

代码清单如下,您应该将其保存到一个单独的 Python 脚本中

运行上面的代码会生成一张与下图类似的训练和验证损失曲线图

在多个训练轮次中训练和验证损失值的折线图

请注意,尽管您可能会看到类似的损失曲线,但它们不一定与上图完全相同。这是因为您是从头开始训练 Transformer 模型的,最终的训练和验证损失值取决于模型权重的随机初始化。 

尽管如此,这些损失曲线能让我们更深入地了解学习性能如何随训练轮数变化,并帮助我们诊断可能导致模型欠拟合或过拟合的学习问题。 

有关使用训练和验证损失曲线诊断模型学习性能的更多详细信息,您可以参考 Jason Brownlee 的这篇教程 

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

书籍

论文

网站

总结

在本教程中,您学习了如何绘制 Transformer 模型的训练和验证损失曲线。 

具体来说,你学到了:

  • 如何修改训练代码,以便在数据集的训练分割之外,还包含验证和测试分割
  • 如何修改训练代码,以存储计算出的训练和验证损失值,以及训练好的模型权重
  • 如何绘制已保存的训练和验证损失曲线

你有什么问题吗?
在下面的评论中提出您的问题,我将尽力回答。

学习 Transformer 和注意力!

Building Transformer Models with Attention

教您的深度学习模型阅读句子

...使用带有注意力的 Transformer 模型

在我的新电子书中探索如何实现
使用注意力机制构建 Transformer 模型

它提供了自学教程可运行代码,指导您构建一个可以
将句子从一种语言翻译成另一种语言的完整 Transformer 模型...

为理解人类语言提供神奇力量
您的项目


查看内容

, , , ,

《绘制 Transformer 模型的训练和验证损失曲线》的 7 条回应

  1. Brett 2022年11月3日 上午7:11 #

    为了让代码正常工作,我必须将这两个项目转换为列表(第 6 行和第 7 行),像这样

    # 检索每个字典的值
    train_values = list(train_loss.values())
    val_values = list(val_loss.values())

    很棒的系列文章,谢谢!

  2. khatija 2023年3月9日 上午3:11 #

    训练后如何绘制图像分类中每个类别的准确率图

  3. Olufunke 2023年5月6日 上午12:01 #

    你好,非常感谢。我正在尝试将其应用于 PyTorch。请问我该如何定义权重

  4. Oliver 2024年1月11日 上午9:28 #

    感谢您提供的这个优秀系列!它对我非常有帮助。

    我认为这篇文章中有两个小笔误
    – prepare-dataset 代码中的第 70 行应该是“dataset”而不是“train”。
    – training 代码中的第 51 行,所用数据集的名称中缺少了“-both”。

    做了这些修改后,我得到了相同的验证损失曲线。

    再次感谢您,祝一切顺利!

    • James Carmichael 2024年1月11日 上午9:38 #

      你好 Oliver……不客气!感谢您的反馈!

发表评论

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。