【深度学习】Sentece Embedding - SImCES

前言

        句子向量表示一直作为很多自然语言处理任务的基石,一直是NLP领域的热门话题,BERT-Flow以及BERT-whitenning其实像是后处理,将bert的输出进行一定的处理来解决各向异性的问题。

        而SimCSE《Simple Contrastive Learning of Sentence Embeddings》,即「简单的对比句向量表征框架」,通过一种简单的对比学习去做句子嵌入。而且在可以不要监督数据的情况下,生成质量较好的句子向量。文章被收录在EMNLP2021。

        paper地址:https://aclanthology.org/2021.emnlp-main.552.pdf
        code地址:https://github.com/princeton-nlp/SimCSE 

1.对比学习

        对比学习的定义:以拉近相似数据,推开不相似数据为目标,有效地学习数据表征。对比学习的流程如下:

        (1)将一只猫的图X,数据增强的方式生成另一张猫的图片作为正例X+,构建正例样本对,选择一只狗作为负例X-。
        (2)将这个正负例样本组(X,X+,X-)同时输入到一个模型中进行特征抽取。
        (3)优化对比损失,将X和X+的在特征空间里面的距离拉近,同时将X和X-在特征空间中的距离拉远。

        通过对比学习方式,可以达到下面两个目的
        (1)相似图片早特征空间靠的很近,这就实现了相似图片,它们的特征也比较相近
        (2)而不相似的图片在特征空间中距离会非常大,导致这些具有差异性得图片会比较分散的分布在特征空间中,从另一个角度上来思考,就是特征空间的信息会尽可能的多。

        从对比学习的整个流程来看,我们可以发现在没有标注数据的时候,只需要做一下数据增强构建正例样本对,就可以很方便的使用对比学习抽取出比较有用的特征向量。

2.SimCSE

        SimSCE 就是一个采用对比学习框架进行句子嵌入的方法,SimCES提出了有监督和无监督这两种对比学习方式来进行句子嵌入。

2.1 无监督方法

       无监督方法中,采用dropout技术,对原始文本进行数据增强,从而构造出正样本,用于后续对比学习训练。

2.1.1 流程实现

        无监督方法如下图所示,过程如下。

         (1) 将同一个句子输入到模型两次,采用dropout技术,得到两个不同的特征向量。由于模型中存在dropout 层,神经元随机失活会导致同一个句子在训练阶段输入到模型中得到的输出都会不一样。
        (2) 在一个batch中,将同一个句子在模型中的两次输出当作正例,将其他句子的输出全部当作负例。
        (3) 优化对比损失,增加正例之间的相似度,减小负例之间的相似度。

2.1.2 Loss 实现与详解

        这里假设每个batch 输入给模型的样本 格式如下 :
        (1) [0,1,2,3,4,5] 代表一个batch中含有六个样本
        (2)其中0,1表示同一个句子,其中2,3是同一个句子,其中4,5是同一个句子
        那么模型的输出 y_pred 就是[X0,X1,X2,X3,X4,X5] 这六个句子的向量表示。对比Loss 的详解 如下。

