Transformers 4.37 中文文档(二)(4)

简介: Transformers 4.37 中文文档(二)

Transformers 4.37 中文文档(二)(3)https://developer.aliyun.com/article/1563284


评估

在训练过程中包含一个度量通常有助于评估模型的性能。您可以使用 🤗 Evaluate 库快速加载一个评估方法。对于这个任务,加载 accuracy 度量(查看 🤗 Evaluate 快速导览 以了解如何加载和计算度量):

>>> import evaluate
>>> accuracy = evaluate.load("accuracy")

然后创建一个函数,将您的预测和标签传递给 compute 来计算准确率:

>>> import numpy as np
>>> def compute_metrics(eval_pred):
...     predictions, labels = eval_pred
...     predictions = np.argmax(predictions, axis=1)
...     return accuracy.compute(predictions=predictions, references=labels)

您的 compute_metrics 函数现在已经准备就绪,当您设置训练时会返回到它。

训练

在开始训练模型之前,使用 id2labellabel2id 创建预期 id 到标签的映射:

>>> id2label = {0: "NEGATIVE", 1: "POSITIVE"}
>>> label2id = {"NEGATIVE": 0, "POSITIVE": 1}

Pytorch 隐藏 Pytorch 内容

如果您不熟悉如何使用 Trainer 对模型进行微调,请查看这里的基本教程!

现在您已经准备好开始训练您的模型了!加载 DistilBERT 与 AutoModelForSequenceClassification 以及预期标签的数量和标签映射:

>>> from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer
>>> model = AutoModelForSequenceClassification.from_pretrained(
...     "distilbert-base-uncased", num_labels=2, id2label=id2label, label2id=label2id
... )

此时,只剩下三个步骤:

  1. 在 TrainingArguments 中定义您的训练超参数。唯一必需的参数是 output_dir,指定保存模型的位置。通过设置 push_to_hub=True 将此模型推送到 Hub(您需要登录 Hugging Face 以上传您的模型)。在每个 epoch 结束时,Trainer 将评估准确率并保存训练检查点。
  2. 将训练参数传递给 Trainer,以及模型、数据集、标记器、数据整理器和 compute_metrics 函数。
  3. 调用 train() 来微调您的模型。
>>> training_args = TrainingArguments(
...     output_dir="my_awesome_model",
...     learning_rate=2e-5,
...     per_device_train_batch_size=16,
...     per_device_eval_batch_size=16,
...     num_train_epochs=2,
...     weight_decay=0.01,
...     evaluation_strategy="epoch",
...     save_strategy="epoch",
...     load_best_model_at_end=True,
...     push_to_hub=True,
... )
>>> trainer = Trainer(
...     model=model,
...     args=training_args,
...     train_dataset=tokenized_imdb["train"],
...     eval_dataset=tokenized_imdb["test"],
...     tokenizer=tokenizer,
...     data_collator=data_collator,
...     compute_metrics=compute_metrics,
... )
>>> trainer.train()

当您将 tokenizer 传递给 Trainer 时,默认情况下会应用动态填充。在这种情况下,您不需要显式指定数据整理器。

训练完成后,使用 push_to_hub() 方法将您的模型分享到 Hub,这样每个人都可以使用您的模型:

>>> trainer.push_to_hub()

TensorFlow 隐藏 TensorFlow 内容

如果您不熟悉如何使用 Keras 对模型进行微调,请查看这里的基本教程!

要在 TensorFlow 中微调模型,请首先设置优化器函数、学习率调度和一些训练超参数:

>>> from transformers import create_optimizer
>>> import tensorflow as tf
>>> batch_size = 16
>>> num_epochs = 5
>>> batches_per_epoch = len(tokenized_imdb["train"]) // batch_size
>>> total_train_steps = int(batches_per_epoch * num_epochs)
>>> optimizer, schedule = create_optimizer(init_lr=2e-5, num_warmup_steps=0, num_train_steps=total_train_steps)

然后,您可以加载 DistilBERT 与 TFAutoModelForSequenceClassification,以及预期标签的数量和标签映射:

