损失函数
sentence_transformers.sparse_encoder.losses
定义了不同的损失函数,可用于在训练数据上微调稀疏嵌入模型。损失函数的选择在微调模型时起着关键作用。它决定了我们的嵌入模型在特定下游任务上的表现如何。
遗憾的是,没有“一刀切”的损失函数。选择哪种损失函数取决于可用的训练数据和目标任务。请考虑查阅损失函数概览,以帮助缩小您对损失函数的选择范围。
警告
要训练一个 SparseEncoder
,您需要 SpladeLoss
或 CSRLoss
,具体取决于架构。这些是包装器损失,它们在主损失函数之上添加稀疏性正则化,主损失函数必须作为参数提供。唯一可以独立使用的损失是 SparseMSELoss
,因为它执行嵌入级别的蒸馏,通过直接复制教师模型的稀疏嵌入来确保稀疏性。
SpladeLoss
- class sentence_transformers.sparse_encoder.losses.SpladeLoss(model: SparseEncoder, loss: Module, document_regularizer_weight: float, query_regularizer_weight: float | None = None, document_regularizer: Module | None = None, query_regularizer: Module | None = None, document_regularizer_threshold: int | None = None, query_regularizer_threshold: int | None = None, use_document_regularizer_only: bool = False)[源代码]
SpladeLoss 为 SPLADE (稀疏词汇和扩展) 模型实现了损失函数,该模型将主损失函数与正则化项相结合以控制效率。
该损失函数通过对查询和文档表示进行正则化以使其稀疏,从而在有效性(通过主损失)和效率之间取得平衡,减少了推理时的计算需求。
- 参数:
model – SparseEncoder 模型
loss – 要使用的主损失函数,可以是除 CSR 相关损失和 flops 损失之外的任何 SparseEncoder 损失。
document_regularizer_weight – 语料库正则化项的权重。该项鼓励文档嵌入的稀疏性。如果提供,将应用于正例文档和所有负例文档。在一些论文中,该参数被称为“lambda_d”(文档)或“lambda_c”(语料库)。
query_regularizer_weight – 查询正则化项的权重。该项鼓励查询嵌入的稀疏性。如果为 None,则不应用查询正则化,如果您处于无推理设置或将 use_document_regularizer_only 设置为 True,则没有问题。否则,您应该有一个大于 0 的 query_regularizer_weight。在一些论文中,该参数被称为“lambda_q”(查询)。
document_regularizer – 可选的正则化器,专门用于语料库正则化,而不是默认的 FlopsLoss。这允许对文档与查询采用不同的正则化策略。
query_regularizer – 可选的正则化器,专门用于查询正则化,而不是默认的 FlopsLoss。这允许对查询与文档采用不同的正则化策略。
document_regularizer_threshold – 在 FlopsLoss 中考虑的语料库嵌入中非零(活动)元素数量的可选阈值。如果指定,则仅考虑非零(活动)元素数量超过此值的语料库嵌入。仅当 document_regularizer 为 None 时(对于默认的 FlopsLoss)使用。
query_regularizer_threshold – 在 FlopsLoss 中考虑的查询嵌入中非零(活动)元素数量的可选阈值。如果指定,则仅考虑非零(活动)元素数量超过此值的查询嵌入。仅当 query_regularizer 为 None 时(对于默认的 FlopsLoss)使用。
use_document_regularizer_only – 如果为 True,则所有输入嵌入都被视为文档,并与 document_regularizer_weight 一起进行正则化。在训练对称文本(例如,文档对)或更多文本时特别有用。
参考文献
有关更多详细信息,请参阅论文“From Distillation to Hard Negative Sampling: Making Sparse Neural IR Models More Effective” https://arxiv.org/abs/2205.04733
- 要求
输入要求取决于所选的损失
通常在知识蒸馏设置中与教师模型和相关损失一起使用
示例
from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses student_model = SparseEncoder("distilbert/distilbert-base-uncased") teacher_model = SparseEncoder("naver/splade-cocondenser-ensembledistil") train_dataset = Dataset.from_dict( { "query": ["It's nice weather outside today.", "He drove to work."], "passage1": ["It's so sunny.", "He took the car to work."], "passage2": ["It's very sunny.", "She walked to the store."], } ) def compute_labels(batch): emb_queries = teacher_model.encode(batch["query"]) emb_passages1 = teacher_model.encode(batch["passage1"]) emb_passages2 = teacher_model.encode(batch["passage2"]) return { "label": teacher_model.similarity_pairwise(emb_queries, emb_passages1) - teacher_model.similarity_pairwise(emb_queries, emb_passages2) } train_dataset = train_dataset.map(compute_labels, batched=True) loss = losses.SpladeLoss( student_model, loss=losses.SparseMarginMSELoss(student_model), document_regularizer_weight=3e-5, query_regularizer_weight=5e-5, ) trainer = SparseEncoderTrainer(model=student_model, train_dataset=train_dataset, loss=loss) trainer.train()
FlopsLoss
- class sentence_transformers.sparse_encoder.losses.FlopsLoss(model: SparseEncoder, threshold: float | None = None)[源代码]
FlopsLoss 实现了一种正则化技术,以促进稀疏编码器模型的稀疏性。它计算平均嵌入向量的 L2 范数的平方,通过鼓励嵌入中更多的零值,有助于减少推理期间所需的浮点运算(FLOPs)。它可以使用阈值来忽略非零(活动)元素过少的嵌入。
该损失在
SpladeLoss
等其他损失中用作正则化组件,而不是作为独立的损失函数使用。- 参数:
model – 需要正则化的 SparseEncoder 模型
threshold – 嵌入中非零(活动)元素数量的可选阈值。如果指定,则仅考虑非零(活动)元素数量超过此值的嵌入。这有助于忽略过于稀疏且可能对损失没有显著贡献的嵌入。
参考文献
有关更多详细信息,请参阅:https://arxiv.org/pdf/2004.05665(关于通用 FLOPS 损失)和 https://arxiv.org/pdf/2504.14839(关于带阈值的 FLOPS,也称为带 l0 掩码的 FLOPS)。
- 关系
在
SpladeLoss
中用作正则化查询和文档嵌入的组件
示例
此损失通常在
SpladeLoss
类中使用,该类将其与其他损失组件结合。
CSRLoss
- class sentence_transformers.sparse_encoder.losses.CSRLoss(model: SparseEncoder, loss: Module | None = None, beta: float = 0.1, gamma: float = 1.0)[源代码]
CSRLoss 为对比稀疏表示 (CSR) 模型实现了组合损失函数。
此损失结合了两个部分
- 一个重建损失
CSRReconstructionLoss
,确保稀疏表示能够忠实地 重建原始嵌入。
- 一个重建损失
- 一个主损失,在论文中是
SparseMultipleNegativesRankingLoss
,确保语义上 相似的句子有相似的表示。
- 一个主损失,在论文中是
总损失是这两个损失的线性组合。
- 参数:
model – SparseEncoder 模型
loss – 要使用的主损失函数,可以是除 flops 损失和 CSRReconstruction 损失之外的任何 SparseEncoder 损失。如果为 None,则使用默认损失,即 SparseMultipleNegativesRankingLoss。
beta – 重建损失中 L_aux 分量的权重。默认为 0.1。
gamma – 主损失分量(默认为 MNRL,即 InfoNCE)的权重。默认为 1.0。
参考文献
更多详情,请参阅论文“Beyond Matryoshka: Revisiting Sparse Coding for Adaptive Representation”
https://arxiv.org/abs/2503.01776
- 要求
输入要求取决于所选的损失
使用 SparseEncoder 模型的自编码器组件
- 关系
使用
CSRReconstructionLoss
作为重建组件
示例
from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses model = SparseEncoder("sentence-transformers/all-MiniLM-L6-v2") train_dataset = Dataset.from_dict( { "anchor": ["It's nice weather outside today.", "He drove to work."], "positive": ["It's so sunny.", "He took the car to the office."], "negative": ["It's quite rainy, sadly.", "She walked to the store."], } ) loss = losses.CSRLoss(model, beta=0.1, gamma=1.0) trainer = SparseEncoderTrainer(model=model, train_dataset=train_dataset, loss=loss) trainer.train()
CSRReconstructionLoss
- class sentence_transformers.sparse_encoder.losses.CSRReconstructionLoss(model: SparseEncoder, beta: float = 1.0)[源代码]
CSRReconstructionLoss 实现了对比稀疏表示 (CSR) 模型的重建损失组件。
该损失通过三个组件确保稀疏编码能够准确地重建原始模型嵌入
一个主重建损失 (L_k),用于衡量原始嵌入与其使用 top-k 稀疏组件进行重建之间的误差。
一个次要重建损失 (L_4k),用于衡量使用 top-4k 稀疏组件的误差。
一个辅助损失 (L_aux),用于帮助学习残差信息。
- 参数:
model – 具有自编码器组件的 SparseEncoder 模型
beta – 辅助损失组件 (L_aux) 的权重
参考文献
有关更多详细信息,请参阅论文“Beyond Matryoshka: Revisiting Sparse Coding for Adaptive Representation” https://arxiv.org/abs/2503.01776
- 要求
模型必须配置为输出必要的重建组件
用于实现了组合稀疏自编码的 SparseEncoder 模型
- 关系
作为
CSRLoss
内的组件,与对比损失结合使用
示例
此损失从不单独使用,而是在
CSRLoss
类中使用。有关更多详细信息,请参阅该损失的文档。
SparseMultipleNegativesRankingLoss
- class sentence_transformers.sparse_encoder.losses.SparseMultipleNegativesRankingLoss(model: ~sentence_transformers.sparse_encoder.SparseEncoder.SparseEncoder, scale: float = 1.0, similarity_fct=<function dot_score>, gather_across_devices: bool = False)[源代码]
给定一个 (anchor, positive) 对或 (anchor, positive, negative) 三元组列表,此损失函数优化以下目标
给定一个锚点(例如一个问题),在批次中的每一个正例和负例(例如所有答案)中,为对应的正例(即答案)赋予最高的相似度。
如果您提供可选的负例,它们都将被用作额外的选项,模型必须从中选择正确的正例。在合理范围内,这种“选择”越困难,模型就会变得越强大。因此,更大的批次大小会产生更多的批内负例,从而(在一定程度上)提高性能。
当您有正例对(例如(查询,答案))时,此损失函数非常适合训练用于检索设置的嵌入,因为它会在每个批次中随机采样
n-1
个负例文档。此损失函数也称为 InfoNCE 损失、SimCSE 损失、带批内负例的交叉熵损失,或简称为批内负例损失。
- 参数:
model – SparseEncoder 模型
scale – 相似度函数的输出乘以 scale 值。在一些文献中,缩放参数被称为温度,它是 scale 的倒数。简而言之:scale = 1 / temperature,因此 scale=20.0 等效于 temperature=0.05。对于点积相似度,通常使用 1.0 的 scale,而对于余弦相似度,通常使用 20.0 到 50.0 左右的值。
similarity_fct – 句子嵌入之间的相似度函数。默认使用点积。也可以设置为余弦相似度(然后将 scale 设置为例如 20.0)。
gather_across_devices – 如果为 True,则在计算损失之前跨所有设备收集嵌入。在多 GPU 上训练时推荐使用,因为它允许更大的批次大小,但可能会因通信开销而减慢训练速度,并可能导致内存不足错误。
- 要求
需要作为损失函数在 SpladeLoss 或 CSRLoss 中使用。
(anchor, positive) 对或 (anchor, positive, negative) 三元组
- 输入
文本
标签
(锚点, 正例) 对
无
(锚点, 正例, 负例) 三元组
无
(anchor, positive, negative_1, ..., negative_n)
无
- 建议
使用
BatchSamplers.NO_DUPLICATES
(文档
) 来确保批内负例不是锚点或正例样本的副本。
- 关系
SparseCachedMultipleNegativesRankingLoss
与此损失等效,但它使用缓存,允许在不增加额外内存使用的情况下实现更大的批次大小(从而获得更好的性能)。然而,它的速度稍慢。SparseGISTEmbedLoss
与此损失等效,但它使用一个指导模型来指导批内负样本的选择。SparseGISTEmbedLoss 以一些训练开销为代价,产生了更强的训练信号。
示例
from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses model = SparseEncoder("distilbert/distilbert-base-uncased") train_dataset = Dataset.from_dict( { "anchor": ["It's nice weather outside today.", "He drove to work."], "positive": ["It's so sunny.", "He took the car to the office."], } ) loss = losses.SpladeLoss( model=model, loss=losses.SparseMultipleNegativesRankingLoss(model), document_regularizer_weight=3e-5, query_regularizer_weight=5e-5 ) trainer = SparseEncoderTrainer(model=model, train_dataset=train_dataset, loss=loss) trainer.train()
SparseMarginMSELoss
- class sentence_transformers.sparse_encoder.losses.SparseMarginMSELoss(model: ~sentence_transformers.sparse_encoder.SparseEncoder.SparseEncoder, similarity_fct=<function pairwise_dot_score>)[源代码]
计算
|sim(Query, Pos) - sim(Query, Neg)|
与|gold_sim(Query, Pos) - gold_sim(Query, Neg)|
之间的 MSE 损失。默认情况下,sim() 是点积。gold_sim 通常是来自教师模型的相似度得分。与
SparseMultipleNegativesRankingLoss
相比,这两个段落不必是严格的正例和负例,对于给定的查询,两者都可以是相关的或不相关的。这可能是 SparseMarginMSELoss 相对于 SparseMultipleNegativesRankingLoss 的一个优势,但请注意,SparseMarginMSELoss 的训练速度要慢得多。使用 SparseMultipleNegativesRankingLoss,当批次大小为 64 时,我们将一个查询与 128 个段落进行比较。而使用 SparseMarginMSELoss,我们只将一个查询与两个段落进行比较。也可以将 SparseMarginMSELoss 与多个负例一起使用,但训练会更慢。- 参数:
model – SparseEncoder (稀疏编码器)
similarity_fct – 使用哪种相似度函数。
参考文献
有关更多详情,请参阅 https://arxiv.org/abs/2010.02666。
- 要求
需要作为损失函数在 SpladeLoss 或 CSRLoss 中使用。
(查询, 段落一, 段落二) 三元组 或 (查询, 正例, 负例_1, ..., 负例_n)
通常在知识蒸馏设置中与微调过的教师模型 M 一起使用
- 输入
文本
标签
(查询, 段落_一, 段落_二) 三元组
M(查询, 段落一) - M(查询, 段落二)
(查询, 段落_一, 段落_二) 三元组
[M(查询, 段落一), M(查询, 段落二)]
(查询, 正例, 负例_1, ..., 负例_n)
[M(查询, 正例) - M(查询, 负例_i) for i in 1..n]
(查询, 正例, 负例_1, ..., 负例_n)
[M(查询, 正例), M(查询, 负例_1), ..., M(查询, 负例_n)]
- 关系
SparseMSELoss
与此损失类似,但没有通过负例对产生的边距。
示例
使用黄金标签,例如,如果您有句子的硬性分数。假设您希望一个模型将具有相似“质量”的句子嵌入到相近的位置。如果“text1”的质量是 5 分(满分 5 分),“text2”的质量是 1 分(满分 5 分),“text3”的质量是 3 分(满分 5 分),那么一对的相似度可以定义为质量分数的差异。所以,“text1”和“text2”之间的相似度是 4,“text1”和“text3”之间的相似度是 2。如果我们将此用作我们的“教师模型”,则标签变为 similarity(“text1”, “text2”) - similarity(“text1”, “text3”) = 4 - 2 = 2。
正值表示第一个段落比第二个段落更相似于查询,而负值表示相反。
from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses model = SparseEncoder("naver/splade-cocondenser-ensembledistil") train_dataset = Dataset.from_dict( { "text1": ["It's nice weather outside today.", "He drove to work."], "text2": ["It's so sunny.", "He took the car to work."], "text3": ["It's very sunny.", "She walked to the store."], "label": [0.1, 0.8], } ) loss = losses.SpladeLoss( model, losses.SparseMarginMSELoss(model), document_regularizer_weight=3e-5, query_regularizer_weight=5e-5 ) trainer = SparseEncoderTrainer(model=model, train_dataset=train_dataset, loss=loss) trainer.train()
我们也可以使用教师模型来计算相似度分数。在这种情况下,我们可以使用教师模型计算相似度分数,并将它们用作银标签。这通常用于知识蒸馏。
from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses student_model = SparseEncoder("distilbert/distilbert-base-uncased") teacher_model = SparseEncoder("naver/splade-cocondenser-ensembledistil") train_dataset = Dataset.from_dict( { "query": ["It's nice weather outside today.", "He drove to work."], "passage1": ["It's so sunny.", "He took the car to work."], "passage2": ["It's very sunny.", "She walked to the store."], } ) def compute_labels(batch): emb_queries = teacher_model.encode(batch["query"]) emb_passages1 = teacher_model.encode(batch["passage1"]) emb_passages2 = teacher_model.encode(batch["passage2"]) return { "label": teacher_model.similarity_pairwise(emb_queries, emb_passages1) - teacher_model.similarity_pairwise(emb_queries, emb_passages2) } train_dataset = train_dataset.map(compute_labels, batched=True) loss = losses.SpladeLoss( student_model, losses.SparseMarginMSELoss(student_model), document_regularizer_weight=3e-5, query_regularizer_weight=5e-5 ) trainer = SparseEncoderTrainer(model=student_model, train_dataset=train_dataset, loss=loss) trainer.train()
我们也可以在知识蒸馏期间使用多个负例。
import torch from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses student_model = SparseEncoder("distilbert/distilbert-base-uncased") teacher_model = SparseEncoder("naver/splade-cocondenser-ensembledistil") train_dataset = Dataset.from_dict( { "query": ["It's nice weather outside today.", "He drove to work."], "passage1": ["It's so sunny.", "He took the car to work."], "passage2": ["It's very cold.", "She walked to the store."], "passage3": ["Its rainy", "She took the bus"], } ) def compute_labels(batch): emb_queries = teacher_model.encode(batch["query"]) emb_passages1 = teacher_model.encode(batch["passage1"]) emb_passages2 = teacher_model.encode(batch["passage2"]) emb_passages3 = teacher_model.encode(batch["passage3"]) return { "label": torch.stack( [ teacher_model.similarity_pairwise(emb_queries, emb_passages1) - teacher_model.similarity_pairwise(emb_queries, emb_passages2), teacher_model.similarity_pairwise(emb_queries, emb_passages1) - teacher_model.similarity_pairwise(emb_queries, emb_passages3), ], dim=1, ) } train_dataset = train_dataset.map(compute_labels, batched=True) loss = losses.SpladeLoss( student_model, loss=losses.SparseMarginMSELoss(student_model), document_regularizer_weight=3e-5, query_regularizer_weight=5e-5 ) trainer = SparseEncoderTrainer(model=student_model, train_dataset=train_dataset, loss=loss) trainer.train()
SparseDistillKLDivLoss
- class sentence_transformers.sparse_encoder.losses.SparseDistillKLDivLoss(model: ~sentence_transformers.sparse_encoder.SparseEncoder.SparseEncoder, similarity_fct=<function pairwise_dot_score>, temperature: float = 2.0)[源代码]
计算学生模型和教师模型的相似度分数派生出的概率分布之间的 KL 散度损失。默认情况下,使用点积计算相似度。此损失专为知识蒸馏设计,其中较小的学生模型从功能更强大的教师模型中学习。
该损失从教师相似度分数计算 softmax 概率,从学生模型计算 log-softmax 概率,然后计算这些分布之间的 KL 散度。
- 参数:
model – SentenceTransformer 模型(学生模型)
similarity_fct – 学生模型使用的相似度函数
temperature – 用于软化概率分布的温度参数(温度越高 = 分布越软)。与其他损失结合使用时,温度为 1.0 也是可行的,但更高的温度(例如 2.0 或 4.0)可以帮助防止学生模型陷入零活动维度。默认为 2.0。
参考文献
有关更多详情,请参阅 https://arxiv.org/abs/2010.11386
- 要求
需要作为损失函数在 SpladeLoss 或 CSRLoss 中使用。
(查询, 正例, 负例_1, ..., 负例_n) 样本
包含教师模型在查询-正例和查询-负例对之间分数的标签
- 输入
文本
标签
(查询, 正例, 负例)
[Teacher(查询, 正例), Teacher(查询, 负例)]
(查询, 正例, 负例_1, ..., 负例_n)
[Teacher(查询, 正例), Teacher(查询, 负例_i)...]
- 关系
与
SparseMarginMSELoss
类似,但使用 KL 散度代替 MSE更适合于保留排序很重要的蒸馏任务
示例
使用教师模型计算用于蒸馏的相似度分数
import torch from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses student_model = SparseEncoder("distilbert/distilbert-base-uncased") teacher_model = SparseEncoder("naver/splade-cocondenser-ensembledistil") train_dataset = Dataset.from_dict( { "query": ["It's nice weather outside today.", "He drove to work."], "positive": ["It's so sunny.", "He took the car to work."], "negative": ["It's very cold.", "She walked to the store."], } ) def compute_labels(batch): emb_queries = teacher_model.encode(batch["query"]) emb_positives = teacher_model.encode(batch["positive"]) emb_negatives = teacher_model.encode(batch["negative"]) pos_scores = teacher_model.similarity_pairwise(emb_queries, emb_positives) neg_scores = teacher_model.similarity_pairwise(emb_queries, emb_negatives) # Stack the scores for positive and negative pairs return {"label": torch.stack([pos_scores, neg_scores], dim=1)} train_dataset = train_dataset.map(compute_labels, batched=True) loss = losses.SpladeLoss( student_model, loss=losses.SparseDistillKLDivLoss(student_model), document_regularizer_weight=3e-5, query_regularizer_weight=5e-5 ) trainer = SparseEncoderTrainer(model=student_model, train_dataset=train_dataset, loss=loss) trainer.train()
使用多个负例
import torch from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses student_model = SparseEncoder("distilbert/distilbert-base-uncased") teacher_model = SparseEncoder("naver/splade-cocondenser-ensembledistil") train_dataset = Dataset.from_dict( { "query": ["It's nice weather outside today.", "He drove to work."], "positive": ["It's so sunny.", "He took the car to work."], "negative1": ["It's very cold.", "She walked to the store."], "negative2": ["Its rainy", "She took the bus"], } ) def compute_labels(batch): emb_queries = teacher_model.encode(batch["query"]) emb_positives = teacher_model.encode(batch["positive"]) emb_negatives1 = teacher_model.encode(batch["negative1"]) emb_negatives2 = teacher_model.encode(batch["negative2"]) pos_scores = teacher_model.similarity_pairwise(emb_queries, emb_positives) neg_scores1 = teacher_model.similarity_pairwise(emb_queries, emb_negatives1) neg_scores2 = teacher_model.similarity_pairwise(emb_queries, emb_negatives2) # Stack the scores for positive and multiple negative pairs return {"label": torch.stack([pos_scores, neg_scores1, neg_scores2], dim=1)} train_dataset = train_dataset.map(compute_labels, batched=True) loss = losses.SpladeLoss( student_model, loss=losses.SparseDistillKLDivLoss(student_model), document_regularizer_weight=3e-5, query_regularizer_weight=5e-5 ) trainer = SparseEncoderTrainer(model=student_model, train_dataset=train_dataset, loss=loss) trainer.train()
SparseTripletLoss
- class sentence_transformers.sparse_encoder.losses.SparseTripletLoss(model: ~sentence_transformers.sparse_encoder.SparseEncoder.SparseEncoder, distance_metric=<function TripletDistanceMetric.<lambda>>, triplet_margin: float = 5)[源代码]
此类实现了三元组损失。给定一个 (anchor, positive, negative) 三元组,该损失最小化 anchor 和 positive 之间的距离,同时最大化 anchor 和 negative 之间的距离。它计算以下损失函数:
损失 = max(||anchor - positive|| - ||anchor - negative|| + margin, 0)
.边距(Margin)是一个重要的超参数,需要相应地进行调整。
- 参数:
model – SparseEncoder (稀疏编码器)
distance_metric – 用于计算两个嵌入之间距离的函数。TripletDistanceMetric 类包含可以使用的常见距离度量。
triplet_margin – 负例应比正例离锚点至少远这么多。
参考文献
- 要求
需要作为损失函数在 SpladeLoss 或 CSRLoss 中使用。
(锚点, 正例, 负例) 三元组
- 输入
文本
标签
(锚点, 正例, 负例) 三元组
无
示例
from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses model = SparseEncoder("distilbert/distilbert-base-uncased") train_dataset = Dataset.from_dict( { "anchor": ["It's nice weather outside today.", "He drove to work."], "positive": ["It's so sunny.", "He took the car to the office."], "negative": ["It's quite rainy, sadly.", "She walked to the store."], } ) loss = losses.SpladeLoss( model=model, loss=losses.SparseTripletLoss(model), document_regularizer_weight=3e-5, query_regularizer_weight=5e-5 ) trainer = SparseEncoderTrainer(model=model, train_dataset=train_dataset, loss=loss) trainer.train()
SparseCosineSimilarityLoss
- class sentence_transformers.sparse_encoder.losses.SparseCosineSimilarityLoss(model: SparseEncoder, loss_fct: Module = MSELoss(), cos_score_transformation: Module = Identity())[源代码]
SparseCosineSimilarityLoss 期望 InputExamples 由两个文本和一个浮点数标签组成。它计算向量
u = model(sentence_A)
和v = model(sentence_B)
,并测量两者之间的余弦相似度。默认情况下,它最小化以下损失:||input_label - cos_score_transformation(cosine_sim(u,v))||_2
。- 参数:
model – SparseEncoder 模型
loss_fct – 应该使用哪个 pytorch 损失函数来比较
cosine_similarity(u, v)
与 input_label?默认情况下,使用 MSE:||input_label - cosine_sim(u, v)||_2
cos_score_transformation – cos_score_transformation 函数应用于 cosine_similarity 之上。默认情况下,使用恒等函数(即不作改变)。
- 要求
需要作为损失函数在 SpladeLoss 或 CSRLoss 中使用。
具有相应相似度分数(范围在 [0, 1])的句子对
- 输入
文本
标签
(句子_A, 句子_B) 对
浮点型相似度分数
- 关系
SparseAnglELoss
是使用pairwise_angle_sim
作为度量的SparseCoSENTLoss
,而不是pairwise_cos_sim
。
示例
from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses model = SparseEncoder("distilbert/distilbert-base-uncased") train_dataset = Dataset.from_dict( { "sentence1": ["It's nice weather outside today.", "He drove to work."], "sentence2": ["It's so sunny.", "She walked to the store."], "score": [1.0, 0.3], } ) loss = losses.SpladeLoss( model=model, loss=losses.SparseCosineSimilarityLoss(model), document_regularizer_weight=5e-5, use_document_regularizer_only=True, ) trainer = SparseEncoderTrainer(model=model, train_dataset=train_dataset, loss=loss) trainer.train()
SparseCoSENTLoss
- class sentence_transformers.sparse_encoder.losses.SparseCoSENTLoss(model: ~sentence_transformers.sparse_encoder.SparseEncoder.SparseEncoder, scale: float = 20.0, similarity_fct=<function cos_sim>)[源代码]
此类实现了 CoSENT (Cosine Sentence)。它期望每个 InputExamples 由一对文本和一个浮点值标签组成,代表该对的预期相似度分数。
它计算以下损失函数:
loss = logsum(1+exp(s(i,j)-s(k,l))+exp...)
,其中(i,j)
和(k,l)
是批次中任何一对输入,使得(i,j)
的预期相似度大于(k,l)
。求和是对批次中所有满足此条件的输入对的所有可能组合进行的。- 参数:
model – SparseEncoder (稀疏编码器)
similarity_fct – 用于计算嵌入之间成对相似度的函数。默认为
util.pairwise_cos_sim
。scale – 相似度函数的输出乘以 scale 值。表示逆温度。
参考文献
更多详情,请参阅:https://kexue.fm/archives/8847
- 要求
需要作为损失函数在 SpladeLoss 或 CSRLoss 中使用。
具有相应相似度分数的句子对,分数范围在相似度函数的范围内。默认为 [-1,1]。
- 输入
文本
标签
(句子_A, 句子_B) 对
浮点型相似度分数
- 关系
SparseAnglELoss
是使用pairwise_angle_sim
作为度量的 SparseCoSENTLoss,而不是pairwise_cos_sim
。
示例
from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses model = SparseEncoder("distilbert/distilbert-base-uncased") train_dataset = Dataset.from_dict( { "sentence1": ["It's nice weather outside today.", "He drove to work."], "sentence2": ["It's so sunny.", "She walked to the store."], "score": [1.0, 0.3], } ) loss = losses.SpladeLoss( model=model, loss=losses.SparseCoSENTLoss(model), document_regularizer_weight=5e-5, use_document_regularizer_only=True ) trainer = SparseEncoderTrainer(model=model, train_dataset=train_dataset, loss=loss) trainer.train()
SparseAnglELoss
- class sentence_transformers.sparse_encoder.losses.SparseAnglELoss(model: SparseEncoder, scale: float = 20.0)[源代码]
此类实现了 AnglE (Angle Optimized)。这是对
SparseCoSENTLoss
的修改,旨在解决以下问题:当余弦波接近其波峰或波谷时,其梯度趋近于 0。这可能会阻碍优化过程,因此 AnglE 建议在复数空间中优化角度差,以减轻这种影响。它期望每个 InputExamples 由一对文本和一个浮点值标签组成,代表该对的预期相似度分数。
它计算以下损失函数:
loss = logsum(1+exp(s(k,l)-s(i,j))+exp...)
,其中(i,j)
和(k,l)
是批次中任何一对输入,使得(i,j)
的预期相似度大于(k,l)
。求和是对批次中所有满足此条件的输入对的所有可能组合进行的。这与 CoSENTLoss 相同,只是相似度函数不同。- 参数:
model – SparseEncoder (稀疏编码器)
scale – 相似度函数的输出乘以 scale 值。表示逆温度。
参考文献
更多详情,请参阅:https://arxiv.org/abs/2309.12871v1
- 要求
需要作为损失函数在 SpladeLoss 或 CSRLoss 中使用。
具有相应相似度分数的句子对,分数范围在相似度函数的范围内。默认为 [-1,1]。
- 输入
文本
标签
(句子_A, 句子_B) 对
浮点型相似度分数
- 关系
SparseCoSENTLoss
是使用pairwise_cos_sim
作为度量的 AnglELoss,而不是pairwise_angle_sim
。
示例
from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses model = SparseEncoder("distilbert/distilbert-base-uncased") train_dataset = Dataset.from_dict( { "sentence1": ["It's nice weather outside today.", "He drove to work."], "sentence2": ["It's so sunny.", "She walked to the store."], "score": [1.0, 0.3], } ) loss = losses.SpladeLoss( model=model, loss=losses.SparseAnglELoss(model), document_regularizer_weight=5e-5, use_document_regularizer_only=True ) trainer = SparseEncoderTrainer(model=model, train_dataset=train_dataset, loss=loss) trainer.train()
SparseMSELoss
- class sentence_transformers.sparse_encoder.losses.SparseMSELoss(model: SparseEncoder)[源代码]
计算计算出的句子嵌入和目标句子嵌入之间的 MSE 损失。当将句子嵌入扩展到新语言时使用此损失,如我们的出版物《Making Monolingual Sentence Embeddings Multilingual using Knowledge Distillation》中所述。
- 参数:
model – SparseEncoder (稀疏编码器)
- 要求
通常在知识蒸馏设置中使用经过微调的教师模型 M
- 输入
文本
标签
句子
模型句子嵌入
句子_1, 句子_2, ..., 句子_N
模型句子嵌入
- 关系
SparseMarginMSELoss
与此损失等效,但通过一个负例对增加了边距。
示例
from datasets import Dataset from sentence_transformers.sparse_encoder import SparseEncoder, SparseEncoderTrainer, losses student_model = SparseEncoder("prithivida/Splade_PP_en_v1") teacher_model = SparseEncoder("naver/splade-cocondenser-ensembledistil") train_dataset = Dataset.from_dict( { "english": ["The first sentence", "The second sentence", "The third sentence", "The fourth sentence"], "french": ["La première phrase", "La deuxième phrase", "La troisième phrase", "La quatrième phrase"], } ) def compute_labels(batch): return {"label": teacher_model.encode(batch["english"], convert_to_sparse_tensor=False)} train_dataset = train_dataset.map(compute_labels, batched=True) loss = losses.SparseMSELoss(student_model) trainer = SparseEncoderTrainer(model=student_model, train_dataset=train_dataset, loss=loss) trainer.train()