【拥抱AI】如何使用BERT等预训练模型计算语义相似度

使用BERT等预训练模型计算语义相似度是一种非常有效的方法,可以捕捉句子之间的深层次语义关系。下面是一个详细的步骤指南,介绍如何使用BERT和Sentence-BERT来计算语义相似度。
在这里插入图片描述

1. 环境准备

1.1 安装必要的库

首先,确保你已经安装了必要的Python库。这里我们使用transformers库来加载BERT模型,使用sentence-transformers库来加载Sentence-BERT模型。

pip install transformers sentence-transformers

2. 加载预训练模型

2.1 加载BERT模型

BERT模型可以将输入文本编码为向量表示,但默认情况下,BERT模型的输出是每个token的向量表示,而不是整个句子的向量表示。为了得到句子级别的向量表示,我们可以使用池化操作(如取平均值或使用CLS标记)。

from transformers import BertTokenizer, BertModel
import torch# 加载预训练的BERT模型和分词器
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)# 输入文本
reference = "This is a test."
candidate = "This is a test."# 编码为token IDs
input_ids = tokenizer([reference, candidate], padding=True, truncation=True, return_tensors='pt')# 获取模型的输出
with torch.no_grad():outputs = model(**input_ids)# 获取最后一层的隐藏状态
last_hidden_states = outputs.last_hidden_state# 使用CLS标记的向量作为句子表示
cls_embeddings = last_hidden_states[:, 0, :]# 计算余弦相似度
cosine_similarity = torch.nn.functional.cosine_similarity(cls_embeddings[0], cls_embeddings[1], dim=0)
print(f"BERT Semantic Similarity: {cosine_similarity.item()}")
2.2 加载Sentence-BERT模型

Sentence-BERT是BERT的一个变种,专门用于生成句子级别的向量表示。Sentence-BERT通过微调BERT模型,使其能够更有效地生成句子级别的向量表示。

from sentence_transformers import SentenceTransformer, util# 加载预训练的Sentence-BERT模型
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')# 输入文本
reference = "This is a test."
candidate = "This is a test."# 编码为向量
reference_embedding = model.encode(reference, convert_to_tensor=True)
candidate_embedding = model.encode(candidate, convert_to_tensor=True)# 计算余弦相似度
similarity = util.pytorch_cos_sim(reference_embedding, candidate_embedding).item()
print(f"Sentence-BERT Semantic Similarity: {similarity}")

3. 详细步骤

3.1 数据预处理
  1. 分词:将输入文本分词为token序列。
  2. 编码:将token序列转换为模型可以接受的输入格式(如token IDs)。
# 输入文本
reference = "This is a test."
candidate = "This is a test."# 编码为token IDs
input_ids = tokenizer([reference, candidate], padding=True, truncation=True, return_tensors='pt')
3.2 模型推理
  1. 前向传播:将输入传递给模型,获取模型的输出。
  2. 提取向量:从模型的输出中提取句子级别的向量表示。
# 获取模型的输出
with torch.no_grad():outputs = model(**input_ids)# 获取最后一层的隐藏状态
last_hidden_states = outputs.last_hidden_state# 使用CLS标记的向量作为句子表示
cls_embeddings = last_hidden_states[:, 0, :]
3.3 计算相似度
  1. 余弦相似度:计算两个向量之间的余弦相似度,范围从-1到1,值越接近1表示相似度越高。
# 计算余弦相似度
cosine_similarity = torch.nn.functional.cosine_similarity(cls_embeddings[0], cls_embeddings[1], dim=0)
print(f"BERT Semantic Similarity: {cosine_similarity.item()}")

4. 示例代码

以下是一个完整的示例代码,展示了如何使用BERT和Sentence-BERT计算两个句子的语义相似度。

from transformers import BertTokenizer, BertModel
import torch
from sentence_transformers import SentenceTransformer, util# 加载预训练的BERT模型和分词器
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)# 输入文本
reference = "This is a test."
candidate = "This is a test."# 编码为token IDs
input_ids = tokenizer([reference, candidate], padding=True, truncation=True, return_tensors='pt')# 获取模型的输出
with torch.no_grad():outputs = model(**input_ids)# 获取最后一层的隐藏状态
last_hidden_states = outputs.last_hidden_state# 使用CLS标记的向量作为句子表示
cls_embeddings = last_hidden_states[:, 0, :]# 计算余弦相似度
cosine_similarity_bert = torch.nn.functional.cosine_similarity(cls_embeddings[0], cls_embeddings[1], dim=0)
print(f"BERT Semantic Similarity: {cosine_similarity_bert.item()}")# 加载预训练的Sentence-BERT模型
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')# 编码为向量
reference_embedding = model.encode(reference, convert_to_tensor=True)
candidate_embedding = model.encode(candidate, convert_to_tensor=True)# 计算余弦相似度
similarity_sentence_bert = util.pytorch_cos_sim(reference_embedding, candidate_embedding).item()
print(f"Sentence-BERT Semantic Similarity: {similarity_sentence_bert}")

