Bert基础(十九)--Bert实战:文本相似度匹配

文本匹配是指计算机系统识别和确定两段文本之间关系的任务。这个概念非常广泛,涵盖了各种场景,其中文本之间的关系可以是有相似度、问答、对话、推理等。在不同的应用场景下,文本匹配的具体定义可能会有所不同。

以下是几种常见的文本匹配任务及其特点:

  1. 文本相似度计算:计算两个文本之间的相似程度,例如判断两个句子是否表达相同或相似的意思。
  2. 问答匹配:将用户提出的问题与数据库中的答案进行匹配,以提供正确的信息。
  3. 对话匹配:在对话系统中,识别用户输入的文本与系统回复之间的匹配关系,以确保对话的连贯性和准确性。
  4. 文本推理 :根据给定的文本内容推断出新的信息或结论。
    此外,像抽取式机器阅读理解和多项选择这样的任务,其本质也是文本匹配。在这些任务中,系统需要理解文本内容,并将其与问题或选项进行匹配,以确定正确答案。
    总之,文本匹配是自然语言处理中的一个重要概念,广泛应用于信息检索、机器翻译、文本生成、对话系统等多个领域。随着技术的发展,文本匹配的算法和模型也在不断进步,以更准确地理解和匹配文本内容。

本次先介绍最简单的文本相似度计算的任务,后面将其他的信息检索、机器翻译、文本生成、对话系统等任务进行实战。

基本步骤:
1 加载数据集 2 数据预处理 3 创建模型 4 创建评估函数 5 创建训练器 6 训练模型 7 评估 8 预测

1 加载数据集

在hugging face没有找到合适的数据集,所以找了一个资源上传在git上,大家可自取

python 复制代码
dataset = load_dataset("json", data_files="/kaggle/input/sentence/sentence_pair.json", split="train")
dataset
Dataset({
    features: ['sentence1', 'sentence2', 'label'],
    num_rows: 10000
})

看下数据格式

python 复制代码
dataset[10]
{'sentence1': '她是一个非常慷慨的女人,拥有自己的一大笔财产。',
 'sentence2': '她有很多钱,但她是个慷慨的女人。',
 'label': '1'}

2 数据预处理

python 复制代码
datasets = dataset.train_test_split(test_size=0.2)
datasets
DatasetDict({
    train: Dataset({
        features: ['sentence1', 'sentence2', 'label'],
        num_rows: 8000
    })
    test: Dataset({
        features: ['sentence1', 'sentence2', 'label'],
        num_rows: 2000
    })
})

数据格式划分

python 复制代码
import torch

tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")

def process_function(examples):
    tokenized_examples = tokenizer(examples["sentence1"], examples["sentence2"], max_length=128, truncation=True)
    tokenized_examples["labels"] = [int(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

原始数据中label是字符串格式,需要int转换下

python 复制代码
print(tokenized_datasets["train"][0])
{'input_ids': [101, 704, 1286, 1762, 100, 4638, 2207, 2238, 828, 2622, 8024, 4692, 4708, 1920, 6496, 1403, 3777, 6804, 6624, 1343, 511, 102, 1762, 100, 7353, 6818, 3766, 3300, 1920, 6496, 511, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'labels': 0}

3 加载模型

python 复制代码
from transformers import BertForSequenceClassification 
model = AutoModelForSequenceClassification.from_pretrained("bert-base-chinese")

4 创建评估函数

python 复制代码
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

5 创建训练器

python 复制代码
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",      # 设定评估指标
                               report_to=['tensorboard'],
                               load_best_model_at_end=True)     # 训练完成后加载最优模型
train_args

6 开始训练

python 复制代码
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()
python 复制代码
TrainOutput(global_step=750, training_loss=0.1850536205768585, metrics={'train_runtime': 302.9995, 'train_samples_per_second': 79.208, 'train_steps_per_second': 2.475, 'total_flos': 1552684115443200.0, 'train_loss': 0.1850536205768585, 'epoch': 3.0})

7 评估

python 复制代码
trainer.evaluate(tokenized_datasets["test"])
{'eval_loss': 0.2481037676334381,
 'eval_accuracy': 0.912,
 'eval_f1': 0.8894472361809046,
 'eval_runtime': 7.6159,
 'eval_samples_per_second': 262.61,
 'eval_steps_per_second': 8.272,
 'epoch': 3.0}

8 预测

python 复制代码
pipe = pipeline("text-classification", model=model, tokenizer=tokenizer, device=0)
result = pipe({"text": "昨天我做了个梦", "text_pair": "下雨了"})
result
{'label': '不相似', 'score': 0.989981472492218}

补充

上面是用分类的方式进行训练的,这里有个问题就是如果我们呢需要对一个句子去喝多个句子进行匹配找出最相似的句子就不行了,因为上面这种方式的结果没有对比的价值。所以我们需要修改下,使用MSE来计算损失。

需要修改的地方主要是两个,

数据预处理

python 复制代码
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

计算MSE需要计算损失的具体数值,所以要转换成浮点型

评估函数

python 复制代码
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

预测的是一个具体的数值,不是【0,1】,所以计算准确率时要转换下

模型

python 复制代码
num_labels=1

num_labels改为一,用回归的形式去预测

完整代码

相关推荐
这个男人是小帅1 小时前
【GAT】 代码详解 (1) 运行方法【pytorch】可运行版本
人工智能·pytorch·python·深度学习·分类
__基本操作__1 小时前
边缘提取函数 [OPENCV--2]
人工智能·opencv·计算机视觉
Doctor老王1 小时前
TR3:Pytorch复现Transformer
人工智能·pytorch·transformer
热爱生活的五柒1 小时前
pytorch中数据和模型都要部署在cuda上面
人工智能·pytorch·深度学习
HyperAI超神经3 小时前
【TVM 教程】使用 Tensorize 来利用硬件内联函数
人工智能·深度学习·自然语言处理·tvm·计算机技术·编程开发·编译框架
扫地的小何尚5 小时前
NVIDIA RTX 系统上使用 llama.cpp 加速 LLM
人工智能·aigc·llama·gpu·nvidia·cuda·英伟达
埃菲尔铁塔_CV算法7 小时前
深度学习神经网络创新点方向
人工智能·深度学习·神经网络
艾思科蓝-何老师【H8053】8 小时前
【ACM出版】第四届信号处理与通信技术国际学术会议(SPCT 2024)
人工智能·信号处理·论文发表·香港中文大学
weixin_452600698 小时前
《青牛科技 GC6125:驱动芯片中的璀璨之星,点亮 IPcamera 和云台控制(替代 BU24025/ROHM)》
人工智能·科技·单片机·嵌入式硬件·新能源充电桩·智能充电枪
学术搬运工8 小时前
【珠海科技学院主办,暨南大学协办 | IEEE出版 | EI检索稳定 】2024年健康大数据与智能医疗国际会议(ICHIH 2024)
大数据·图像处理·人工智能·科技·机器学习·自然语言处理