Chapter 14
基于Transformers的多项选择
Notebooktransformers29 cells
基于Transformers的多项选择
Step1 导入相关包
In [ ]python · cell 3
python
import evaluate
from datasets import DatasetDict
from transformers import AutoTokenizer, AutoModelForMultipleChoice, TrainingArguments, TrainerStep2 加载数据集
In [ ]python · cell 5
python
c3 = DatasetDict.load_from_disk("./c3/")
c3In [ ]python · cell 6
python
c3["train"][:10]In [ ]python · cell 7
python
c3.pop("test")In [ ]python · cell 8
python
c3Step3 数据集预处理
In [ ]python · cell 10
python
tokenizer = AutoTokenizer.from_pretrained("hfl/chinese-macbert-base")
tokenizerIn [ ]python · cell 11
python
def process_function(examples):
# examples, dict, keys: ["context", "quesiton", "choice", "answer"]
# examples, 1000
context = []
question_choice = []
labels = []
for idx in range(len(examples["context"])):
ctx = "\n".join(examples["context"][idx])
question = examples["question"][idx]
choices = examples["choice"][idx]
for choice in choices:
context.append(ctx)
question_choice.append(question + " " + choice)
if len(choices) < 4:
for _ in range(4 - len(choices)):
context.append(ctx)
question_choice.append(question + " " + "不知道")
labels.append(choices.index(examples["answer"][idx]))
tokenized_examples = tokenizer(context, question_choice, truncation="only_first", max_length=256, padding="max_length") # input_ids: 4000 * 256,
tokenized_examples = {k: [v[i: i + 4] for i in range(0, len(v), 4)] for k, v in tokenized_examples.items()} # 1000 * 4 *256
tokenized_examples["labels"] = labels
return tokenized_examples
In [ ]python · cell 12
python
res = c3["train"].select(range(10)).map(process_function, batched=True)
resIn [ ]python · cell 13
python
import numpy as np
np.array(res["input_ids"]).shapeIn [ ]python · cell 14
python
tokenized_c3 = c3.map(process_function, batched=True)
tokenized_c3Step4 创建模型
In [ ]python · cell 16
python
model = AutoModelForMultipleChoice.from_pretrained("hfl/chinese-macbert-base")Step5 创建评估函数
In [ ]python · cell 18
python
import numpy as np
accuracy = evaluate.load("accuracy")
def compute_metric(pred):
predictions, labels = pred
predictions = np.argmax(predictions, axis=-1)
return accuracy.compute(predictions=predictions, references=labels)Step6 配置训练参数
In [ ]python · cell 20
python
args = TrainingArguments(
output_dir="./muliple_choice",
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
num_train_epochs=1,
logging_steps=50,
eval_strategy="epoch",
save_strategy="epoch",
load_best_model_at_end=True,
fp16=True
)Step7 创建训练器
In [ ]python · cell 22
python
trainer = Trainer(
model=model,
args=args,
tokenizer=tokenizer,
train_dataset=tokenized_c3["train"],
eval_dataset=tokenized_c3["validation"],
compute_metrics=compute_metric
)Step8 模型训练
In [ ]python · cell 24
python
trainer.train()Step9 模型预测
In [ ]python · cell 26
python
from typing import Any
import torch
class MultipleChoicePipeline:
def __init__(self, model, tokenizer) -> None:
self.model = model
self.tokenizer = tokenizer
self.device = model.device
def preprocess(self, context, quesiton, choices):
cs, qcs = [], []
for choice in choices:
cs.append(context)
qcs.append(quesiton + " " + choice)
return tokenizer(cs, qcs, truncation="only_first", max_length=256, return_tensors="pt")
def predict(self, inputs):
inputs = {k: v.unsqueeze(0).to(self.device) for k, v in inputs.items()}
return self.model(**inputs).logits
def postprocess(self, logits, choices):
predition = torch.argmax(logits, dim=-1).cpu().item()
return choices[predition]
def __call__(self, context, question, choices) -> Any:
inputs = self.preprocess(context, question, choices)
logits = self.predict(inputs)
result = self.postprocess(logits, choices)
return resultIn [ ]python · cell 27
python
pipe = MultipleChoicePipeline(model, tokenizer)In [ ]python · cell 28
python
pipe("小明在北京上班", "小明在哪里上班?", ["北京", "上海", "河北", "海南", "河北", "海南"])In [ ]python · cell 29
python
