侧边栏壁纸
博主头像
小鱼吃猫博客博主等级

你所热爱的,便是你的生活。

  • 累计撰写 114 篇文章
  • 累计创建 47 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

Transformers框架之Trainer组件

小鱼吃猫
2023-08-04 / 1 评论 / 1 点赞 / 46 阅读 / 5707 字

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
    })
})

看一下数据长什么样吧,看一下前几条。

labelreview
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}] 
1

评论区