transformers实现一个检索机器人(一)

news2024/12/13 4:57:17

简介

检索机器人是一种能够自动搜索和提供信息的系统,它可以帮助我们快速找到需要的信息。这类机器人通常使用自然语言处理(NLP)技术来理解用户的查询,并利用搜索引擎或数据库来获取相关信息。
那么我们要通过transforme实现什么样的检索机器人了。一个简化版的检索机器人,本地知识库+文本相似度(自然语言处理(NLP))。
本地知识库使用到了向量模型,文本相似度就是自然语言处理技术了。
检索机器人计划用三篇文章进行讲解。

文本相似度训练

文本相似度简介

文本相似度模型是用来衡量两个或多个文本片段之间的相似程度的工具。这些模型在许多应用场景中都非常有用,例如信息检索、推荐系统、文档去重、问答系统等。

1. 基本概念
  • 文本相似度:衡量两段文本内容上的接近程度。相似度可以是基于词汇、语法结构、语义等多个维度。
  • 向量表示:将文本转换为数值向量,以便于计算相似度。
2. 常用方法
a. 基于词频的方法
  • TF-IDF (Term Frequency-Inverse Document Frequency):通过计算每个词在文档中的频率(TF)和逆文档频率(IDF)来表示文本。然后使用余弦相似度或其他距离度量方法来计算相似度。
  • BoW (Bag of Words):将文本表示成词袋模型,忽略词序,只考虑词频。然后计算向量间的相似度。
b. 基于词嵌入的方法
  • Word Embeddings (如Word2Vec, GloVe):将每个词映射到一个高维向量空间中,使得语义相似的词在向量空间中距离较近。可以通过平均词向量或加权平均词向量来表示整个句子。
  • Sentence Embeddings (如Universal Sentence Encoder, BERT):直接将整个句子映射到一个向量,捕获句子的语义信息。这些模型通常使用预训练的神经网络,能够更好地理解上下文。
c. 基于深度学习的方法
  • Siamese Networks:使用相同的网络结构对两个输入进行编码,然后比较它们的输出向量。常用于孪生网络结构,通过对比损失函数来训练模型。
  • Transformer-based Models (如BERT, RoBERTa):利用Transformer架构的强大表征能力,生成高质量的文本向量。这些模型通常在大规模语料上进行预训练,并可以在特定任务上进行微调。
3. 计算相似度
  • 余弦相似度 (Cosine Similarity):计算两个向量之间的夹角余弦值,范围在-1到1之间,值越接近1表示越相似。
  • 欧氏距离 (Euclidean Distance):计算两个向量之间的直线距离,值越小表示越相似。
  • 曼哈顿距离 (Manhattan Distance):计算两个向量在各维度上的绝对差值之和,值越小表示越相似。
  • Jaccard相似度 (Jaccard Similarity):适用于集合数据,计算两个集合的交集与并集的比值。
4. 应用示例

假设我们有两个句子:

句子A: “我喜欢吃苹果”
句子B: “我爱吃水果”

a. 基于词嵌入的方法

使用预训练的词嵌入模型(如GloVe)将每个词转换为向量。
计算每个句子的平均词向量。
使用余弦相似度计算两个句子向量之间的相似度。

from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

# 假设我们已经得到了每个词的词向量
word_vectors = {
    '我': [0.1, 0.2, 0.3],
    '喜欢': [0.4, 0.5, 0.6],
    '吃': [0.7, 0.8, 0.9],
    '苹果': [0.2, 0.1, 0.3],
    '爱': [0.5, 0.6, 0.7],
    '水果': [0.3, 0.4, 0.5]
}

# 计算句子A和句子B的平均词向量
sentence_A_vector = np.mean([word_vectors[word] for word in "我喜欢吃苹果".split()], axis=0)
sentence_B_vector = np.mean([word_vectors[word] for word in "我爱吃水果".split()], axis=0)