5. 结果解释

  • BERT Semantic Similarity:使用BERT模型计算的余弦相似度。
  • Sentence-BERT Semantic Similarity:使用Sentence-BERT模型计算的余弦相似度。

6. 注意事项

  1. 模型选择:根据任务需求选择合适的模型。Sentence-BERT在句子级别的任务上表现更好,而BERT在更细粒度的任务上可能更适用。
  2. 数据预处理:确保输入文本的预处理步骤一致,以避免因数据格式不一致导致的误差。
  3. 计算资源:BERT和Sentence-BERT模型计算量较大,需要足够的计算资源,特别是在处理大规模数据时。

通过以上步骤,你可以使用BERT和Sentence-BERT模型有效地计算句子之间的语义相似度,从而评估生成文本的质量。

BERT和Sentence-BERT模型不仅在计算语义相似度方面表现出色,还可以应用于多种自然语言处理任务。以下是一些常见的任务及其使用BERT和Sentence-BERT的详细说明:

1. 文本分类

1.1 任务描述

文本分类任务的目标是将文本归类到预定义的类别中,例如情感分类、垃圾邮件检测、新闻分类等。

1.2 使用BERT
from transformers import BertTokenizer, BertForSequenceClassification
import torch# 加载预训练的BERT模型和分词器
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name, num_labels=2)  # 二分类任务# 输入文本
text = "This is a positive review."# 编码为token IDs
input_ids = tokenizer(text, padding=True, truncation=True, return_tensors='pt')# 获取模型的输出
with torch.no_grad():outputs = model(**input_ids)# 获取预测标签
logits = outputs.logits
predicted_label = torch.argmax(logits, dim=1).item()
print(f"Predicted Label: {predicted_label}")
1.3 使用Sentence-BERT
from sentence_transformers import SentenceTransformer, models# 加载预训练的Sentence-BERT模型
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')# 输入文本
text = "This is a positive review."# 编码为向量
embedding = model.encode(text, convert_to_tensor=True)# 假设有一个预训练的分类器
classifier = torch.nn.Linear(embedding.size(-1), 2)  # 二分类任务# 获取模型的输出
with torch.no_grad():logits = classifier(embedding.unsqueeze(0))# 获取预测标签
predicted_label = torch.argmax(logits, dim=1).item()
print(f"Predicted Label: {predicted_label}")

2. 情感分析

2.1 任务描述

情感分析任务的目标是判断文本的情感倾向,通常是正面、负面或中立。

2.2 使用BERT
from transformers import BertTokenizer, BertForSequenceClassification
import torch# 加载预训练的BERT模型和分词器
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name, num_labels=3)  # 三分类任务# 输入文本
text = "I love this product!"# 编码为token IDs
input_ids = tokenizer(text, padding=True, truncation=True, return_tensors='pt')# 获取模型的输出
with torch.no_grad():outputs = model(**input_ids)# 获取预测标签
logits = outputs.logits
predicted_label = torch.argmax(logits, dim=1).item()
print(f"Predicted Label: {predicted_label}")
2.3 使用Sentence-BERT
from sentence_transformers import SentenceTransformer, models# 加载预训练的Sentence-BERT模型
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')# 输入文本
text = "I love this product!"# 编码为向量
embedding = model.encode(text, convert_to_tensor=True)# 假设有一个预训练的分类器
classifier = torch.nn.Linear(embedding.size(-1), 3)  # 三分类任务# 获取模型的输出
with torch.no_grad():logits = classifier(embedding.unsqueeze(0))# 获取预测标签
predicted_label = torch.argmax(logits, dim=1).item()
print(f"Predicted Label: {predicted_label}")

3. 命名实体识别 (NER)

3.1 任务描述

命名实体识别任务的目标是从文本中识别出特定类型的实体,如人名、地名、组织名等。

