1 引言

在构建基于知识库的问答系统时,"语义匹配" 是核心难题 —— 如何让系统准确识别 "表述不同但含义相同" 的问题?比如用户问 "对亲人的期待是不是欲?",系统能匹配到知识库中 "追名逐利是欲,那对孩子和亲人的有所期待是不是欲?" 的答案。

2 系统原来的实现方式

原来的系统是用 BERT 生成句向量并实现匹配的。核心逻辑集中在_get_embedding(生成向量)和search(匹配答案)两个方法中。

BERT 本身并不直接输出 "句向量",需要手动从模型输出中提取特征并处理,原来的核心思路是:

  • BERT 的每一层隐藏层都包含不同粒度的语义(浅层偏字面,深层偏抽象)
  • 融合最后 4 层的特征,并用手动设置的权重([0.15, 0.25, 0.35, 0.25])调整各层的重要性
  • 用 [CLS] 标记的向量代表整个句子的语义

生成向量后,需要计算用户问题与知识库中所有问题的相似度

BERT 预训练时通过 NSP 学到的 “句子间语义关联能力”,已经内化为模型参数。这种能力会间接体现在句向量中:

  • 例如,BERT 能理解 “亲人” 和 “孩子” 在 “亲近关系” 上的共性,“期待” 和 “期望” 的同义性 —— 这些都是 MLM 和 NSP 任务中学习到的语言知识;
  • 系统通过融合 BERT 隐藏层向量,间接利用了这些知识,让生成的句向量具备基础语义区分能力。

“加权融合隐藏层” 是为了弥补原始 BERT 句向量生成能力的不足而设计的关键步骤。它的核心作用是整合 BERT 不同层的语义特征,生成更全面的句向量

  • 浅层(如第 1-4 层):更关注字面信息(如词汇本身、简单搭配)。例如 “对亲人的期待”,浅层可能更关注 “亲人”“期待” 这些词的字面含义;
  • 深层(如第 9-12 层):更关注抽象语义(如句子整体意图、逻辑关系)。例如深层能捕捉到 “对亲人的期待” 本质是 “一种情感诉求”。

3  BERT 的痛点

BERT 作为预训练语言模型,在句子级任务中,它有两个明显局限:

3.1 计算效率低下

BERT 本身是为 “词级” 理解设计的(如完形填空、命名实体识别)。

通常获得句子向量的方法有两种:
1.计算所有 Token 输出向量的平均值
2.使用[cLs]位置输出的向量

若要计算两个句子的相似度,需将两个句子拼接成 [CLS] 句子A [SEP] 句子B [SEP] 作为输入,通过模型输出的 [CLS] 向量判断相似度。
计算量随候选集规模线性增长

3.2  句子级语义捕捉不足

BERT 的 [CLS] 向量虽能代表句子语义,但本质是为 “句子对分类” 任务优化的(如判断两个句子是否同义),并非专门为 “单个句子的语义嵌入” 设计。在问答系统中,常出现 “语义相近但表述差异大” 的问题匹配不准的情况。

具体来说,当用 BERT 做 “判断两个句子是否同义” 时,输入格式是固定的:[CLS] 句子A [SEP] 句子B [SEP]
BERT 输出的 [CLS] 向量(常用来代表整体语义),是 “针对句子 A 和句子 B 的关系” 生成的 —— 它包含的是 “两个句子如何关联” 的信息,而非 “句子 A 单独的语义” 或 “句子 B 单独的语义”。

单独输入句子 A([CLS] 句子A [SEP]),BERT 的 [CLS] 向量缺乏句子 B,生成的向量无法稳定代表句子 A 的语义。

句子对分类任务:输入两个句子,判断它们的关系(如 “是否同义”“是否存在因果关系”“是否矛盾”)。
例:输入 “我喜欢苹果” 和 “苹果是我爱的水果”,模型判断 “同义”(输出分类结果)。

