损失
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)[source]
SpladeLoss 实现了 SPLADE (Sparse Lexical and Expansion) 模型的损失函数,该函数将主要损失函数与正则化项结合,以控制效率。
此损失函数通过正则化查询和文档表示使其稀疏,从而在推理时减少计算需求,平衡了有效性(通过主要损失)与效率。
- 参数:
model – SparseEncoder 模型
loss – 要使用的主要损失函数,可以是除 CSR 相关损失和 flops 损失之外的任何 SparseEncoder 损失。.
document_regularizer_weight – 语料库正则化项的权重。此项鼓励文档嵌入中的稀疏性。将应用于正向文档和所有提供的负向文档。在某些论文中,此参数被称为“lambda_d”(文档)或“lambda_c”(语料库)。
query_regularizer_weight – 查询正则化项的权重。此项鼓励查询嵌入中的稀疏性。如果为 None,则不应用查询正则化,如果您处于免推理设置中或使用了
use_document_regularizer_only=True
,则没有问题。否则,query_regularizer_weight
应大于 0。在某些论文中,此参数被称为“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
一起进行正则化。在训练对称文本(例如文档对)或更多文本时特别有用。
参考
有关更多详细信息,请参阅论文“从蒸馏到硬负采样:使稀疏神经 IR 模型更有效” 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)[source]
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)[source]
CSRLoss 为对比稀疏表示 (Contrastive Sparse Representation, CSR) 模型实现了一个组合损失函数。
此损失结合了两个组件
- 一个重建损失
CSRReconstructionLoss
,确保稀疏表示能够忠实地 重建原始嵌入。
- 一个重建损失
- 一个主要损失,在论文中是
SparseMultipleNegativesRankingLoss
,确保语义 相似的句子具有相似的表示。
- 一个主要损失,在论文中是
总损失是这两个损失的线性组合。
- 参数:
model – SparseEncoder 模型
loss – 要使用的主要损失函数,可以是除 flops 损失和 CSRReconstruction 损失之外的任何 SparseEncoder 损失。如果为 None,则使用默认损失,即 SparseMultipleNegativesRankingLoss。
beta – 重建损失中 L_aux 组件的权重。默认为 0.1。
gamma – 主要损失组件(默认为 MNRL,也称 InfoNCE)的权重。默认为 1.0。
参考
有关更多详细信息,请参阅论文“超越俄罗斯套娃:重新审视稀疏编码以实现自适应表示”
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)[source]
CSRReconstructionLoss 实现了对比稀疏表示 (Contrastive Sparse Representation, CSR) 模型的重建损失组件。
此损失通过三个组件确保稀疏编码能够准确地重建原始模型嵌入
主要重建损失 (L_k),衡量原始嵌入与其使用 top-k 稀疏组件重建后的误差。
次要重建损失 (L_4k),衡量使用 top-4k 稀疏组件的误差。
辅助损失 (L_aux),有助于学习残差信息。
- 参数:
model – 带有自编码器组件的 SparseEncoder 模型
beta – 辅助损失组件 (L_aux) 的权重
参考
有关更多详细信息,请参阅论文“超越俄罗斯套娃:重新审视稀疏编码以实现自适应表示” 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>)[source]
给定(锚点,正例)对或(锚点,正例,负例)三元组列表,此损失函数优化以下目标
给定一个锚点(例如问题),在批次中的所有正例和负例(例如所有答案)中,将其与对应的正例(即答案)分配最高的相似度。
如果您提供可选的负例,它们都将用作额外的选项,模型必须从中选择正确的正例。在合理范围内,这种“选择”越困难,模型就会变得越强大。因此,更高的批次大小会导致更多的批内负例,从而提高性能(达到一定程度)。
此损失函数非常适合训练用于检索设置的嵌入,在这些设置中您有正例对(例如(查询,答案)),因为它会在每个批次中随机采样
n-1
个负文档。此损失函数也称为 InfoNCE 损失、SimCSE 损失、带批内负例的交叉熵损失,或简单地称为批内负例损失。
- 参数:
model – SparseEncoder 模型
scale – 相似度函数的输出乘以缩放值
similarity_fct – 句子嵌入之间的相似度函数。默认情况下为点积。也可以设置为余弦相似度(然后将 scale 设置为 20)
- 要求
需要在 SpladeLoss 或 CSRLoss 中用作损失函数。
(锚点,正例)对或(锚点,正例,负例)三元组
- 输入
文本
标签
(锚点,正例)对
无
(锚点,正例,负例)三元组
无
(锚点,正例,负例_1,…,负例_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>)[source]
计算
|sim(查询, 正例) - sim(查询, 负例)|
与|gold_sim(查询, 正例) - gold_sim(查询, 负例)|
之间的 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)[source]
计算从学生模型和教师模型的相似度分数导出的概率分布之间的 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)示例
包含教师模型在查询-正例和查询-负例对之间的分数的标签
- 输入
文本
标签
(查询,正例,负例)
[教师(查询, 正例), 教师(查询, 负例)]
(查询,正例,负例_1,…,负例_n)
[教师(查询, 正例), 教师(查询, 负例_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)[source]
此类实现了三元组损失。给定一个(锚点,正例,负例)三元组,该损失函数在最小化锚点与正例之间距离的同时,最大化锚点与负例之间的距离。它计算以下损失函数
loss = max(||锚点 - 正例|| - ||锚点 - 负例|| + 边界, 0)
.边界是一个重要的超参数,需要相应地进行调整。
- 参数:
model – SparseEncoder
distance_metric – 用于计算两个嵌入之间距离的函数。TripletDistanceMetric 类包含可使用的常见距离度量。
triplet_margin – 负例与锚点的距离应至少比正例远这么多。
参考
有关更多详细信息,请参阅:https://en.wikipedia.org/wiki/Triplet_loss
- 要求
需要在 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())[source]
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
是SparseCoSENTLoss
,但使用pairwise_angle_sim
作为度量,而不是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>)[source]
此类实现了 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 – 用于计算嵌入之间PAIRWISE相似度的函数。默认是
util.pairwise_cos_sim
。scale – 相似度函数的输出乘以缩放值。表示逆温度。
参考
有关更多详细信息,请参阅:https://kexue.fm/archives/8847
- 要求
需要在 SpladeLoss 或 CSRLoss 中用作损失函数。
句子对及其对应的相似度分数,在相似度函数范围内。默认是 [-1,1]。
- 输入
文本
标签
(句子_A,句子_B)对
浮点相似度分数
- 关系
SparseAnglELoss
是 SparseCoSENTLoss,但使用pairwise_angle_sim
作为度量,而不是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)[source]
此类实现了 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 – 相似度函数的输出乘以缩放值。表示逆温度。
参考
有关更多详细信息,请参阅:https://arxiv.org/abs/2309.12871v1
- 要求
需要在 SpladeLoss 或 CSRLoss 中用作损失函数。
句子对及其对应的相似度分数,在相似度函数范围内。默认是 [-1,1]。
- 输入
文本
标签
(句子_A,句子_B)对
浮点相似度分数
- 关系
SparseCoSENTLoss
是 AnglELoss,但使用pairwise_cos_sim
作为度量,而不是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)[source]
计算计算出的句子嵌入与目标句子嵌入之间的 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()