3.2 使用BERT
from transformers import BertTokenizer, BertForTokenClassification
import torch# 加载预训练的BERT模型和分词器
model_name = 'dbmdz/bert-large-cased-finetuned-conll03-english'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForTokenClassification.from_pretrained(model_name)# 输入文本
text = "Apple is looking at buying U.K. startup for $1 billion"# 编码为token IDs
input_ids = tokenizer(text, return_tensors='pt')# 获取模型的输出
with torch.no_grad():outputs = model(**input_ids)# 获取预测标签
logits = outputs.logits
predicted_labels = torch.argmax(logits, dim=2).squeeze().tolist()# 映射标签
label_list = ['O', 'B-PER', 'I-PER', 'B-ORG', 'I-ORG', 'B-LOC', 'I-LOC', 'B-MISC', 'I-MISC']
tokens = tokenizer.convert_ids_to_tokens(input_ids['input_ids'][0])for token, label in zip(tokens, predicted_labels):print(f"Token: {token}, Label: {label_list[label]}")

4. 问答系统 (Question Answering)

4.1 任务描述

问答系统任务的目标是根据给定的问题和上下文,生成答案。

4.2 使用BERT
from transformers import BertTokenizer, BertForQuestionAnswering
import torch# 加载预训练的BERT模型和分词器
model_name = 'bert-large-uncased-whole-word-masking-finetuned-squad'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForQuestionAnswering.from_pretrained(model_name)# 输入文本
context = "The Apollo program, also known as Project Apollo, was the third United States human spaceflight program carried out by the National Aeronautics and Space Administration (NASA)."
question = "What was the third United States human spaceflight program?"# 编码为token IDs
inputs = tokenizer(question, context, return_tensors='pt')# 获取模型的输出
with torch.no_grad():outputs = model(**inputs)# 获取起始和结束位置
start_scores = outputs.start_logits
end_scores = outputs.end_logits# 获取预测的答案
answer_start = torch.argmax(start_scores)
answer_end = torch.argmax(end_scores) + 1
answer = tokenizer.convert_tokens_to_string(tokenizer.convert_ids_to_tokens(inputs['input_ids'][0][answer_start:answer_end]))print(f"Answer: {answer}")

5. 语义搜索 (Semantic Search)

5.1 任务描述

语义搜索任务的目标是在大量文档中找到与查询最相关的文档。

5.2 使用Sentence-BERT
from sentence_transformers import SentenceTransformer, util# 加载预训练的Sentence-BERT模型
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')# 输入文本
query = "How to train a neural network?"
documents = ["Training a neural network involves several steps, including data preprocessing, model architecture design, and optimization.","Neural networks are a powerful tool for machine learning tasks.","Deep learning frameworks like TensorFlow and PyTorch make it easy to train neural networks."
]# 编码为向量
query_embedding = model.encode(query, convert_to_tensor=True)
document_embeddings = model.encode(documents, convert_to_tensor=True)# 计算余弦相似度
similarities = util.pytorch_cos_sim(query_embedding, document_embeddings)[0]# 排序并输出最相关的文档
top_k = 2
top_results = torch.topk(similarities, k=top_k)
for score, idx in zip(top_results[0], top_results[1]):print(f"Document: {documents[idx]}, Score: {score.item()}")

6. 语义匹配 (Semantic Matching)

6.1 任务描述

语义匹配任务的目标是判断两个句子是否具有相同的语义。

6.2 使用BERT
from transformers import BertTokenizer, BertModel
import torch# 加载预训练的BERT模型和分词器
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)# 输入文本
sentence1 = "This is a test."
sentence2 = "This is a test."# 编码为token IDs
input_ids = tokenizer([sentence1, sentence2], padding=True, truncation=True, return_tensors='pt')# 获取模型的输出
with torch.no_grad():outputs = model(**input_ids)# 获取最后一层的隐藏状态
last_hidden_states = outputs.last_hidden_state# 使用CLS标记的向量作为句子表示
cls_embeddings = last_hidden_states[:, 0, :]# 计算余弦相似度
cosine_similarity = torch.nn.functional.cosine_similarity(cls_embeddings[0], cls_embeddings[1], dim=0)
print(f"BERT Semantic Similarity: {cosine_similarity.item()}")
6.3 使用Sentence-BERT
from sentence_transformers import SentenceTransformer, util# 加载预训练的Sentence-BERT模型
model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2')# 输入文本
sentence1 = "This is a test."
sentence2 = "This is a test."# 编码为向量
sentence1_embedding = model.encode(sentence1, convert_to_tensor=True)
sentence2_embedding = model.encode(sentence2, convert_to_tensor=True)# 计算余弦相似度
similarity = util.pytorch_cos_sim(sentence1_embedding, sentence2_embedding).item()
print(f"Sentence-BERT Semantic Similarity: {similarity}")

7. 文本生成