单个句子的语义嵌入:为单个句子生成一个向量(数字列表),这个向量需要 “完整代表句子的语义”—— 即 “语义越近的句子,向量越相似”。
例:“我喜欢苹果” 和 “我喜爱苹果” 的向量应该非常接近;和 “我讨厌香蕉” 的向量应该差异很大。

举例

  • BERT 就像一台 “双人对比秤”:它擅长测量 “两个人的体重差”(句子对关系),但如果单独测一个人的体重(单个句子向量),结果可能不准(因为它的刻度是为 “对比” 设计的)。

  • 而 “单个句子的语义嵌入” 需要的是 “单人精准秤”:能稳定测量单个人的体重,且两个人的体重数值可以直接比较(比如 “60kg” 和 “61kg” 接近,“60kg” 和 “80kg” 差异大)。

4 Sentence-BERT(SBERT)

Sentence-BERT(SBERT)是专门为 "句子级语义任务" 设计的模型,它在 BERT 基础上做了针对性优化,完美解决了上述问题。

Sentence-BERT(SBERT)的作者对预训练的 BERT 进行修改:

微调+使用 Siamese and TripletNetwork(孪生网络和三胞胎网络)生成具有语义的句子 Embedding 向量。

语义相近的句子,其 Embedding 向量距离就比较近,从而可以使用余弦相似度、曼哈顿距离、欧氏距离等找出语义相似的句子。这样 SBERT 可以完成某些新的特定任务,比如聚类、基于语义的信息检索等