>>> from transformers import TFAutoModelForSequenceClassification
>>> model = TFAutoModelForSequenceClassification.from_pretrained(
...     "distilbert-base-uncased", num_labels=2, id2label=id2label, label2id=label2id
... )

将您的数据集转换为tf.data.Dataset格式,使用 prepare_tf_dataset():

>>> tf_train_set = model.prepare_tf_dataset(
...     tokenized_imdb["train"],
...     shuffle=True,
...     batch_size=16,
...     collate_fn=data_collator,
... )
>>> tf_validation_set = model.prepare_tf_dataset(
...     tokenized_imdb["test"],
...     shuffle=False,
...     batch_size=16,
...     collate_fn=data_collator,
... )

使用compile为训练配置模型。请注意,Transformers 模型都有一个默认的与任务相关的损失函数,因此除非您想要,否则不需要指定一个:

>>> import tensorflow as tf
>>> model.compile(optimizer=optimizer)  # No loss argument!

在开始训练之前设置的最后两件事是从预测中计算准确率,并提供一种将模型推送到 Hub 的方法。这两个都可以通过使用 Keras callbacks 来完成。

将您的compute_metrics函数传递给 KerasMetricCallback:

>>> from transformers.keras_callbacks import KerasMetricCallback
>>> metric_callback = KerasMetricCallback(metric_fn=compute_metrics, eval_dataset=tf_validation_set)

指定在 PushToHubCallback 中推送模型和分词器的位置:

>>> from transformers.keras_callbacks import PushToHubCallback
>>> push_to_hub_callback = PushToHubCallback(
...     output_dir="my_awesome_model",
...     tokenizer=tokenizer,
... )

然后将您的回调捆绑在一起:

>>> callbacks = [metric_callback, push_to_hub_callback]
• 1

最后,您已经准备好开始训练您的模型了!使用您的训练和验证数据集、时代数和回调来微调模型调用fit

>>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3, callbacks=callbacks)

训练完成后,您的模型会自动上传到 Hub,以便每个人都可以使用它!

有关如何为文本分类微调模型的更深入示例,请查看相应的PyTorch 笔记本TensorFlow 笔记本

推理

很好,现在您已经对模型进行了微调,可以用它进行推理!

获取一些您想要进行推理的文本:

>>> text = "This was a masterpiece. Not completely faithful to the books, but enthralling from beginning to end. Might be my favorite of the three."

尝试使用您微调的模型进行推理的最简单方法是在 pipeline()中使用它。用您的模型实例化一个情感分析的pipeline,并将文本传递给它:

>>> from transformers import pipeline
>>> classifier = pipeline("sentiment-analysis", model="stevhliu/my_awesome_model")
>>> classifier(text)
[{'label': 'POSITIVE', 'score': 0.9994940757751465}]

如果您愿意,也可以手动复制pipeline的结果:

Pytorch 隐藏 Pytorch 内容

对文本进行标记化并返回 PyTorch 张量:

>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_model")
>>> inputs = tokenizer(text, return_tensors="pt")

将您的输入传递给模型并返回logits

>>> from transformers import AutoModelForSequenceClassification
>>> model = AutoModelForSequenceClassification.from_pretrained("stevhliu/my_awesome_model")
>>> with torch.no_grad():
...     logits = model(**inputs).logits

获取具有最高概率的类,并使用模型的id2label映射将其转换为文本标签:

>>> predicted_class_id = logits.argmax().item()
>>> model.config.id2label[predicted_class_id]
'POSITIVE'

TensorFlow 隐藏 TensorFlow 内容

对文本进行标记化并返回 TensorFlow 张量:

>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_model")
>>> inputs = tokenizer(text, return_tensors="tf")

将您的输入传递给模型并返回logits

>>> from transformers import TFAutoModelForSequenceClassification
>>> model = TFAutoModelForSequenceClassification.from_pretrained("stevhliu/my_awesome_model")
>>> logits = model(**inputs).logits

获取具有最高概率的类,并使用模型的id2label映射将其转换为文本标签:

>>> predicted_class_id = int(tf.math.argmax(logits, axis=-1)[0])
>>> model.config.id2label[predicted_class_id]
'POSITIVE'