7.1 任务描述

文本生成任务的目标是根据给定的提示生成新的文本,如续写故事、生成新闻标题等。

7.2 使用BERT
from transformers import BertTokenizer, BertForMaskedLM
import torch# 加载预训练的BERT模型和分词器
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForMaskedLM.from_pretrained(model_name)# 输入文本
prompt = "This is a [MASK] test."# 编码为token IDs
input_ids = tokenizer(prompt, return_tensors='pt')# 获取模型的输出
with torch.no_grad():outputs = model(**input_ids)# 获取预测的token
logits = outputs.logits
predicted_token_id = torch.argmax(logits[0, 4, :], dim=-1).item()
predicted_token = tokenizer.decode(predicted_token_id)print(f"Predicted Token: {predicted_token}")
7.3 使用Sentence-BERT

Sentence-BERT主要用于生成句子级别的向量表示,不太适合直接用于文本生成任务。但对于生成任务,可以使用其他预训练模型,如GPT-2或GPT-3。

总结

BERT和Sentence-BERT模型在多种自然语言处理任务中表现出色,包括文本分类、情感分析、命名实体识别、问答系统、语义搜索、语义匹配和文本生成。通过上述示例代码,你可以了解如何在这些任务中使用这些模型。希望这些详细的指南对你有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/19857.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Excel常用技巧分享

excel单元格内换行 直接按回车会退出当前单元格的编辑,如果需要在单元格中换行,需要按下AltEnter。 excel插入多行或多列 WPS 在WPS中想要插入多行,只需在右键菜单中输入对应的数字即可。 Office Excel excel中相对麻烦一些,比…

C# .NET环境下调用ONNX格式YOLOV8模型问题总结

我的环境是: Visual Studio: 2019 显卡: 一、遇到问题 1、EntryPointNotFoundException:无法在DLL“onnxruntime”中找到名为“OrtGetApiBase”的入口点。差了下原因,入口点是启动项中的问题。 原因:之前用yolov7时安装的版本在C…

【PTA】【数据库】【SQL命令】编程题1