4.1 孪生网络(Siamese

模型结构

核心思想是 “用两个共享参数的子网络,学习两个输入的相似度”。它不像普通分类网络那样直接输出类别,而是专注于判断 “两个输入是否相似”。

如下图

  • 包含两个结构完全相同、参数完全共享的子网络(可以是 CNN、RNN、BERT 等任意网络);
  • 两个子网络接收不同输入(如两个句子),分别提取特征;
  • 最后通过一个 “对比层” 计算两个特征的相似度,输出 “两个输入是否相似” 的判断。

SBERT本质上是 “孪生网络 + BERT + 对比学习” 的组合,专门解决句子语义相似度问题。

SBERT 的两个子网络就是 BERT,通过共享参数提取句子向量。传入两个句子,通过计算损失,反向传播更新参数。对比层用余弦相似度计算向量距离,同时通过对比学习(训练时让相似句子向量更近)优化向量分布;

(注意传入第一个句子时没有办法进行梯度回传更新参数)

损失函数

输入:两个待比较的对象

  • 输入 A:用户问题 “对亲人的期待是不是欲?”

  • 输入 B:知识库问题 “对孩子的期待属于欲望吗?”

特征提取:两个子网络生成特征向量

  • 输入 A 进入子网络 1,生成特征向量 V1(比如通过 BERT 提取的语义向量);

  • 输入 B 进入子网络 2(和子网络 1 结构、参数完全相同),生成特征向量 V2;

  • 关键:因为参数共享,两个子网络对 “相似语义” 的理解标准完全一致(比如 “期待” 和 “期望” 会被映射到相近的向量)。

(这里还是通过计算所有 Token 输出向量的平均值或者使用[cLs]位置输出的向量来获得句向量)

对比:计算向量相似度,输出判断结果

  • 通过 “对比层” 计算 V1 和 V2 的相似度(如余弦相似度、欧氏距离);

  • 若相似度高于阈值(如 0.8),判断为 “相似”(匹配成功);否则为 “不相似”。

5 总结

对比原始 BERT 的实现,SBERT 的优势明显:

  • 无需手动提取隐藏层(省去hidden_states[-4:]相关逻辑)
  • 无需加权融合(模型内置最优融合策略)
  • 支持批量编码(model.encode(questions)直接处理列表)

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Word和WPS文字中把全角数字全部改为半角

大部分情况下我们在Word或WPS文字中使用的数字或标点符号都是半角,但是有时不小心按错了快捷键或者点到了输入法的全角半角切换图标,就输入了全角符号和数字。不用担心,使用它们自带的全角、半角转换功能即可快速全部转换回来。一、为什么会输…

数据结构的基本知识

一、集合框架1、什么是集合框架Java集合框架(Java Collection Framework),又被称为容器(container),是定义在java.util包下的一组接口(interfaces)和其实现类(classes).主要表现为把多个元素(element)放在一个单元中,用于对这些元素进行快速、便捷的存储(store&…

WebStack-Hugo | 一个静态响应式导航主题

WebStack-Hugo | 一个静态响应式导航主题 #10 shenweiyan announced in 1.3-折腾 WebStack-Hugo | 一个静态响应式导航主题#10 ​编辑shenweiyan on Oct 23, 2023 6 comments 7 replies Return to top shenweiyan on Oct 23, 2023 Maintainer Via:我给自己…

01 基于sklearn的机械学习-机械学习的分类、sklearn的安装、sklearn数据集、数据集的划分、特征工程中特征提取与无量纲化

文章目录机械学习机械学习分类1. 监督学习2. 半监督学习3. 无监督学习4. 强化学习机械学习的项目开发步骤scikit-learn1 scikit-learn安装2 sklearn数据集1. sklearn 玩具数据集鸢尾花数据集糖尿病数据集葡萄酒数据集2. sklearn现实世界数据集20 新闻组数据集3. 数据集的划分特…

携全双工语音通话大模型亮相WAIC,Soul重塑人机互动新范式

近日,WAIC 2025在上海隆重开幕。作为全球人工智能领域的顶级盛会,本届WAIC展览聚焦底层能力的演进与具体垂类场景的融合落地。坚持“模应一体”方向、立足“AI社交”的具体场景,Soul App此次携最新升级的自研端到端全双工语音通话大模型亮相&…

第2章 cmd命令基础:常用基础命令(1)

Hi~ 我是李小咖,主要从事网络安全技术开发和研究。 本文取自《李小咖网安技术库》,欢迎一起交流学习🫡:https://imbyter.com 本节介绍的命令有目录操作(cd)、清屏操作(cls)、设置颜色…

Java 10 新特性解析

Java 10 新特性解析 文章目录Java 10 新特性解析1. 引言2. 本地变量类型推断(JEP 286)2.1. 概述2.2. 使用场景2.3. 限制2.4. 与之前版本的对比2.5. 风格指南2.6. 示例代码2.7. 优点与注意事项3. 应用程序类数据共享(JEP 310)3.1. …

【WRF工具】服务器中安装编译GrADS

目录 安装编译 GrADS 所需的依赖库 conda下载库包 安装编译 GrADS 编译前检查依赖可用性 安装编译 GrADS 参考 安装编译 GrADS 所需的依赖库 以统一方式在 $HOME/WRFDA_LIBS/grads_deps 下安装所有依赖: # 选择一个目录用于安装所有依赖库 export DIR=$HOME/WRFDA_LIBS库包1…

数据结构之队列(C语言)

1.队列的定义: 队列(Queue)是一种基础且重要的线性数据结构,遵循先进先出(FIFO)​​ 原则,即最早入队的元素最先出队,与栈不同的是出队列的顺序是固定的。队列具有以下特点&#xff…

C#开发基础之深入理解“集合遍历时不可修改”的异常背后的设计

前言 欢迎关注【dotnet研习社】&#xff0c;今天我们聊聊一个基础问题“集合已修改&#xff1a;可能无法执行枚举操作”背后的设计。 在日常 C# 开发中&#xff0c;我们常常会操作集合&#xff08;如 List<T>、Dictionary<K,V> 等&#xff09;。一个新手开发者极…

【工具】图床完全指南:从选择到搭建的全方位解决方案

前言 在数字化内容创作的时代&#xff0c;图片已经成为博客、文档、社交媒体等平台不可或缺的元素。然而&#xff0c;如何高效、稳定地存储和分发图片资源&#xff0c;一直是内容创作者面临的重要问题。图床&#xff08;Image Hosting&#xff09;作为专门的图片存储和分发服务…

深度学习篇---PaddleDetection模型选择

PaddleDetection 是百度飞桨推出的目标检测开发套件&#xff0c;提供了丰富的模型库和工具链&#xff0c;覆盖从轻量级移动端到高性能服务器的全场景需求。以下是核心模型分类、适用场景及大小选择建议&#xff08;通俗易懂版&#xff09;&#xff1a;一、主流模型分类及适用场…

cmseasy靶机密码爆破通关教程

靶场安装1.首先我们需要下载一个cms靶场CmsEasy_7.6.3.2_UTF-8_20200422,下载后解压在phpstudy_pro的网站根目录下。2.然后我们去访问一下安装好的网站&#xff0c;然后注册和链接数据库3.不知道自己数据库密码的可以去小皮面板里面查看4.安装好后就可以了来到后台就可以了。练…

【C语言】指针深度剖析(一)

文章目录一、内存和地址1.1 内存的基本概念1.2 编址的原理二、指针变量和地址2.1 取地址操作符&#xff08;&&#xff09;2.2 指针变量和解引用操作符&#xff08;*&#xff09;2.2.1 指针变量2.2.2 指针类型的解读2.2.3 解引用操作符2.3 指针变量的大小三、指针变量类型的…

半导体企业选用的跨网文件交换系统到底应该具备什么功能?

在半导体行业的数字化转型过程中&#xff0c;跨网文件交换已成为连接研发、生产、供应链的关键纽带。半导体企业的跨网文件交换不仅涉及设计图纸、工艺参数等核心知识产权&#xff0c;还需要满足跨国协同、合规审计等复杂需求。那么&#xff0c;一款适合半导体行业的跨网文件交…

影刀RPA_初级课程_玩转影刀自动化_网页操作自动化

声明&#xff1a;相关内容来自影刀学院&#xff0c;本文章为自用笔记&#xff0c;切勿商用&#xff01;&#xff08;若有侵权&#xff0c;请联络删除&#xff09; 1. 基本概念与操作 1.1 正确处理下拉框元素&#xff08;先判断页面元素&#xff0c;后进行流程编制&#xff09;…

Spark初探:揭秘速度优势与生态融合实践

更多推荐阅读 Spark与Flink深度对比&#xff1a;大数据流批一体框架的技术选型指南-CSDN博客 LightProxy使用操作手册-CSDN博客 Sentry一看就会教程_sentry教程-CSDN博客 微前端架构解析&#xff1a;核心概念与主流方案特性对比_微前端方案对比-CSDN博客 目录 Spark为何比Hadoo…

详谈OSI七层模型和TCP/IP四层模型以及tcp与udp为什么是4层,http与https为什么是7层

一、网络模型&#xff1a;OSI七层 vs TCP/IP四层OSI七层模型 (理论参考模型):目的&#xff1a;提供一个标准化的理论框架&#xff0c;用于理解网络通信过程和各层的功能划分&#xff0c;促进不同厂商设备的互操作性。它是一个理想化的模型。分层 (从下到上):物理层&#xff1a;…

ClickHouse 高性能实时分析数据库-索引与数据跳过(查询的“瞬移”能力)

告别等待&#xff0c;秒级响应&#xff01;这不只是教程&#xff0c;这是你驾驭PB级数据的超能力&#xff01;我的ClickHouse视频课&#xff0c;凝练十年实战精华&#xff0c;从入门到精通&#xff0c;从单机到集群。点开它&#xff0c;让数据处理速度快到飞起&#xff0c;让你…

Jetpack - Room(Room 引入、Room 优化)

一、Room 引入 1、基本介绍 Room 在 SQLite 上提供了一个抽象层&#xff0c;以便在充分利用 SQLite 的强大功能的同时&#xff0c;能够流畅地访问数据库&#xff0c;官方强烈建议使用 Room 而不是 SQLite 2、演示 &#xff08;1&#xff09;Setting 模块级 build.gradle depend…