1 准备数据
1.1 下载数据
https://hf-mirror.com/datasets/tiansz/ChineseSTS/tree/main
1.2 转为 csv格式并且保存
#dataset = load_dataset('text',"../data/Chinese_Text_Similarity.txt",split="train")
count = 0
# 打开文件
content1 = []
content2 = []
labels = []
with open("../data/Chinese_Text_Similarity.txt", 'r', encoding='utf-8') as f:
count +=1
# 读取文件内容
line = f.readline()
columns = line.strip().split('\t')
for line in f:
line = line.strip().split('\t')
if len(line) < 3:
continue
content1.append(line[0].strip())
content2.append(line[1].strip())
labels.append(int(float(line[2].strip())))
import pandas as pd
df = pd.DataFrame(data=[content1,content2,labels]).T
df.columns = ['sentence1','sentence2','label']
train_df, test_df = train_test_split(df,test_size=0.2)
print(f'train shape = {train_df.shape}, test shape = {test_df.shape}')
df.to_csv('../data/Chinese_Text_Similarity.csv',encoding='utf_8_sig')
备注:
下载的数据最后一行需要删除,是一个不完整的预料。其次我还转为了utf-8的文件格式;
原本想通过下面一行的代码搞定,但是一直报错,大家可自己尝试。我是没有成功,所以才通过转为CSV然后再通过load_dataset加载数据。
dataset = load_dataset('text',"../data/Chinese_Text_Similarity.txt",split="train")
2 模型
选择一个稍微小点的模型进行调优。
Chinese MacBERT Base 是苹果公司基于 BERT 架构在中文语料库上进行预训练的模型。该模型在处理中文自然语言处理任务时表现出色,具有强大的语义理解和表征学习能力。以下是 Chinese MacBERT Base 模型的一些特点和优势:
1. **中文优化**:Chinese MacBERT Base 是专门为中文语言任务进行优化的模型,能够更好地捕捉中文文本的语义和语境。
2. **预训练性能**:通过在大规模中文文本数据上进行预训练,Chinese MacBERT Base 能够学习丰富的语言表示,有助于提高在各种中文自然语言处理任务上的性能。
3. **参数规模**:通常,Chinese MacBERT Base 包含数亿个参数,具有较大的模型规模,可以更好地捕捉文本中的复杂关系和特征。
4. **应用领域**:Chinese MacBERT Base 可以用于各种中文自然语言处理任务,如文本分类、命名实体识别、情感分析、句子相似度计算等,为这些任务提供了强大的基础模型。
需要注意的点:
原本是一个二分类任务(有两个输出结果),但是使用的损失函数是 MSE, 在评估指标这一块使用代码部分predictions = [int(p > 0.5) for p in predictions],超过0.5 直接设定为”相似“ 。而不是一个二分类任务输出各个类别一个判定的概率,输出最大的位置作为判定结果。
完整的代码
from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset,load_from_disk
import traceback
from sklearn.model_selection import train_test_split
#dataset = load_dataset('text',"../data/Chinese_Text_Similarity.txt",split="train")
count = 0
# 打开文件
content1 = []
content2 = []
labels = []
with open("../data/Chinese_Text_Similarity.txt", 'r', encoding='utf-8') as f:
count +=1
# 读取文件内容
line = f.readline()
columns = line.strip().split('\t')
for line in f:
line = line.strip().split('\t')
if len(line) < 3:
continue
content1.append(line[0].strip())
content2.append(line[1].strip())
labels.append(int(float(line[2].strip())))
import pandas as pd
df = pd.DataFrame(data=[content1,content2,labels]).T
df.columns = ['sentence1','sentence2','label']
train_df, test_df = train_test_split(df,test_size=0.2)
print(f'train shape = {train_df.shape}, test shape = {test_df.shape}')
df.to_csv('../data/Chinese_Text_Similarity.csv',encoding='utf_8_sig')
dataset = load_dataset("csv", data_files="../data/Chinese_Text_Similarity.csv", split="train")
import torch
tokenizer = AutoTokenizer.from_pretrained("../chinese_macbert_base")
def process_function(examples):
tokenized_examples = tokenizer(examples["sentence1"], examples["sentence2"], max_length=128, truncation=True)
tokenized_examples["labels"] = [float(label) for label in examples["label"]]
return tokenized_examples
tokenized_datasets = datasets.map(process_function, batched=True, remove_columns=datasets["train"].column_names)
tokenized_datasets
from transformers import BertForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained("../chinese_macbert_base/", num_labels=1)
import evaluate
acc_metric = evaluate.load("./metric_accuracy.py")
f1_metirc = evaluate.load("./metric_f1.py")
#
# acc_metric = evaluate.load("accuracy")
# f1_metirc = evaluate.load("f1")
def eval_metric(eval_predict):
predictions, labels = eval_predict
predictions = [int(p > 0.5) for p in predictions]
labels = [int(l) for l in labels]
# 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
train_args = TrainingArguments(output_dir="./cross_model", # 输出文件夹
per_device_train_batch_size=32, # 训练时的batch_size
per_device_eval_batch_size=32, # 验证时的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) # 训练完成后加载最优模型
train_args
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),
compute_metrics=eval_metric)
trainer.train()
trainer.evaluate(tokenized_datasets["test"])
数据相对来说比较的少,其次也没有选择过于复杂的模型,因此训练过程很快。训练的最终结果也挺不错的。