数据库SQL命令测试题1 10-1 显示教工编号以02开头的教师信息 作者 冰冰 单位 广东东软学院 显示教工编号以02开头的教师信息 提示:请使用SELECT语句作答。 表结构: CREATE TABLE teacher ( TId CHAR(5) NOT NULL, -- 教师工号,主键 DId CHAR(2) …

VSCode快速生成vue组件模版

1&#xff0c;点击设置&#xff0c;找到代码片段 2&#xff0c;搜索vue&#xff0c;打开vue.json 3&#xff0c;添加模版 vue2模板 "vue2": {"prefix": "vue2","body": ["<template>"," <div>$0</di…

理解DOM:前端开发的基础

理解DOM 在前端开发中&#xff0c;DOM&#xff08;文档对象模型&#xff09;是一个至关重要的概念。它不仅定义了如何通过编程方式访问和修改网页内容&#xff0c;还为我们提供了一种结构化的方式来与页面交互。本文将带你了解DOM的基本概念、不同节点的操作以及何时可以进行更…

如何将几个音频合成一个音频?非常简单的几种合成方法

如何将几个音频合成一个音频&#xff1f;音频合成不仅仅是将不同的音频文件按顺序排列&#xff0c;它还可能涉及到音量调节、剪辑、淡入淡出、音效调整等多个方面。对于一些专业的音频制作人员来说&#xff0c;音频的每一部分细节都可能需要精心打磨&#xff0c;以确保最终合成…

虚拟化表格(Virtualized Table)性能优化

文章目录 功能介绍一开始的代码领导让我们分析一下开始优化如何监听事件和传参&#xff1f;定位操作栏更加优化 功能介绍 菜鸟最近做的一个功能如下&#xff1a; 后端返回两个很大的数组&#xff0c;例如&#xff1a;数组a 1w条&#xff0c;数组b 2w条&#xff0c;然后要操作b…

Orcad 输出有链接属性的PDF

安装adobe pdf安装Ghostscript修改C:\Cadence\SPB_16.6\tools\capture\tclscripts\capUtils\capPdfUtil.tcl ​ 设置默认打印机为 Adobe PDF ​ 将Ghostscript的路径修改正确 打开cadence Orcad &#xff0c;accessories->candece Tcl/Tk Utilities-> Utilities->PD…

从源头保障电力安全:输电线路动态增容与温度监测技术详解

在电力系统中&#xff0c;输电线路是电能传输的关键环节。然而&#xff0c;当导线温度过高时&#xff0c;会加速导线老化&#xff0c;降低绝缘性能&#xff0c;甚至引发短路、火灾等严重事故&#xff0c;对电网安全运行构成巨大威胁。近日&#xff0c;某地区因持续高温和用电负…

递归系列 简单(倒序输出一个正整数)

倒序输出一个正整数 时间限制: 1s 类别: 递归->简单 问题描述 例如给出正整数 n12345&#xff0c;希望以各位数的逆序形式输出&#xff0c;即输出54321。 递归思想&#xff1a;首先输出这个数的个位数&#xff0c;然后将个位丢掉&#xff0c;得到新的数&#xff0c;继续…

矩阵论在图像算法中的应用

摘要&#xff1a; 本文详细阐述了矩阵论在图像算法中的广泛应用。首先介绍了图像在计算机中的矩阵表示形式&#xff0c;然后从图像压缩、图像变换、图像特征提取与识别、图像恢复与重建等多个方面深入分析了矩阵论相关技术的作用原理和优势。通过对这些应用的探讨&#xff0c;展…

鸿蒙改变状态栏和安全区域颜色之 expandSafeArea

改变状态栏和安全区域颜色之 expandSafeArea 基于API12。 参考文档 直接设置build里边根元素的背景色之后&#xff0c;本想着是整个页面的颜色全变成相应的颜色&#xff0c;不过实际上状态栏跟地步安全区域是不受影响的。这个时候一般可能都会各种地方找API来设置状态栏跟安全…

Ubuntu Linux使用前准备动作_使用root登录图形化界面

Ubuntu默认是不允许使用 root 登录图形化界面的。这是出于安全考虑的设置。但如果有需要&#xff0c;可以通过以下步骤来实现使用 root 登录&#xff1a; 1、设置 root 密码 打开终端&#xff0c;使用当前的管理员账户登录系统。在终端中输入命令sudo passwd root&#xff0c…

交换排序——快速排序3 针对LeetCode某OJ的优化

交换排序——快速排序3 针对LeetCode某OJ的优化 快速排序的优化小区间优化三数取中三路划分优化 快速排序的优化 这篇优化围绕这个测试OJ展开。 912. 排序数组 - 力扣&#xff08;LeetCode&#xff09; 这个测试OJ在早期用快排还能过。但现在用快排不能过了。 因为这个OJ针…

【Vue笔记】基于vue3 + element-plus + el-dialog封装一个自定义的dialog弹出窗口组件

这篇文章,介绍一下如何使用vue3+element-plus中的el-dialog组件,自己封装一个通用的弹出窗口组件。运行效果如下所示: 目录 1.1、父子组件通信 1.2、自定义VDialog组件(【v-model】模式) 1.2.1、编写VDialog组件代码 1.2.2、使用VDialog组件 1.2.3、运行效果 1.3、自…

【支持向量机(SVM)】:算法原理及核函数

文章目录 1 SVM算法原理1.1 目标函数确定1.2 约束条件优化问题转换1.3 对偶问题转换1.4 确定超平面1.5 计算举例1.6 SVM原理小节 2 SVM核函数2.1 核函数的作用2.2 核函数分类2.3 高斯核函数2.3 高斯核函数API2.4 超参数 γ \gamma γ 1 SVM算法原理 1.1 目标函数确定 SVM思想…

【数据结构】树——链式存储二叉树的基础

写在前面 书接上文&#xff1a;【数据结构】树——顺序存储二叉树 本篇笔记主要讲解链式存储二叉树的主要思想、如何访问每个结点、结点之间的关联、如何递归查找每个结点&#xff0c;为后续更高级的树形结构打下基础。不了解树的小伙伴可以查看上文 文章目录 写在前面 一、链…

Java基于微信小程序+SSM的校园失物招领小程序

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

IDEA 2024.3 版本更新主要功能介绍

IDEA 2024.3 版本提供的新特性 IntelliJ IDEA 2024.3 的主要新特性&#xff1a; AI Assistant 增强 改进的代码补全和建议更智能的代码分析和重构建议Java 支持改进 支持 Java 21 的所有新特性改进的模式匹配和记录模式支持更好的虚拟线程调试体验开发工具改进 更新的 UI/UX 设…

Unity类银河战士恶魔城学习总结(P132 Merge skill tree with skill Manager 把技能树和冲刺技能相组合)

【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili 教程源地址&#xff1a;https://www.udemy.com/course/2d-rpg-alexdev/ 本章节实现了解锁技能后才可以使用技能&#xff0c;先完成了冲刺技能的锁定解锁 Dash_Skill.cs using System.Collections; using System…