CoSENT 句嵌入模型理论介绍与语义检索实践
引言
CoSENT(Cosine Sentence)是一种基于余弦相似度排序损失的句嵌入模型。相较于传统的 Sentence-BERT,CoSENT 在训练目标上进行了改进,使其更契合文本匹配的实际应用场景。本文将对 CoSENT 的理论基础进行简述,并结合领域文本训练句嵌入以实现语义检索,最终对比 CoSENT 和 Sentence-BERT 的效果差异。
有监督句嵌入模型概述
句嵌入是将句子表征为向量的过程,基于句向量可以进一步完成文本匹配、文本聚类、语义搜索等下游场景任务。句嵌入主要分为无监督和监督两大类。
Sentence-BERT 是一种典型的有监督句嵌入方案,它通过人工标注的三元组数据(句子 1,句子 2,是否相似),微调 BERT 使得相似语义的文本表征距离更小。而无监督的方案不需要人工标注,它依据文本的上下文关系来构造出预测任务,句嵌入是该任务的中间产物。这类方法包括 Word2Vec 词嵌入池化、Doc2Vec、Sentence2Vec、Skip-Thought Vectors 等。
本篇重点介绍另一种有监督句嵌入模型CoSENT。它将cosine 余弦相似度的排序损失引入到 Sentence-BERT 的训练环节,使得训练过程更加契合应用场景,同时加快模型在训练阶段的收敛。在众多数据集上,CoSENT 的表现优于 Sentence-BERT。
快速开始:使用 CoSENT 生成句嵌入
模型加载
在 HuggingFace 模型仓库中下载 shibing624/text2vec-base-chinese 预训练模型。该模型以 macbert 作为基座,通过 CoSENT 损失函数策略微调得到,可以实现对输入文本做 Embedding 表征。
CoSENT 也是 BERT 模型微调的结果,因此使用 BERT 的模型 API 导入 CoSENT 模型和词表。
from transformers import BertTokenizer, BertModel
import torch
embedding_model_name = "./text2vec-base-chinese"
embedding_model_length = 512
tokenizer = BertTokenizer.from_pretrained(embedding_model_name)
model = BertModel.from_pretrained(embedding_model_name)
预处理与编码
输入样例句子,对它们进行分词编码预处理。注意设置 padding=True 和 truncation=True 以适应批量处理。
sentences = [
'我不知道过年火车票能不能抢到',
'过年假期你准备去哪里玩',
'我准备春节请假两天提前回家,但是好没有抢到票',
'这个假期太短了,我作业还没有做完'
]
encoded_input = tokenizer(sentences, padding=True, truncation=True, return_tensors='pt')
均值池化
输出层需要使用 BERT 最后一层 block 的非 Padding 位置所有词 Embedding 的均值池化作为句嵌入。定义 mean_pooling 函数来实现该操作。
def mean_pooling():
token_embeddings = model_output[]
input_mask_expanded = attention_mask.unsqueeze(-).expand(token_embeddings.size()).()
torch.(token_embeddings * input_mask_expanded, ) / torch.clamp(input_mask_expanded.(), =)