标记分类

原文链接:huggingface.co/docs/transformers/v4.37.2/en/tasks/token_classification

www.youtube-nocookie.com/embed/wVHdVlPScxA

标记分类为句子中的每个单词分配一个标签。最常见的标记分类任务之一是命名实体识别(NER)。NER 试图为句子中的每个实体找到一个标签,比如人名、地点或组织。

本指南将向您展示如何:

  1. 在 WNUT 17 数据集上对DistilBERT进行微调,以检测新实体。
  2. 使用您微调的模型进行推断。

本教程中演示的任务由以下模型架构支持:

ALBERT, BERT, BigBird, BioGpt, BLOOM, BROS, CamemBERT, CANINE,  ConvBERT, Data2VecText, DeBERTa, DeBERTa-v2, DistilBERT, ELECTRA, ERNIE,  ErnieM, ESM, Falcon, FlauBERT, FNet, Funnel Transformer, GPT-Sw3,  OpenAI GPT-2, GPTBigCode, GPT Neo, GPT NeoX, I-BERT, LayoutLM,  LayoutLMv2, LayoutLMv3, LiLT, Longformer, LUKE, MarkupLM, MEGA,  Megatron-BERT, MobileBERT, MPNet, MPT, MRA, Nezha, Nyströmformer, Phi,  QDQBert, RemBERT, RoBERTa, RoBERTa-PreLayerNorm, RoCBert, RoFormer,  SqueezeBERT, XLM, XLM-RoBERTa, XLM-RoBERTa-XL, XLNet, X-MOD, YOSO

在开始之前,请确保已安装所有必要的库:

pip install transformers datasets evaluate seqeval

我们鼓励您登录您的 Hugging Face 账户,这样您就可以上传和分享您的模型给社区。在提示时,输入您的令牌以登录:

>>> from huggingface_hub import notebook_login
>>> notebook_login()

加载 WNUT 17 数据集

首先从🤗数据集库中加载 WNUT 17 数据集:

>>> from datasets import load_dataset
>>> wnut = load_dataset("wnut_17")

然后看一个例子:

>>> wnut["train"][0]
{'id': '0',
 'ner_tags': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0],
 'tokens': ['@paulwalk', 'It', "'s", 'the', 'view', 'from', 'where', 'I', "'m", 'living', 'for', 'two', 'weeks', '.', 'Empire', 'State', 'Building', '=', 'ESB', '.', 'Pretty', 'bad', 'storm', 'here', 'last', 'evening', '.']
}

ner_tags中的每个数字代表一个实体。将数字转换为它们的标签名称,以找出这些实体是什么:

