诸神缄默不语-个人CSDN博文目录
我准备过几天录一个讲解视频。先等一下,现在只有图文版。
本文代码最早写于2024年3月27日,不保证未来以下代码及操作过程仍然可以使用。
本文主要关注中文仇恨检测短文本分类,数据集来源于datasets官网,本教程不介绍datasets包的使用技能。
完整代码见:https://github.com/PolarisRisingWar/all-notes-in-one/blob/main/hate_text_classification.ipynb
文章目录
- 1. 环境配置
- 2. 设置超参
- 3. 导入包
- 4. 构建tokenizer和模型
- 5. 导入数据集
- 6. 数据集预处理
- 7. 设置训练和评估超参数
- 8. 训练
- 9. 测试
1. 环境配置
Anaconda安装教程:Anaconda教程(持续更新ing…)
或视频版:https://www.bilibili.com/video/BV1K34y1G7av/
PyTorch安装教程:PyTorch安装教程
transformers安装教程:huggingface.transformers安装教程
此外还需要下载datasets, evaluate, accelerate包,直接用pip下载就可以
pip教程:pip详解(持续更新ing…)
BERT中文版预训练模型权重:下载这里所有的文件:bert-base-chinese at main
然后放到某个文件夹里,这个文件夹路径在下面的代码里放到pretrained_path位置处
2. 设置超参
# 超参设置
pretrained_path = r"D:\allApplications\forPython\llm\bert-base-chinese" #预训练模型权重路径
max_epoch_num = 1 #运行epoch数
output_dim = 2 #分类标签数(本文做仇恨检测,所以是二分类)
3. 导入包
import numpy as npfrom transformers import (AutoTokenizer,AutoModelForSequenceClassification,TrainingArguments,Trainer,
)import datasets, evaluate
4. 构建tokenizer和模型
tokenizer = AutoTokenizer.from_pretrained(pretrained_path)
model = AutoModelForSequenceClassification.from_pretrained(pretrained_path, num_labels=output_dim
)
5. 导入数据集
我直接用的是datasets官网上的Paul/hatecheck-mandarin数据集,可以参考以下代码将数据文件先下载到本地:
import datasets
dataset=datasets.load_dataset("Paul/hatecheck-mandarin")dataset.save_to_disk("hatecheck-mandarin")
以后就可以直接通过如下代码导入数据集:
all_dataset = datasets.load_from_disk("hatecheck-mandarin")
6. 数据集预处理
这个数据集只有测试集,我尝试性地选择了30个样本分别作为训练集、验证集和测试集。
label_map = {"hateful": 1, "non-hateful": 0} #将标签映射为数字def tokenize_function(examples):"""批量预处理样本的代码"""return_dict = tokenizer(examples["test_case"], padding="max_length", truncation=True, max_length=512) #tokenize输入文本return_dict["label"] = [label_map[x] for x in examples["label_gold"]] #将标签映射为数字return return_dicttokenized_datasets = all_dataset.map(tokenize_function, batched=True) #对数据集进行批量预处理#将数据集划分为训练集、验证集、测试集
example_train_dataset = tokenized_datasets["test"].select(range(10))
example_valid_dataset = tokenized_datasets["test"].select(range(10, 20))
example_test_dataset = tokenized_datasets["test"].select(range(20, 30))
7. 设置训练和评估超参数
#训练阶段超参数
training_args = TrainingArguments(output_dir="test_checkpoint", #训练权重存储路径evaluation_strategy="epoch", #每个epoch评估一次report_to="none", #设置不用wandb记录训练日志push_to_hub=False, #不将训练权重上传到huggingface hubnum_train_epochs=max_epoch_num, #训练轮数per_device_train_batch_size=1, #每个设备(CPU/GPU)上的batch sizeno_cuda=True, #不使用GPU(我是因为电脑上GPU内存只有2G根本带不动,反正只是个示例代码干脆不用了)do_train=True, #训练save_steps=10, #每10个step保存一次checkpointsave_total_limit=1, #保存最后1个checkpoint
)#调用evaluate包的准确率评估指标
metric = evaluate.load("accuracy")def compute_metrics(eval_pred):logits, labels = eval_predpredictions = np.argmax(logits, axis=-1)return metric.compute(predictions=predictions, references=labels)#设置训练器
trainer = Trainer(model=model,args=training_args,train_dataset=example_train_dataset,eval_dataset=example_valid_dataset,compute_metrics=compute_metrics,
)
8. 训练
trainer.train()
一边训练一边就会保存训练权重,打印进度条和评估指标:
9. 测试
直接得到测试集上的预测结果。
predictions是每个样本对应的logits(两个元素分别是正负标签归一化前的预测概率)。
label_ids是标签。
metrics是评估指标(损失函数、准确率、运行时间)
result = trainer.predict(example_test_dataset)
print(result)
输出:
PredictionOutput(predictions=array([[-2.42961 , 3.2694852],[-2.601208 , 3.2841954],[-2.4568973, 3.0550063],[-2.48325 , 3.239044 ],[-2.5793636, 3.283456 ],[-2.356497 , 2.8706086],[-2.5480254, 3.2449925],[-2.4836488, 3.2778778],[-2.6639569, 3.2867384],[-2.5087523, 3.067698 ]], dtype=float32), label_ids=array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int64), metrics={'test_loss': 0.003417523577809334, 'test_accuracy': 1.0, 'test_runtime': 17.7476, 'test_samples_per_second': 0.563, 'test_steps_per_second': 0.113})