def compute_loss(y_pred, lamda=0.05):idxs = torch.arange(0, y_pred.shape[0])  # [0,1,2,3,4,5] #这里[(0,1),(2,3),(4,5)]代表三组样本,#其中0,1是同一个句子,输入模型两次#其中2,3是同一个句子,输入模型两次#其中4,5是同一个句子,输入模型两次y_true = idxs + 1 - idxs % 2 * 2 #  生成真实的label  = [1,0,3,2,5,4]  # 计算各句子之间的相似度,形成下方similarities 矩阵,其中xij 表示第i句子和第j个句子的相似度#[[ x00,x01,x02,x03,x04 ,x05  ]# [ x10,x11,x12,x13,x14 ,x15  ]# [ x20,x21,x22,x23,x24 ,x25  ]# [ x30,x31,x32,x33,x34 ,x35  ]# [ x40,x41,x42,x43,x44 ,x45  ]# [ x50,x51,x52,x53,x54 ,x55  ]]similarities = F.cosine_similarity(y_pred.unsqueeze(1), y_pred.unsqueeze(0), dim=2)# similarities屏蔽对角矩阵即自身相等的loss#[[ -nan,x01,x02,x03,x04 ,x05   ]   # [ x10, -nan,x12,x13,x14 ,x15 ]# [ x20,x21, -nan,x23,x24 ,x25 ]# [ x30,x31,x32, -nan,x34 ,x35 ]# [ x40,x41,x42,x43, -nan,x45  ]# [ x50,x51,x52,x53,x54 , -nan ]]similarities = similarities - torch.eye(y_pred.shape[0]) * 1e12# 论文中除以 temperature 超参similarities = similarities / lamda#下面这一行计算的是相似矩阵每一行和y_true = [1,0,3,2,5,4] 的交叉熵损失#[[ -nan,x01,x02,x03,x04 ,x05  ]   label = 1 含义:第0个句子应该和第1个句子的相似度最高,即x01越接近1越好# [ x10, -nan,x12,x13,x14,x15 ]   label = 0  含义:第1个句子应该和第0个句子的相似度最高,即x10越接近1越好# [ x20,x21, -nan,x23,x24,x25 ]   label = 3  含义:第2个句子应该和第3个句子的相似度最高,即x23越接近1越好# [ x30,x31,x32, -nan,x34,x35 ]   label = 2  含义:第3个句子应该和第2个句子的相似度最高,即x32越接近1越好# [ x40,x41,x42,x43, -nan,x45 ]   label = 5  含义:第4个句子应该和第5个句子的相似度最高,即x45越接近1越好# [ x50,x51,x52,x53,x54 , -nan ]]  label = 4 含义:第5个句子应该和第4个句子的相似度最高,即x54越接近1越好#这行代码就是simsce的核心部分,就是一个句子被dropout 两次得到的向量相似度应该越大 #越好,且和其他句子向量的相似度越小越好loss = F.cross_entropy(similarities, y_true) return torch.mean(loss)

2.2 监督学习方法 

2.2.1 流程实现

        监督学习方法中,借助于文本蕴含(自然语言推理)数据集,将蕴涵-pair作为正例,矛盾-pair作为难负例,用于后续对比学习训练。并且通过对比学习解决了预训练Embedding的各向异性问题,使其空间分布更均匀,当有监督数据可用时,可以使正样本直接更紧密。模型结构如下图所示:

2.2.2 Loss 实现与详解

        这里假设每个batch 输入给模型的样本 格式如下 :
        (1) [0,1,2,3,4,5] 代表一个batch中含有六个样本。
        (2)[(0,1,2),(3,4,5)]代表二组样本,其中0,1是相似句子代表正例,0,2是不相似的句子代表负例;其中3,4是相似句子代表正例,3,5是不相似的句子代表负例。模型的输出 y_pred 就是[X0,X1,X2,X3,X4,X5] 这六个句子的向量表示。对比Loss 的详解 如下。

def compute_loss(y_pred,lamda=0.05):row = torch.arange(0,y_pred.shape[0],3,device='cuda') # [0,3]col = torch.arange(y_pred.shape[0], device='cuda') # [0,1,2,3,4,5]#这里[(0,1,2),(3,4,5)]代表二组样本,#其中0,1是相似句子,0,2是不相似的句子#其中3,4是相似句子,3,5是不相似的句子col = torch.where(col % 3 != 0)[0].cuda() # [1,2,4,5]y_true = torch.arange(0,len(col),2,device='cuda') # 生成真实的label  = [0,2]#计算各句子之间的相似度,形成下方similarities 矩阵,其中xij 表示第i句子和第j个句子的相似度#[[ x00,x01,x02,x03,x04 ,x05  ]# [ x10,x11,x12,x13,x14 ,x15  ]# [ x20,x21,x22,x23,x24 ,x25  ]# [ x30,x31,x32,x33,x34 ,x35  ]# [ x40,x41,x42,x43,x44 ,x45  ]# [ x50,x51,x52,x53,x54 ,x55  ]]similarities = F.cosine_similarity(y_pred.unsqueeze(1), y_pred.unsqueeze(0), dim=2)#这里将similarities 做切片处理,形成下方矩阵#[[ x01,x02,x04 ,x05 ]  # [x31,x32,x34 ,x35 ]]similarities = torch.index_select(similarities,0,row)similarities = torch.index_select(similarities,1,col)#论文中除以 temperature 超参 similarities = similarities / lamda#下面这一行计算的是相似矩阵每一行和y_true = [0, 2] 的交叉熵损失#[[ x01,x02,x04 ,x05 ]   label = 0 含义:第0个句子应该和第1个句子的相似度最高,  即x01越接近1越好# [x31,x32,x34 ,x35 ]]  label = 2 含义:第3个句子应该和第4个句子的相似度最高   即x34越接近1越好#这行代码就是simsce的核心部分,和正例句子向量相似度应该越大 #越好,和负例句子之间向量的相似度越小越好loss = F.cross_entropy(similarities,y_true)return torch.mean(loss)

        其实除了通过dropout 两次来构造对比学习的正例样本,其实还有很多的方式构造正例,比如可以采用文本处理里面经常用到的同义词替换,回译等方式去进行正例构造,但SimCSE的作者想到用dropout这么简单的方式来构建对比学习的正例样本对,并且在很多数据集上表现不俗。