>>> label_list = wnut["train"].features[f"ner_tags"].feature.names
>>> label_list
[
    "O",
    "B-corporation",
    "I-corporation",
    "B-creative-work",
    "I-creative-work",
    "B-group",
    "I-group",
    "B-location",
    "I-location",
    "B-person",
    "I-person",
    "B-product",
    "I-produ

每个ner_tag前缀的字母表示实体的标记位置:

  • B-表示一个实体的开始。
  • I-表示一个单词包含在同一个实体中(例如,State单词是Empire State Building这样一个实体的一部分)。
  • 0表示该标记不对应任何实体。

预处理

www.youtube-nocookie.com/embed/iY2AZYdZAr0

下一步是加载一个 DistilBERT 分词器来预处理tokens字段:

>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")

正如您在上面的示例 tokens 字段中看到的,看起来输入已经被标记化了。但实际上输入还没有被标记化,您需要设置 is_split_into_words=True 将单词标记化为子词。例如:

>>> example = wnut["train"][0]
>>> tokenized_input = tokenizer(example["tokens"], is_split_into_words=True)
>>> tokens = tokenizer.convert_ids_to_tokens(tokenized_input["input_ids"])
>>> tokens
['[CLS]', '@', 'paul', '##walk', 'it', "'", 's', 'the', 'view', 'from', 'where', 'i', "'", 'm', 'living', 'for', 'two', 'weeks', '.', 'empire', 'state', 'building', '=', 'es', '##b', '.', 'pretty', 'bad', 'storm', 'here', 'last', 'evening', '.', '[SEP]']

然而,这会添加一些特殊标记 [CLS][SEP],子词标记化会导致输入和标签之间的不匹配。现在,一个对应于单个标签的单词可能会被拆分为两个子词。您需要通过以下方式重新对齐标记和标签:

  1. 使用 word_ids 方法将所有标记映射到它们对应的单词。
  2. 将标签 -100 分配给特殊标记 [CLS][SEP],以便它们被 PyTorch 损失函数忽略(参见 CrossEntropyLoss)。
  3. 仅标记给定单词的第一个标记。将其他来自同一单词的子标记分配为 -100

以下是如何创建一个函数来重新对齐标记和标签,并截断序列,使其不超过 DistilBERT 的最大输入长度:

>>> def tokenize_and_align_labels(examples):
...     tokenized_inputs = tokenizer(examples["tokens"], truncation=True, is_split_into_words=True)
...     labels = []
...     for i, label in enumerate(examples[f"ner_tags"]):
...         word_ids = tokenized_inputs.word_ids(batch_index=i)  # Map tokens to their respective word.
...         previous_word_idx = None
...         label_ids = []
...         for word_idx in word_ids:  # Set the special tokens to -100.
...             if word_idx is None:
...                 label_ids.append(-100)
...             elif word_idx != previous_word_idx:  # Only label the first token of a given word.
...                 label_ids.append(label[word_idx])
...             else:
...                 label_ids.append(-100)
...             previous_word_idx = word_idx
...         labels.append(label_ids)
...     tokenized_inputs["labels"] = labels
...     return tokenized_inputs

要在整个数据集上应用预处理函数,请使用 🤗 Datasets map 函数。您可以通过设置 batched=True 来加速 map 函数,以一次处理数据集的多个元素:

>>> tokenized_wnut = wnut.map(tokenize_and_align_labels, batched=True)

现在使用 DataCollatorWithPadding 创建一批示例。在整理过程中,将句子动态填充到批次中的最大长度,而不是将整个数据集填充到最大长度。

PytorchHide Pytorch 内容

>>> from transformers import DataCollatorForTokenClassification
>>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer)

TensorFlowHide TensorFlow 内容

>>> from transformers import DataCollatorForTokenClassification
>>> data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer, return_tensors="tf")


Transformers 4.37 中文文档(二)(5)https://developer.aliyun.com/article/1563286

相关文章
|
3月前
|
存储 缓存 Shell
Transformers 4.37 中文文档(一)(3)
Transformers 4.37 中文文档(一)
212 1
Transformers 4.37 中文文档(一)(3)
|
3月前
|
存储 编解码 JSON
Transformers 4.37 中文文档(四)(5)
Transformers 4.37 中文文档(四)
43 1
Transformers 4.37 中文文档(四)(5)
|
3月前
|
自然语言处理 PyTorch 语音技术
Transformers 4.37 中文文档(四)(1)
Transformers 4.37 中文文档(四)
34 3
|
3月前
|
自然语言处理 安全 PyTorch
Transformers 4.37 中文文档(一)(4)
Transformers 4.37 中文文档(一)
42 1
|
3月前
|
PyTorch TensorFlow 调度
Transformers 4.37 中文文档(一)(5)
Transformers 4.37 中文文档(一)
57 1
|
3月前
|
编解码 缓存 算法
Transformers 4.37 中文文档(一百)(2)
Transformers 4.37 中文文档(一百)
33 1
|
3月前
|
自然语言处理 PyTorch TensorFlow
Transformers 4.37 中文文档(一)(2)
Transformers 4.37 中文文档(一)
66 1
|
3月前
|
存储 API 计算机视觉
Transformers 4.37 中文文档(五)(2)
Transformers 4.37 中文文档(五)
40 1
|
3月前
|
自然语言处理 PyTorch TensorFlow
Transformers 4.37 中文文档(三)(2)
Transformers 4.37 中文文档(三)
27 1
|
3月前
|
存储 自然语言处理 测试技术
Transformers 4.37 中文文档(八)(4)
Transformers 4.37 中文文档(八)
59 2