# 计算余弦相似度
similarity = cosine_similarity([sentence_A_vector], [sentence_B_vector])[0][0]
print(f"相似度: {similarity:.4f}")
b. 基于预训练模型的方法

使用预训练的句子嵌入模型(如Universal Sentence Encoder)。
直接获取句子的嵌入向量。
计算余弦相似度。


from sentence_transformers import SentenceTransformer
import torch

# 加载预训练模型
model = SentenceTransformer('paraphrase-MiniLM-L6-v2')

# 获取句子嵌入
sentence_A_embedding = model.encode("我喜欢吃苹果")
sentence_B_embedding = model.encode("我爱吃水果")

# 计算余弦相似度
cosine_sim = torch.nn.functional.cosine_similarity(
    torch.tensor(sentence_A_embedding).unsqueeze(0),
    torch.tensor(sentence_B_embedding).unsqueeze(0)
)

print(f"相似度: {cosine_sim.item():.4f}")

文本相似度模型通过将文本转换为向量,并使用各种距离度量方法来计算相似度。从简单的基于词频的方法到复杂的基于深度学习的方法,选择合适的模型取决于具体的应用场景和需求。现代预训练模型如BERT和Sentence Transformers提供了强大的语义理解能力,使得文本相似度计算更加准确和高效。

训练文本相似度

简介中介绍了文本相似度一些基础知识,核心点是将文本向量化,在计算两个向量之间的距离来帮别相似度。实际上文本相似你也可以看做是文本分类,两个话是否为一类,是不是一样的。
那么这次的训练就使用BERT来进行。
在写训练代码前,先考虑对数据集处理,怎么样的数据方便模型进行训练。使用BERT那么处理就是

[CLS] ............ [SEP] ........ [SEP]

如果数据集是这种一对一的:

SentenceASentenceBLabel
找一部小时候的动画片求一部小时候的动画片。谢了1
等一下马上来马上来1
不对明天不是37度明天要做什么了0
这事什么给忘了路口有个红蓝房子0

可以使用这种方式对数据进行处理和评估进行训练。
在这里插入图片描述
数据进行这样的整理
在这里插入图片描述
评估就计算softmax就可以了。

如果数据是一对多的如:

SentenceASentenceBLabel
找一部小时候的动画片求一部小时候的动画片。谢了1
找一部小时候的动画片马上来0
找一部小时候的动画片明天要做什么了0
这事什么给忘了路口有个红蓝房子0
那么用刚才的数据处理方式效率就比较低了,可以使用这种方式。

在这里插入图片描述
两个改动的地方不多,一个是模型,一个评估的处理,其它都是一致的。

代码实现
# 文本相似度实例

# Step1 导入相关包
from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset
import evaluate
from transformers import DataCollatorWithPadding
from transformers import pipeline, TextClassificationPipeline

# Step2 加载数据集
dataset = load_dataset("json", data_files="./train_pair_1w.json", split="train")
print(dataset)
#第一条数据
s = dataset[0]
print(s)


# Step3 划分数据集(训练数据和测试数据)
datasets = dataset.train_test_split(test_size=0.2)
print(datasets)

# Step4 数据集预处理
tokenizer = AutoTokenizer.from_pretrained("chinese-macbert-large")

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)
print(tokenized_datasets)

print(tokenized_datasets["train"][0])

# Step5 创建模型
model = AutoModelForSequenceClassification.from_pretrained("chinese-macbert-large", num_labels=1)

# Step6 创建评估函数
acc_metric = evaluate.load("./metric_accuracy.py")
f1_metirc = evaluate.load("./metric_f1.py")


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]
    acc = acc_metric.compute(predictions=predictions, references=labels)
    f1 = f1_metirc.compute(predictions=predictions, references=labels)
    acc.update(f1)
    return acc


# Step7 创建TrainingArguments
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 打印的频率
                               eval_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