3.代码调用

# Import our models. The package will take care of downloading the models automatically
tokenizer = AutoTokenizer.from_pretrained("princeton-nlp/sup-simcse-bert-base-uncased")
model = AutoModel.from_pretrained("princeton-nlp/sup-simcse-bert-base-uncased")
# Tokenize input texts
texts = ["马云说本周六要来京和高文欣会面","马云计划周六在北京会见高文欣","马云周六没空"
]
inputs = tokenizer(texts, padding=True, truncation=True, return_tensors="pt")
# Get the embeddings
with torch.no_grad():embeddings = model(**inputs, output_hidden_states=True, return_dict=True).pooler_output# Calculate cosine similarities
# Cosine similarities are in [-1, 1]. Higher means more similar
cosine_sim_0_1 = 1 - cosine(embeddings[0], embeddings[1])
cosine_sim_0_2 = 1 - cosine(embeddings[0], embeddings[2])print("Cosine similarity between \"%s\" and \"%s\" is: %.3f" % (texts[0], texts[1], cosine_sim_0_1))
print("Cosine similarity between \"%s\" and \"%s\" is: %.3f" % (texts[0], texts[2], cosine_sim_0_2))

 Reference:

        1.https://www.jianshu.com/p/d73e499ec859

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

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

相关文章

线上BUG引起思考:package.json 中的 ^~ 该保留吗?

一、写在前面 一次线上项目 bug,引发了关于 package.json 中的 ^~ 是否该保留?保留可能引发的后果?以及如何在版本更新便利和版本更稳定中取舍的思考?这个 bug 是由于线上部署打包时,自己下载了最新依赖,于…

硬件基础-电感

电感 目录 1.原理 2.作用 3.高频等效模型 4. 直流偏置特性 5.器件选型 6.电感损耗 7.功率电感 8.贴片电感 9.共模电感 10.差模电感 1.原理 电感是阻碍电流的变化,储能 电感的磁芯决定了电感的饱和电流,也决定了电感值与电流的变化曲线,磁滞损…

P1 H264码流结构分析 (上)

目录 前言 01 什么是码流结构 02 H264帧类型的区别 03 片slice 前言 从本章开始我们将要学习嵌入式音视频的学习了 ,使用的瑞芯微的开发板 🎬 个人主页:ChenPi 🐻推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525…

石器时代H5小游戏架设教程

本文讲解石器时代 H5 之恐龙宝贝架设教程,想研究 H5 游戏如何实现,那请跟着此次教程学习在拥有小游戏源码的情况下该如何搭建起来 开始架设 1. 架设条件 石器时代架设需要准备: 一台linux 服务器,建议 CentOs 7.6 版本&#xf…

ros2 学习08 topic 话题定义及示例

topic 在ros 中的作用 节点实现了机器人各种各样的功能,但这些功能并不是独立的,之间会有千丝万缕的联系,其中最重要的一种联系方式就是话题,它是节点间传递数据的桥梁。 大家可以想一下,这两个节点是不是必然存在某种…

作业--day34

使用select完成TCP并发服务器和客户端 server.c #include <myhead.h>#define PORT 8888 #define IP "192.168.125.137"int main(int argc, const char *argv[]) {int sfd socket(AF_INET, SOCK_STREAM, 0);if(sfd -1){perror("socket error");re…

Docker 网络模式 -day05

docker 启动时候还会有&#xff0c;名为docker0的虚拟网桥&#xff0c;注意网址为 127.0.0.1 [rootiZuf6hxabqikytnrumsi4gZ ~]# ifconfig docker0: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.2…

基于k6和python进行自动化性能测试

摘要&#xff1a;在性能测试中&#xff0c;达到相应的性能指标对于一个软件来说十分重要&#xff0c;在本文中&#xff0c;将介绍一种现代化性能测试工具k6。 import http from k6/http; import { sleep } from k6; export default function () {http.get(https://test-api.co…

Backend - Django 项目创建 运行

