Path: blob/main/transformers_doc/zh/training.ipynb
4522 views
微调预训练模型
准备数据集
在您进行预训练模型微调之前,需要下载一个数据集并为训练做好准备。之前的教程向您展示了如何处理训练数据,现在您有机会将这些技能付诸实践!
首先,加载Yelp评论数据集:
正如您现在所知,您需要一个tokenizer
来处理文本,包括填充和截断操作以处理可变的序列长度。如果要一次性处理您的数据集,可以使用 🤗 Datasets 的 map
方法,将预处理函数应用于整个数据集:
如果愿意的话,您可以从完整数据集提取一个较小子集来进行微调,以减少训练所需的时间:
训练
此时,您应该根据您训练所用的框架来选择对应的教程章节。您可以使用右侧的链接跳转到您想要的章节 - 如果您想隐藏某个框架对应的所有教程内容,只需使用右上角的按钮!
使用 PyTorch Trainer 进行训练
🤗 Transformers 提供了一个专为训练 🤗 Transformers 模型而优化的 Trainer
类,使您无需手动编写自己的训练循环步骤而更轻松地开始训练模型。Trainer
API 支持各种训练选项和功能,如日志记录、梯度累积和混合精度。
首先加载您的模型并指定期望的标签数量。根据 Yelp Review 数据集卡片,您知道有五个标签:
您将会看到一个警告,提到一些预训练权重未被使用,以及一些权重被随机初始化。不用担心,这是完全正常的!BERT 模型的预训练head
被丢弃,并替换为一个随机初始化的分类head
。您将在您的序列分类任务上微调这个新模型head
,将预训练模型的知识转移给它。
训练超参数
接下来,创建一个 TrainingArguments
类,其中包含您可以调整的所有超参数以及用于激活不同训练选项的标志。对于本教程,您可以从默认的训练超参数开始,但随时可以尝试不同的设置以找到最佳设置。
指定保存训练检查点的位置:
评估
Trainer
在训练过程中不会自动评估模型性能。您需要向 Trainer
传递一个函数来计算和展示指标。🤗 Evaluate 库提供了一个简单的 accuracy
函数,您可以使用 evaluate.load
函数加载它(有关更多信息,请参阅此快速入门):
在 metric
上调用 compute
来计算您的预测的准确性。在将预测传递给 compute
之前,您需要将预测转换为logits
(请记住,所有 🤗 Transformers 模型都返回对logits
):
如果您希望在微调过程中监视评估指标,请在您的训练参数中指定 eval_strategy
参数,以在每个epoch
结束时展示评估指标:
训练器
创建一个包含您的模型、训练参数、训练和测试数据集以及评估函数的 Trainer
对象:
然后调用train()
以微调模型:
使用keras训练TensorFlow模型
您也可以使用 Keras API 在 TensorFlow 中训练 🤗 Transformers 模型!
加载用于 Keras 的数据
当您希望使用 Keras API 训练 🤗 Transformers 模型时,您需要将您的数据集转换为 Keras 可理解的格式。如果您的数据集很小,您可以将整个数据集转换为NumPy数组并传递给 Keras。在进行更复杂的操作之前,让我们先尝试这种方法。
首先,加载一个数据集。我们将使用 GLUE benchmark 中的 CoLA 数据集,因为它是一个简单的二元文本分类任务。现在只使用训练数据集。
接下来,加载一个tokenizer
并将数据标记为 NumPy 数组。请注意,标签已经是由 0 和 1 组成的list
,因此我们可以直接将其转换为 NumPy 数组而无需进行分词处理!
当您使用 compile()
编译模型时,无需传递损失参数!如果不指定损失参数,Hugging Face 模型会自动选择适合其任务和模型架构的损失函数。如果需要,您始终可以自己指定损失函数以覆盖默认配置。
这种方法对于较小的数据集效果很好,但对于较大的数据集,您可能会发现它开始变得有问题。为什么呢?因为分词后的数组和标签必须完全加载到内存中,而且由于 NumPy 无法处理“不规则”数组,因此每个分词后的样本长度都必须被填充到数据集中最长样本的长度。这将使您的数组变得更大,而所有这些padding tokens
也会减慢训练速度!
将数据加载为 tf.data.Dataset
如果您想避免训练速度减慢,可以将数据加载为 tf.data.Dataset
。虽然您可以自己编写自己的 tf.data
流水线,但我们有两种方便的方法来实现这一点:
prepare_tf_dataset():这是我们在大多数情况下推荐的方法。因为它是模型上的一个方法,它可以检查模型以自动确定哪些列可用作模型输入,并丢弃其他列以创建一个更简单、性能更好的数据集。
to_tf_dataset
:这个方法更低级,但当您希望完全控制数据集的创建方式时非常有用,可以通过指定要包括的确切columns
和label_cols
来实现。
在使用 prepare_tf_dataset() 之前,您需要将tokenizer
的输出添加到数据集作为列,如下面的代码示例所示:
请记住,默认情况下,Hugging Face 数据集存储在硬盘上,因此这不会增加您的内存使用!一旦列已经添加,您可以从数据集中流式的传输批次数据,并为每个批次添加padding tokens
,这与为整个数据集添加padding tokens
相比,大大减少了padding tokens
的数量。
在原生 PyTorch 中训练
Trainer
负责训练循环,允许您在一行代码中微调模型。对于喜欢编写自己训练循环的用户,您也可以在原生 PyTorch 中微调 🤗 Transformers 模型。
现在,您可能需要重新启动您的notebook
,或执行以下代码以释放一些内存:
接下来,手动处理 tokenized_dataset
以准备进行训练。
移除 text 列,因为模型不接受原始文本作为输入:
将 label 列重命名为 labels,因为模型期望参数的名称为 labels:
设置数据集的格式以返回 PyTorch 张量而不是
lists
:
接着,创建一个先前展示的数据集的较小子集,以加速微调过程
DataLoader
您的训练和测试数据集创建一个DataLoader
类,以便可以迭代处理数据批次
加载您的模型,并指定期望的标签数量:
Optimizer and learning rate scheduler
创建一个optimizer
和learning rate scheduler
以进行模型微调。让我们使用 PyTorch 中的 AdamW 优化器:
创建来自 Trainer
的默认learning rate scheduler
:
最后,指定 device
以使用 GPU(如果有的话)。否则,使用 CPU 进行训练可能需要几个小时,而不是几分钟。
训练循环
为了跟踪训练进度,使用 tqdm 库来添加一个进度条,显示训练步数的进展:
评估
就像您在 Trainer
中添加了一个评估函数一样,当您编写自己的训练循环时,您需要做同样的事情。但与在每个epoch
结束时计算和展示指标不同,这一次您将使用 add_batch
累积所有批次,并在最后计算指标。
附加资源
更多微调例子可参考如下链接:
🤗 Transformers 示例 包含用于在 PyTorch 和 TensorFlow 中训练常见自然语言处理任务的脚本。
🤗 Transformers 笔记 包含针对特定任务在 PyTorch 和 TensorFlow 中微调模型的各种
notebook
。