CoSENT:比sentence bert更好的向量表征

news2024/11/27 20:29:21

本文是对https://spaces.ac.cn/archives/8847文章的总结

有监督的文本表征主流方案是sentence bert,虽然sentence BERT效果还行,但是存在训练和预测不一致的问题,而一些文章也指出而如果直接优化预测目标cos值,效果往往特别差(如CoSENT(一):比Sentence-BERT更有效的句向量方案,我也尝试了下,效果貌似不是太差,甚至比sentence bert好一点)

直接优化Cos方案

直接优化cos值通常有如下几种损失函数方案,其中t∈{0,1}表示是否相似,都是让正样本对的相似度尽可能大、负样本对的相似度尽可能小
t ⋅ ( 1 − cos ⁡ ( u , v ) ) + ( 1 − t ) ⋅ ( 1 + cos ⁡ ( u , v ) ) t \cdot(1-\cos (u, v))+(1-t) \cdot(1+\cos (u, v)) t(1cos(u,v))+(1t)(1+cos(u,v))

t ⋅ ( 1 − cos ⁡ ( u , v ) ) 2 + ( 1 − t ) ⋅ cos ⁡ 2 ( u , v ) t \cdot(1-\cos (u, v))^2+(1-t) \cdot \cos ^2(u, v) t(1cos(u,v))2+(1t)cos2(u,v)

t ⋅ ( 1 − c o s ( u , v ) ) + ( 1 − t ) ⋅ ( m a x ( 0 , c o s ( u , v ) − m a r g i n ) ) t\cdot(1-cos(u,v))+(1-t)\cdot(max(0, cos(u,v)-margin)) t(1cos(u,v))+(1t)(max(0,cos(u,v)margin))

文章CoSENT(一):比Sentence-BERT更有效的句向量方案针对直接优化cos效果差,给出如下解释:

文本匹配语料中标注出来的负样本对都是“困难样本”,常见的是语义不相同但字面上有比较多的重合。此时,如果我们用式(1)作为损失函数,那么正样本对的目标是1、负样本对的目标是-1,如果我们用式(2)作为损失函数,那么正样本对的目标是1、负样本对的目标是0。不管哪一种,负样本对的目标都“过低”了,因为对于“困难样本”来说,虽然语义不同,但依然是“相似”,相似度不至于0甚至-1那么低,如果强行让它们往0、-1学,那么通常的后果就是造成过度学习,从而失去了泛化能力,又或者是优化过于困难,导致根本学不动

为了证明上述结论,作者用了如式三所示的损失函数进行验证,margin取0.7,即负样本优化到0.7即不需要继续优化,从而就不那么容易过度学习了。但这仅仅是缓解,效果也很难达到最优,而且如何选取这个margin的值依然是比较困难的问题

Sentence-Bert

sentence-bert采用了训练和预测不一致的方式,它的训练阶段是将u,v,|u−v|(其中|u−v|是指u−v的每个元素都取绝对值后构成的向量)拼接起来做为特征,后面接一个全连接层做2分类(如果是NLI数据集则是3分类),而在预测阶段,还是跟普通的句向量模型一样,先计算句向量然后算cos值作为相似度。如下图所示:
在这里插入图片描述
关于sentence-bert的有效性,作者也给出如下思考:

一般情况下,哪怕负样本对是“困难样本”,总体而言正样本对的字面相似度是大于负样本对的,这样一来,哪怕是对于初始模型,正样本对的差距∥u−v∥总体较小,而负样本对的差距∥u−v∥总体较大,我们可以想象正样本对的u−v主要分布在一个半径较小的球面附近,而负样本对的u−v分布在一个半径较大的球面附近,也就是说,初始阶段u−v本身就有聚类倾向,我们接下来只需要根据标签信息强化这种聚类倾向,使得正样本对的u−v依然保持更小,负样本对的u−v保持更大。一个直接的做法就是u−v后面接一个Dense分类器,然而常规的分类器是基于内积的,它没法区分两个分布在不同球面的类别,所以我们加上绝对值变成|u−v|,将球面变为局部的球盖(或者说将球体变成锥形),此时就可以用Dense分类层来分类了。这就是笔者认为的|u−v|的来源。

CoSENT

cosent的提出目标是直接优化cos值,记 Ω pos  \Omega_{\text {pos }} Ωpos 为所有的正样本对集合, Ω neg  \Omega_{\text {neg }} Ωneg 为所有的负样本对集合,我们希望对于任意的正样本对 ( i , j ) ∈ Ω p o s ‾ (i, j) \in \Omega_{p o s} \overline{ } (i,j)Ωpos和负样本对 ( k , l ) ∈ Ω n e g ‾ (k, l) \in \Omega_{neg} \overline{ } (k,l)Ωneg,都有