目录 一、配置环境 二、创建 Django 项目 &#xff08;一&#xff09;新建文件夹 &#xff08;二&#xff09;打开文件夹 &#xff08;三&#xff09;打开运行终端 &#xff08;四&#xff09;创建基础项目 &#xff08;五&#xff09;创建app 1. 安装Django &#xf…

note-1

一个“逆向思维”的小例子&#xff1a;“一男生晚上到某银行ATM机存款&#xff0c;碰ATM机出现故障&#xff0c;5000元被吞。当即联系银行&#xff0c;被告知要等到天亮才能维修。其绞尽脑汁的想突然灵机一动&#xff0c;使用公用电话致电客服称&#xff1a;ATM机多吐出3000元&…

VR智慧酒店:提升人气入住率,助力酒店开辟新赛道

随着智能科技的不断进步&#xff0c;智能感、科技感也体现在我们的住宿体验上&#xff0c;VR智慧酒店可以让用户沉浸式体验高质量的酒店服务&#xff0c;这种全新的体验方式助力开启智能化酒店获客新模式&#xff0c;引爆超人气入住率。 传统的酒店行业推广成本高、效果差&…

map|动态规划|单调栈|LeetCode975:奇偶跳

作者推荐 【贪心算法】【中位贪心】.执行操作使频率分数最大 涉及知识点 单调栈 动态规划 map 题目 给定一个整数数组 A&#xff0c;你可以从某一起始索引出发&#xff0c;跳跃一定次数。在你跳跃的过程中&#xff0c;第 1、3、5… 次跳跃称为奇数跳跃&#xff0c;而第 2、…

linux 驱动——私有数据

文章目录 linux 驱动中的私有数据container_of驱动程序应用程序模块使用 linux 驱动中的私有数据 container_of 参考&#xff1a;linux——宏 list_entry/container_of 驱动程序 #include "linux/device/class.h" #include "linux/export.h" #include…

Python人脸识别

实现效果 代码 import cv2# 加载人脸识别分类器 face_cascade cv2.CascadeClassifier(haarcascade_frontalface_default.xml)# 打开摄像头 cap cv2.VideoCapture(0)while True:# 读取摄像头捕获的帧ret, frame cap.read()# 将帧转换为灰度图像gray cv2.cvtColor(frame, c…

迪文屏开发保姆级教程——页面键盘

迪文屏页面键盘保姆级教程。 本篇文章主要介绍了在DGBUS平台上使用页面键盘的步骤。 迪文屏官方开发指南PDF&#xff1a;&#xff08;不方便下载的私聊我发给你&#xff09; https://download.csdn.net/download/qq_21370051/88647174?spm1001.2014.3001.5503https://downloa…

vivado 关于时钟

关于时钟 在数字设计中&#xff0c;时钟代表了从寄存器可靠传输数据的时间基准注册。AMD Vivado™集成设计环境&#xff08;IDE&#xff09;计时引擎使用时钟计算时序路径要求并通过以下方式报告设计时序裕度的特性松弛计算的方法有关更多信息&#xff0c;请参阅Vivado Design…

AI百模大战:引领行业变革与开启人才黄金时代

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Linux学习 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 技术进步&#xff1a;AI的飞速发展 1. 深度学习的多领域应用 2. 自然语言处理的语境理解提升 3. 计算机视觉的实时处理能力提高 4…

Python学习笔记(六):函数的多返回值、函数的多种参数使用形式、匿名函数、文件的读取操作、文件的写入 、文件的追加

目录 一、函数的多返回值 二、函数的多种参数使用形式 2.1位置参数 2.2关键字参数 2.3缺省参数 2.4不定长参数 三、匿名函数 3.1 函数作为参数传递 3.2 函数的定义 3.3 匿名函数定义语法&#xff1a; 四、文件的读取操作 4.1 open&#xff08;&#xff09;打开函数…

图卷积神经网络发展

1. 图神经网络&#xff08;GNN&#xff09; 图神经网络的概念最早在2005年提出。2009年Franco博士在其论文 [2]中定义了图神经网络的理论基础。 本文中所提到的图均指图论中的图(Graph)。它是一种由若干个结点(Node)及连接两个结点的边(Edge)所构成的图形&#xff0c;用于刻画…

【模式识别】解锁降维奥秘:深度剖析PCA人脸识别技术

​&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《模式之谜 | 数据奇迹解码》⏰诗赋清音&#xff1a;云生高巅梦远游&#xff0c; 星光点缀碧海愁。 山川深邃情难晤&#xff0c; 剑气凌云志自修。 目录 &#x1f30c;1 初识模式识…