Transformers框架之Trainer组件
Trainer参数解读
在学习完Tokenizer、Datasets、Model、Evaluate组件后,Trainer组件是用来训练模型的,也是最简 单的。以下是一个最基础的Trainer的参数示例:
trainer = Trainer(
model=model, # 模型
args=training_args, # 训练参数
train_dataset=train_dataset, # 训练集
eval_dataset=eval_dataset, # 验证集
tokenizer=tokenizer, # 分词器
data_collator=data_collator, # 数据收集器
compute_metrics=compute_metrics, # 评估函数
)
接下来,以**情感分析(外卖评价)**为例进行参数解读一下。
1.参数构造
1.1导包
from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset
1.2加载数据集
选择huggingface上的公开数据集,可以看到,他这个数据集是已经区分了训练集和测试集的。我们无需划分再次划分
dataset = load_dataset("C-MTEB/waimai-classification")
数据集内容如下:
DatasetDict({
test: Dataset({
features: ['label', 'text'],
num_rows: 1000
})
train: Dataset({
features: ['label', 'text'],
num_rows: 8000
})
})
看一下数据长什么样吧,看一下前几条。
label | review |
---|---|
1 | 分量很足,不错,都是肉丁,还有青辣椒,不腻,下次尝尝别的口味的。 |
1 | 味道一如既往的好,说好的微辣呢,感觉比普通还辣,但盖不过眉州的美味,好评 |
0 | 不好吃,还不如食堂做的,这口味不值这个价 |
1 | 肘子挺好吃~ |
0 | 清炒菠菜根本无法吃,菠菜里的沙子没洗净 |
1.3加载分词器
tokenizer = AutoTokenizer.from_pretrained("hfl/rbt3")
1.4数据集预处理
利用分词器把数据文本进行分词,并把分词后的结果转换为模型可读的格式。
def process_function(examples):
# 编码,最大长度为128,使用padding和截断
tokenized_examples = tokenizer(examples["text"], max_length=128, truncation=True,padding="max_length")
# 构建labels
tokenized_examples["labels"] = examples["label"]
return tokenized_examples
#映射词表,remove_columns的意思是删除原有的标签text和label
tokenized_datasets = dataset.map(process_function, batched=True, remove_columns=dataset["train"].column_names)
结果如下:
DatasetDict({
test: Dataset({
features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
num_rows: 1000
})
train: Dataset({
features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
num_rows: 8000
})
)}
1.5加载模型
model = AutoModelForSequenceClassification.from_pretrained("hfl/rbt3")
1.6创建评估函数
import evaluate
acc_metric = evaluate.load("accuracy")
f1_metirc = evaluate.load("f1")
def eval_metric(eval_predict):
predictions, labels = eval_predict
predictions = predictions.argmax(axis=-1)
acc = acc_metric.compute(predictions=predictions, references=labels)
f1 = f1_metirc.compute(predictions=predictions, references=labels)
acc.update(f1)
return acc
1.7创建TrainingArguments(训练参数)
train_args = TrainingArguments(
output_dir="./checkpoints", # 输出文件夹
)
TrainingArguments还支持一些自定义参数,比如:
per_device_train_batch_size=64, # 训练时的batch_size
per_device_eval_batch_size=128, # 验证时的batch_size
logging_steps=10, # log 打印的频率
evaluation_strategy="epoch", # 评估策略
save_strategy="epoch", # 保存策略
save_total_limit=3, # 最大保存数
learning_rate=2e-5, # 学习率
weight_decay=0.01, # weight_decay
metric_for_best_model="f1", # 设定评估指标
load_best_model_at_end=True, # 训练完成后加载最优模型
no_cuda=True,# 仅使用CPU进行训练
2.参数传入Trainer
将第一步构建的参数传进来
from transformers import DataCollatorWithPadding
trainer = Trainer(
model=model,# 模型
args=train_args, # 训练参数
train_dataset=tokenized_datasets["train"], # 训练集
eval_dataset=tokenized_datasets["test"], # 验证集
data_collator=DataCollatorWithPadding(tokenizer=tokenizer),
tokenizer=tokenizer, # 分词器
compute_metrics=eval_metric)
3.开始训练
开始训练就很简单了,一句代码搞定
trainer.train()
4.模型评估
使用数据集中的测试数据集进行评估
trainer.evaluate(tokenized_datasets["test"])
输出结果如下:
{'eval_loss': 0.2914249002933502,
'eval_accuracy': 0.894,
'eval_f1': 0.8290322580645162,
'eval_recall': 0.7907692307692308,
'eval_precision': 0.8711864406779661,
'eval_runtime': 2.8437,
'eval_samples_per_second': 351.651,
'eval_steps_per_second': 2.813,
'epoch': 3.0}
5.模型预测
使用pipeline来加载模型,进行预测。从checkpoint中进行加载
from transformers import pipeline
model = AutoModelForSequenceClassification.from_pretrained("./checkpoints/checkpoint-3000")
# checkpoint是没有分词器的,所以使用之前的分词器
tokenizer = AutoTokenizer.from_pretrained("hfl/rbt3")
model.config.id2label = {0: "差评", 1: "好评"}
pipe = pipeline("text-classification", model=model, tokenizer=tokenizer, device=0)
使用pipe()预测
pipe("老板真离谱,让送个菜也不送")
# [{'label': '差评', 'score': 0.9980535507202148}]
评论区