cos ⁡ ( u i , u j ) > cos ⁡ ( u k , u l ) \cos \left(u_i, u_j\right)>\cos \left(u_k, u_l\right) cos(ui,uj)>cos(uk,ul)

其中 u i u j u k u l u_i u_j u_k u_l uiujukul是各自的句向量,也就是我们只希望正样本对的相似度大于负样本对的相似度,至于大多少,模型自己决定就好。

因此可以使用如下损失, 其中 s i s_i si是负样本对的相似度, s j s_j sj是正样本对的相似度

l o s s = log ⁡ ( 1 + ∑ i ∈ Ω n e g , j ∈ Ω p o s e s i − s j ) loss = \log \left(1+\sum_{i \in \Omega_{n e g}, j \in \Omega_{p o s}} e^{s_i-s_j}\right) loss=log1+iΩneg,jΩposesisj

上式的由来可参考将“softmax+交叉熵”推广到多标签分类问题,本文在此处略微介绍:
分类任务中交叉熵损失如下:

− log ⁡ e s t ∑ i = 1 n e s i = − log ⁡ 1 ∑ i = 1 n e s i − s t = log ⁡ ∑ i = 1 n e s i − s t = log ⁡ ( 1 + ∑ i = 1 , i ≠ t n e s i − s t ) -\log \frac{e^{s t}}{\sum_{i=1}^n e^{s_i}}=-\log \frac{1}{\sum_{i=1}^n e^{s_i-s_t}}=\log \sum_{i=1}^n e^{s_i-s_t}=\log \left(1+\sum_{i=1, i \neq t}^n e^{s_i-s_t}\right) logi=1nesiest=logi=1nesist1=logi=1nesist=log1+i=1,i=tnesist

而上式又可有如下近似

log ⁡ ( 1 + ∑ i = 1 , i ≠ t n e s i − s t ) ≈ max ⁡ ( 0 s 1 − s t ⋮ s t − 1 − s t s t + 1 − s t ⋮ s n − s t ) \log \left(1+\sum_{i=1, i \neq t}^n e^{s_i-s t}\right) \approx \max \left(\begin{array}{c} 0 \\ s_1-s_t \\ \vdots \\ s_{t-1}-s_t \\ s_{t+1}-s_t \\ \vdots \\ s_n-s_t \end{array}\right) log1+i=1,i=tnesistmax0s1stst1stst+1stsnst

所有的非目标类得分 s 1 , ⋯ , s t − 1 , s t + 1 , ⋯ , s n {s_1,⋯,s_{t−1},s_{t+1},⋯,s_{n}} s1,,st1,st+1,,sn跟目标类得分 s t {s_t} st两两作差比较,它们的差的最大值都要尽可能小于零,所以实现了“目标类得分都大于每个非目标类的得分”的效果

简单来说,就是如果你希望最终实现 s i < s j s_i<s_j si<sj,那么就往log里边加入 e s i − s j e^{s_i−s_j} esisj一项。所以最后可以得到CoSENT损失函数形式如下:

c o s e n t _ l o s s = log ⁡ ( 1 + ∑ ( i , j ) ∈ Ω pos  , ( k , l ) ∈ Ω neg  e λ ( cos ⁡ ( u k , u l ) − cos ⁡ ( u i , u j ) ) ) cosent\_loss = \log \left(1+\sum_{(i, j) \in \Omega_{\text {pos }},(k, l) \in \Omega_{\text {neg }}} e^{\lambda\left(\cos \left(u_k, u_l\right)-\cos \left(u_i, u_j\right)\right)}\right) cosent_loss=log1+(i,j)Ωpos ,(k,l)Ωneg eλ(cos(uk,ul)cos(ui,uj))

其中λ>0是一个超参数,实验中作者取了20。CoSENT损失函数的含义就是:在一个batch中任意一个负样本对的相似度都要小于任意一个正样本对的相似度

实验结果

下图展示了作者所作的实验,可见CoSENT的优异结果
在这里插入图片描述

代码实现

from torch import nn
import torch
import torch.nn.functional as F

