Transformers 4.37 中文文档(二)(4)https://developer.aliyun.com/article/1563285
评估
在训练过程中包含一个指标通常有助于评估模型的性能。您可以使用 🤗 Evaluate 库快速加载评估方法。对于这个任务,加载 seqeval 框架(查看 🤗 Evaluate 快速入门 了解如何加载和计算指标)。Seqeval 实际上会生成几个分数:精确度、召回率、F1 和准确度。
>>> import evaluate >>> seqeval = evaluate.load("seqeval")
首先获取 NER 标签,然后创建一个函数,将您的真实预测和真实标签传递给 compute
来计算分数:
>>> import numpy as np >>> labels = [label_list[i] for i in example[f"ner_tags"]] >>> def compute_metrics(p): ... predictions, labels = p ... predictions = np.argmax(predictions, axis=2) ... true_predictions = [ ... [label_list[p] for (p, l) in zip(prediction, label) if l != -100] ... for prediction, label in zip(predictions, labels) ... ] ... true_labels = [ ... [label_list[l] for (p, l) in zip(prediction, label) if l != -100] ... for prediction, label in zip(predictions, labels) ... ] ... results = seqeval.compute(predictions=true_predictions, references=true_labels) ... return { ... "precision": results["overall_precision"], ... "recall": results["overall_recall"], ... "f1": results["overall_f1"], ... "accuracy": results["overall_accuracy"], ... }
您的 compute_metrics
函数现在已经准备就绪,当您设置训练时会返回到它。
训练
在开始训练模型之前,使用 id2label
和 label2id
创建预期 id 到标签的映射:
>>> id2label = { ... 0: "O", ... 1: "B-corporation", ... 2: "I-corporation", ... 3: "B-creative-work", ... 4: "I-creative-work", ... 5: "B-group", ... 6: "I-group", ... 7: "B-location", ... 8: "I-location", ... 9: "B-person", ... 10: "I-person", ... 11: "B-product", ... 12: "I-product", ... } >>> label2id = { ... "O": 0, ... "B-corporation": 1, ... "I-corporation": 2, ... "B-creative-work": 3, ... "I-creative-work": 4, ... "B-group": 5, ... "I-group": 6, ... "B-location": 7, ... "I-location": 8, ... "B-person": 9, ... "I-person": 10, ... "B-product": 11, ... "I-product": 12, ... }
PytorchHide Pytorch 内容
如果您不熟悉使用 Trainer 对模型进行微调,请查看这里的基本教程 here!
现在您已经准备好开始训练您的模型了!使用 AutoModelForTokenClassification 加载 DistilBERT,以及预期标签数和标签映射:
>>> from transformers import AutoModelForTokenClassification, TrainingArguments, Trainer >>> model = AutoModelForTokenClassification.from_pretrained( ... "distilbert-base-uncased", num_labels=13, id2label=id2label, label2id=label2id ... )
此时,只剩下三个步骤:
- 在 TrainingArguments 中定义您的训练超参数。唯一必需的参数是
output_dir
,指定保存模型的位置。通过设置push_to_hub=True
将此模型推送到 Hub(您需要登录 Hugging Face 以上传模型)。在每个时代结束时,Trainer 将评估 seqeval 分数并保存训练检查点。 - 将训练参数传递给 Trainer,以及模型、数据集、分词器、数据整理器和
compute_metrics
函数。 - 调用 train()来微调您的模型。
>>> training_args = TrainingArguments( ... output_dir="my_awesome_wnut_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_wnut["train"], ... eval_dataset=tokenized_wnut["test"], ... tokenizer=tokenizer, ... data_collator=data_collator, ... compute_metrics=compute_metrics, ... ) >>> trainer.train()
培训完成后,使用 push_to_hub()方法将您的模型共享到 Hub,以便每个人都可以使用您的模型:
>>> trainer.push_to_hub()
隐藏 TensorFlow 内容
如果您不熟悉使用 Keras 微调模型,请查看基本教程这里!
要在 TensorFlow 中微调模型,请首先设置优化器函数、学习率调度和一些训练超参数:
>>> from transformers import create_optimizer >>> batch_size = 16 >>> num_train_epochs = 3 >>> num_train_steps = (len(tokenized_wnut["train"]) // batch_size) * num_train_epochs >>> optimizer, lr_schedule = create_optimizer( ... init_lr=2e-5, ... num_train_steps=num_train_steps, ... weight_decay_rate=0.01, ... num_warmup_steps=0, ... )
然后,您可以加载 DistilBERT 与 TFAutoModelForTokenClassification 以及预期标签的数量和标签映射:
>>> from transformers import TFAutoModelForTokenClassification >>> model = TFAutoModelForTokenClassification.from_pretrained( ... "distilbert-base-uncased", num_labels=13, id2label=id2label, label2id=label2id ... )
使用 prepare_tf_dataset()将数据集转换为tf.data.Dataset
格式:
>>> tf_train_set = model.prepare_tf_dataset( ... tokenized_wnut["train"], ... shuffle=True, ... batch_size=16, ... collate_fn=data_collator, ... ) >>> tf_validation_set = model.prepare_tf_dataset( ... tokenized_wnut["validation"], ... shuffle=False, ... batch_size=16, ... collate_fn=data_collator, ... )
使用compile
配置模型进行训练。请注意,Transformers 模型都有一个默认的与任务相关的损失函数,因此除非您想要指定一个,否则不需要指定:
>>> import tensorflow as tf >>> model.compile(optimizer=optimizer) # No loss argument!
在开始训练之前设置的最后两件事是从预测中计算 seqeval 分数,并提供一种将您的模型推送到 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_wnut_model", ... tokenizer=tokenizer, ... )
然后将您的回调捆绑在一起:
>>> callbacks = [metric_callback, push_to_hub_callback]
最后,您已经准备好开始训练您的模型了!使用您的训练和验证数据集、时代数和回调调用fit
来微调模型:
>>> model.fit(x=tf_train_set, validation_data=tf_validation_set, epochs=3, callbacks=callbacks) • 1
一旦训练完成,您的模型将自动上传到 Hub,以便每个人都可以使用它!
要了解如何为标记分类微调模型的更深入示例,请查看相应的PyTorch 笔记本或TensorFlow 笔记本。
推理
很好,现在您已经微调了一个模型,可以用它进行推理了!
获取一些您想要运行推理的文本:
>>> text = "The Golden State Warriors are an American professional basketball team based in San Francisco."
尝试使用您微调的模型进行推理的最简单方法是在 pipeline()中使用它。用您的模型实例化一个 NER 的pipeline
,并将文本传递给它:
>>> from transformers import pipeline >>> classifier = pipeline("ner", model="stevhliu/my_awesome_wnut_model") >>> classifier(text) [{'entity': 'B-location', 'score': 0.42658573, 'index': 2, 'word': 'golden', 'start': 4, 'end': 10}, {'entity': 'I-location', 'score': 0.35856336, 'index': 3, 'word': 'state', 'start': 11, 'end': 16}, {'entity': 'B-group', 'score': 0.3064001, 'index': 4, 'word': 'warriors', 'start': 17, 'end': 25}, {'entity': 'B-location', 'score': 0.65523505, 'index': 13, 'word': 'san', 'start': 80, 'end': 83}, {'entity': 'B-location', 'score': 0.4668663, 'index': 14, 'word': 'francisco', 'start': 84, 'end': 93}]
如果您愿意,您也可以手动复制pipeline
的结果:
隐藏 Pytorch 内容
对文本进行标记化并返回 PyTorch 张量:
>>> from transformers import AutoTokenizer >>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_wnut_model") >>> inputs = tokenizer(text, return_tensors="pt")
将您的输入传递给模型并返回logits
:
>>> from transformers import AutoModelForTokenClassification >>> model = AutoModelForTokenClassification.from_pretrained("stevhliu/my_awesome_wnut_model") >>> with torch.no_grad(): ... logits = model(**inputs).logits
获取具有最高概率的类,并使用模型的id2label
映射将其转换为文本标签:
>>> predictions = torch.argmax(logits, dim=2) >>> predicted_token_class = [model.config.id2label[t.item()] for t in predictions[0]] >>> predicted_token_class ['O', 'O', 'B-location', 'I-location', 'B-group', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'B-location', 'B-location', 'O', 'O']
隐藏 TensorFlow 内容
对文本进行标记化并返回 TensorFlow 张量:
>>> from transformers import AutoTokenizer >>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_wnut_model") >>> inputs = tokenizer(text, return_tensors="tf")
将您的输入传递给模型并返回logits
:
>>> from transformers import TFAutoModelForTokenClassification >>> model = TFAutoModelForTokenClassification.from_pretrained("stevhliu/my_awesome_wnut_model") >>> logits = model(**inputs).logits
获取具有最高概率的类,并使用模型的id2label
映射将其转换为文本标签:
>>> predicted_token_class_ids = tf.math.argmax(logits, axis=-1) >>> predicted_token_class = [model.config.id2label[t] for t in predicted_token_class_ids[0].numpy().tolist()] >>> predicted_token_class ['O', 'O', 'B-location', 'I-location', 'B-group', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'B-location', 'B-location', 'O', 'O']
olden’, ‘start’: 4, ‘end’: 10}, {‘entity’: ‘I-location’, ‘score’: 0.35856336, ‘index’: 3, ‘word’: ‘state’, ‘start’: 11, ‘end’: 16}, {‘entity’: ‘B-group’, ‘score’: 0.3064001, ‘index’: 4, ‘word’: ‘warriors’, ‘start’: 17, ‘end’: 25}, {‘entity’: ‘B-location’, ‘score’: 0.65523505, ‘index’: 13, ‘word’: ‘san’, ‘start’: 80, ‘end’: 83}, {‘entity’: ‘B-location’, ‘score’: 0.4668663, ‘index’: 14, ‘word’: ‘francisco’, ‘start’: 84, ‘end’: 93}]
如果您愿意,您也可以手动复制`pipeline`的结果: 隐藏 Pytorch 内容 对文本进行标记化并返回 PyTorch 张量: ```py >>> from transformers import AutoTokenizer >>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_wnut_model") >>> inputs = tokenizer(text, return_tensors="pt")
将您的输入传递给模型并返回logits
:
>>> from transformers import AutoModelForTokenClassification >>> model = AutoModelForTokenClassification.from_pretrained("stevhliu/my_awesome_wnut_model") >>> with torch.no_grad(): ... logits = model(**inputs).logits
获取具有最高概率的类,并使用模型的id2label
映射将其转换为文本标签:
>>> predictions = torch.argmax(logits, dim=2) >>> predicted_token_class = [model.config.id2label[t.item()] for t in predictions[0]] >>> predicted_token_class ['O', 'O', 'B-location', 'I-location', 'B-group', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'B-location', 'B-location', 'O', 'O']
隐藏 TensorFlow 内容
对文本进行标记化并返回 TensorFlow 张量:
>>> from transformers import AutoTokenizer >>> tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_wnut_model") >>> inputs = tokenizer(text, return_tensors="tf")
将您的输入传递给模型并返回logits
:
>>> from transformers import TFAutoModelForTokenClassification >>> model = TFAutoModelForTokenClassification.from_pretrained("stevhliu/my_awesome_wnut_model") >>> logits = model(**inputs).logits
获取具有最高概率的类,并使用模型的id2label
映射将其转换为文本标签:
>>> predicted_token_class_ids = tf.math.argmax(logits, axis=-1) >>> predicted_token_class = [model.config.id2label[t] for t in predicted_token_class_ids[0].numpy().tolist()] >>> predicted_token_class ['O', 'O', 'B-location', 'I-location', 'B-group', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'B-location', 'B-location', 'O', 'O']