# Step8 创建Trainer
trainer = Trainer(model=model,
                  args=train_args,
                  tokenizer=tokenizer,
                  train_dataset=tokenized_datasets["train"],
                  eval_dataset=tokenized_datasets["test"],
                  data_collator=DataCollatorWithPadding(tokenizer=tokenizer),
                  compute_metrics=eval_metric)

# Step9 模型训练
trainer.train()


# Step10 模型评估
trainer.evaluate(tokenized_datasets["test"])

# Step11 模型预测
model.config.id2label = {0: "不相似", 1: "相似"}

pipe = pipeline("text-classification", model=model, tokenizer=tokenizer, device=0)


result = pipe({"text": "我喜欢长沙", "text_pair": "天气怎样"}, function_to_apply="none")
result["label"] = "相似" if result["score"] > 0.5 else "不相似"
print(result)

这里我使用本地模型进行训练,直接使用这段代码是跑不起来的,需要将chinese-macbert-large替换为hfl/chinese-macbert-base,网络需要kexue上网。如果不能进行kexue上网,那么可以到这个地址下载模型到本地: 地址

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

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

相关文章

开源ISP介绍(2)————嵌入式Vitis搭建

Vivado搭建参考前一节Vivado基于IP核的视频处理框架搭建: 开源ISP介绍(1)——开源ISP的Vivado框架搭建-CSDN博客 导出Hardware 在vivado中导出Hardware文件,成功综合—实现—生成比特流后导出硬件.xsa文件。(注意导…

力扣-图论-2【算法学习day.52】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非…

【PlantUML系列】序列图(二)

目录 一、参与者 二、消息交互顺序 三、其他技巧 3.1 改变参与者的顺序 3.2 使用 as 重命名参与者 3.3 注释 3.4 页眉和页脚 一、参与者 使用 participant、actor、boundary、control、entity 和 database 等关键字来定义不同类型的参与者。例如: Actor&…

如何利用内链策略提升网站的整体权重?

内链是谷歌SEO中常常被低估的部分,实际上,合理的内链策略不仅能帮助提升页面间的关联性,还可以增强网站的整体权重。通过正确的内链布局,用户可以更流畅地浏览你的网站,谷歌爬虫也能更快地抓取到更多页面,有…

zotero中pdf-translate插件和其他插件的安装

1.工具–》插件 2.找插件 3.点击之后看到一堆插件 4.找到需要的,例如pdf-translate 5.点击进入,需要看一下md文档了解下,其实最重要的就是找到特有的(.xpi file) 6.点击刚刚的蓝色链接 7.下载并保存xpi文件 8.回到zotero,安装并使…

Datax遇到的坑

公司数据中台产品,要使用airflow调datax任务实现离线作业的同步。 一、python版本问题 执行python ..datax.py .json时 报错 在运行 Python 脚本时,代码中使用了 Python 2 的 print语法,当前的环境是 Python 3。在 Python 3 中&#xff0…

容易被遗忘的测试用例

网络服务器启动了吗?应用程序服务器启动了吗?数据库上线了吗?测试数据是否预先加载到数据库中?每当我们准备开始测试应用程序时,一切都应该已经准备妥当。 然而,当测试开始后,我们可能会漏掉一些…

机器学习与深度学习-2-Softmax回归从零开始实现

机器学习与深度学习-2-Softmax回归从零开始实现 1 前言 内容来源于沐神的《动手学习深度学习》课程,本篇博客对于Softmax回归从零开始实现进行重述,依旧是根据Python编程的PEP8规范,将沐神的template代码进行简单的修改。近期有点懒散哈哈哈…

文本生成类(机器翻译)系统评估

在机器翻译任务中常用评价指标:BLEU、ROGUE、METEOR、PPL。 这些指标的缺点:只能反应模型输出是否类似于测试文本。 BLUE(Bilingual Evaluation Understudy):是用于评估模型生成的句子(candidate)和实际句子(referen…

保护数字资产:iOS 加固在当前安全环境中的重要性

随着互联网和手机的发展,APP在我们的日常生活中已经变得无处不在,各大平台的应用程序成为了黑客攻击的主要目标。尤其在 2024 年,随着数据泄露和隐私侵犯事件的频发,手机应用的安全问题再次成为公众关注的焦点。近期,多…

基于HTML和CSS的校园网页设计与实现

摘要 随着计算机、互联网与通信技术的进步,Internet在人们的学习、工作和生活中的地位也变得越来越高,校园网站已经成为学校与学生,学生与学生之间交流沟通的重要平台,对同学了解学校内发生的各种事情起到了重要的作用。学校网站…

Secured Finance 推出 TVL 激励计划以及基于 FIL 的稳定币

Secured Finance 是新一代 DeFi 2.0 协议,其正在推出基于 FIL 的稳定币、固定收益市场以及具有吸引力的 TVL 激励计划,以助力 Filecoin 构建更强大的去中心化金融生态体系,并为 2025 年初 Secured Finance 协议代币的推出铺平道路。Secure Fi…

WebRover :一个功能强大的 Python 库,用于从 Web 内容生成高质量的数据集,专为训练大型语言模型和 AI 应用程序而设计。

2024-11-30 ,由Area-25团队开发的一个专门用于生成高质量网络内容数据集的Python库。该数据集旨在为大型语言模型(LLM)和人工智能应用的训练提供丰富的数据资源。 数据集地址:WebRover Dataset|自然语言处理数据集|AI模型训练数据…

基于ZYNQ-7000系列的FPGA学习笔记7——按键控制蜂鸣器(模块化编写)

基于ZYNQ-7000系列的FPGA学习笔记7——按键控制蜂鸣器(模块化编写) 1. 实验要求2. 功能分析3. 模块设计4. 波形图4.1 按键消抖模块4.2 按键控制蜂鸣器模块 5.代码编写5.1 rtl代码5.2 测试代码 6. 代码仿真7. 添加约束文件并分析综合 在上期的内容中&…

Android 分词的两种方式

前言: 本文分别介绍了原生和三方(Jieba)两种分词方式的使用和注意事项 1、安卓原生BreakIterator分词 比较简单,但是效果不太行 /*** 功能:原生分词* 参数:text:需要分词的语句* 返回值:return&#xf…

python之Django连接数据库

文章目录 连接Mysql数据库安装Mysql驱动配置数据库信息明确连接驱动定义模型在模型下的models.py中定义表对象在settings.py 中找到INSTALLED_APPS添加创建的模型 测试testdb.py中写增删改查操作urls.py添加请求路径启动项目进行测试 连接Mysql数据库 安装Mysql驱动 pip inst…

JavaWeb学习(1)(同步或异步请求、依赖jQuery简单实现Ajax技术)

目录 一、Web的基本流程与页面局部刷新。 (1)web开发时基本流程。 (2)页面的"全局刷新"与"局部刷新"。 二、Ajax技术。 (1)基本介绍。 (2)基本特点。 1、与服务…

spark sql 环境安装,java 默认路径和 安装配置!

yum安装java 查看默认路径 update-alternatives --config java # Java 环境变量 export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.412.b08-1.el7_9.x86_64/jreexport PATH$JAVA_HOME/bin:$PATH# Spark 环境变量 export SPARK_HOME/home/vagrant/soft/sparkexport PATH…

网络层总结

网络层任务: 分组 从源主机 经多个网络/多段链路 传输到目的主机 两种重要的功能: 分组转发、 路由选择 网络层向其上层提供的两种服务 —— 面向连接的虚电路服务、无连接的数据报服务 面向连接的虚电路服务: 可靠通…

python学习笔记15 python中的类

上一篇我们介绍了python中的库 ,学习了一些常见的内置库。详细内容可点击–>python学习笔记14 python中的库,常见的内置库(random、hashlib、json、时间、os) 这一篇我们来看一下python中的类 创建一个类 class 类的名称():de…