class CoSENTLoss(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, embed1, embed2, label):
        if type(label) == list:
            label = torch.tensor(label, device=embed1.device)
        # 单位化
        norm_embed1 = F.normalize(embed1, p=2, dim=1, eps=1e-8)
        norm_embed2 = F.normalize(embed2, p=2, dim=1, eps=1e-8)
        # 计算相似度 shape=(batch_size, )
        sim = torch.sum(norm_embed1*norm_embed2, dim=1)*20
        # sim[:, None]改变形状(n, 1), sim[None, :]改变形状(1, n)
        # sim.shape = [bs, bs], 任意相似相减,计算si-sj
        sim = sim[:, None]-sim[None, :]
        # 确定si-sj时si是负样本,sj是正样本;但满足该条件时结果为1
        label = label[:, None]<label[None, :]
        label = label.float()
        # label为0的位置对应的si为正样本, 将该位置为极小的一个数x[-1e12],最终e^(-x)为0忽略不计
        sim = sim-(1-label)*1e12
        # 最前面加一个0元素,通过指数函数后得到对应公式中的1
        sim = torch.cat((torch.zeros(1).to(sim.device), sim.view(-1)), dim=0)
        # 最后求log sum exp
        loss = torch.logsumexp(sim, dim=0)
        return loss


if __name__ == "__main__":
    embed_a = torch.rand(4, 10)
    embed_b = torch.rand(4, 10)
    label = [1, 0, 1, 0]
    cosent_loss = CoSENTLoss()
    loss_value = cosent_loss(embed_a, embed_b, label)
    print(loss_value.item())

参考

CoSENT(一):比Sentence-BERT更有效的句向量方案
将“softmax+交叉熵”推广到多标签分类问题

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

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

相关文章

方寸间联结世界,中国直播电商如何诠释“人类命运共同体”?

十几个人凝神屏息地盯着屏幕&#xff0c;仿佛静止了一般&#xff0c;眼睛一眨不眨&#xff0c;生怕错过了什么。直到听到屏幕另一端终于有了动静&#xff0c;悬在他们心里的石头才落下——“谢谢大家的支持&#xff0c;全部没有了。” 话音未落&#xff0c;这边已爆发了欢呼声…

只工作,不上班,「远程办公」是不是理想的工作方式?

在我们90后眼中&#xff0c;上班和工作是两回事。准确来说。上班是为别人做事&#xff0c;而工作是为自己。 圆桌派有一期的话题是“不想工作怎么破&#xff1f;”当时&#xff0c;几位嘉宾说&#xff1a;“不是不想工作&#xff0c;是不想上班”&#xff0c;“周围很多年轻人…

【linux】之 kubernetes安装

一、容器编排工具 docker machinedocker composedocker swarm docker servicedocker stack kubernetesmesosmarathon 二、PaaS平台 OpenShiftRancher 三、认识kubernetes 官方网址 https://kubernetes.io/ https://kubernetes.io/zh/ 中文社区 http://docs.kubernetes.org…

libco 宏分析

// 下面是从libco中导出的宏 #include <iostream> using namespace std;/*以下是计算参数的个数&#xff0c;最多支持7个参数 */ #define comac_get_args_cnt( ... ) comac_arg_n( __VA_ARGS__ ) #define comac_arg_n( _0,_1,_2,_3,_4,_5,_6,_7,N,...) N #define comac_a…

完整的PCB生产工艺到底是怎样的?华秋告诉你

前面&#xff0c;与朋友们分享了一些关于PCB生产工艺的事情。 有的朋友看了后非常感兴趣&#xff0c;私信说——现在的各种PCB资料满天飞&#xff0c;经常彼此间相互不一致&#xff0c;甚至对立&#xff0c;能给我们再讲讲&#xff0c;完整的PCB生产工艺到底是怎样的吗&#x…

Java 8函数式编程

函数式接口 一个接口中&#xff0c;有且只有一个抽象方法&#xff0c;这个接口就叫做函数式接口。常常使用FunctionalInterface注解作为编译校验。满足函数式接口的要求&#xff0c;才能校验通过&#xff0c;否则会在校验阶段失败。 接口中有且只能有一个抽象方法&#xff0c;…

STM32F4 | 外部中断实验

文章目录一、STM32F4 外部中断简介二、硬件设计三、软件设计四、实验现象五、STM32CubeMX 配置外部中断本章我们将介绍如何将 STM32F429 的 IO 口作为外部中断输入。一、STM32F4 外部中断简介 这里首先介绍STM32F4 IO 口中断的一些基础概念。STM32F4 的每个 IO 都可以作为外部…

实验五图形用户界面编程

目录 一、目的与任务 二、内容、要求与安排方式 三、实验设备 四、实验步骤 一、目的与任务 掌握常用事件及其处理模型&#xff1b;掌握常用GUI控制组件的使用及其事件的处理&#xff1b;掌握菜单的使用以及对话框的使用。 二、内容、要求与安排方式 1、实验内容与要求&…

SpringCloud系列(五)Nacos 注册中心配置管理的设置及使用

介绍几种 Nacos 常用的配置, 如统一配置管理的步骤, 如何配置自动刷新及多环境配置优先级问题. Nacos 配置管理⚽️ 统一配置管理⚽️⚽️配置自动刷新⚽️⚽️⚽️ 多环境配置优先级⚽️ 统一配置管理 步骤一: 在 Nacos 中添加配置信息, 如添加时间格式的配置内容; 步骤二: …

Ribbon实战与原理剖析

一、ribbon概述 1、ribbon简介 目前主流的负载方案分为以下两种&#xff1a; 集中式负载均衡&#xff0c;在消费者和服务提供方中间使用独立的代理方式进行负载&#xff0c;有硬件的&#xff08;比如 F5&#xff09;&#xff0c;也有软件的&#xff08;比如 Nginx&#xff0…

读写锁的学习与实验

目录 目录 1&#xff0c;场景 2&#xff0c;接口 3&#xff0c;场景模拟 1&#xff0c;场景 有一种场景&#xff0c;读者多&#xff0c;写者少&#xff0c;绝大多数的情况下我们都是在进行读取而不修改&#xff0c;只有少数的情况下我们才会修改。 场景一&#xff1a;比如…

解决jenkins构建失败,空间不足问题

随着构建次数过多&#xff0c;之后jenkins构建会出现空间不足的问题&#xff0c;解决方式如下&#xff1a; 目录 1.配置时&#xff0c;去除旧的构建任务 2.使用脚本&#xff0c;删除历史构建 3.清理磁盘空间 4.重新加载服务器节点 1.配置时&#xff0c;去除旧的构建任务 2…

计算机网络(自顶向下)学习笔记——路由选择算法

第五章—路由选择算法 5.1、路由的概念 路由:按照某种指标(传输延迟,所经过的站点数目等)找到一条 从源节点到目标节点的较好路径 较好路径: 按照某种指标较小的路径指标:站数, 延迟,费用,队列长度等, 或者是一些单纯指标的加权平均采用什么样的指标,表示网络使用者希望网络…

m基于优化算法的多车辆的路径规划matlab仿真,对比GA,PSO以及烟花算法

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 路径规划是运动规划的主要研究内容之一。运动规划由路径规划和轨迹规划组成&#xff0c;连接起点位置和终点位置的序列点或曲线称之为路径&#xff0c;构成路径的策略称之为路径规划。路径规划在…

微软12月多个安全漏洞修复解决方案

安全狗应急响应中心监测到&#xff0c;微软发布了2022年12月份安全更新&#xff0c;事件等级&#xff1a;严重&#xff0c;事件评分&#xff1a;10.0。此次安全更新发布了52个漏洞的补丁&#xff0c;主要覆盖了以下组件&#xff1a;Azure; Office and Office Components; SysIn…

提高电网的稳态稳定性(Matlab代码实现)

目录 1 概述 2 稳态稳定性分析 2.1 系统模型 2.2 稳态稳定性 2.3 问题说明 3 仿真结果 4 一点小智慧 5 Matlab代码实现 1 概述 随着电力系统的复杂性和规模的增加&#xff0c;电力系统的有效控制变得越来越困难。我们提出了一种自动控制策略&#xff0c;该策略基于通过…

如何使用typeScript实现贪吃蛇游戏?

1.配置文件 配置文件写过一次之后&#xff0c;可以复制粘贴使用&#xff0c;修改部分细节就可以了。 package.json {"name": "snake","version": "1.0.0","description": "","main": "index.js&q…

网络协议——RPC协议综述

拿最简单的场景&#xff0c;客户端调用一个加法函数&#xff0c;将两个整数加起来&#xff0c;返回它们的和。 如果放在本地调用&#xff0c;那是简单的不能再简单了&#xff0c;。但是一旦变成了远程调用&#xff0c;门槛一下子就上去了。 如何解决这五个问题&#xff1f; …

秦力洪复盘2022:蔚来的长板和误判

作者 | 张祥威 编辑 | 王博最初我们看蔚来&#xff0c;觉得它是中国的特斯拉。后来它主动挑战宝马&#xff0c;以46万的平均单价在高端品牌阵营厮杀&#xff0c;看上去又具备成为宝马的潜力。再到后来&#xff0c;蔚来宣布将推出全新品牌&#xff0c;喊话月销5万辆&#xff0c;…

[附源码]Nodejs计算机毕业设计基于大数据的高校国有固定资产管理及绩效自动评价系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…