损失

sentence_transformers.sparse_encoder.losses 定义了可用于在训练数据上微调稀疏嵌入模型的不同损失函数。损失函数的选择在微调模型时起着关键作用。它决定了我们的嵌入模型在特定下游任务上的表现。

遗憾的是,没有“一刀切”的损失函数。哪种损失函数适用取决于可用的训练数据和目标任务。建议查看损失概览以帮助缩小您的损失函数选择范围。

警告

要训练 SparseEncoder,您需要根据架构选择 SpladeLossCSRLoss。这些是包装损失,它们在主要损失函数之上添加了稀疏性正则化,主要损失函数必须作为参数提供。唯一可以独立使用的损失是 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 一起进行正则化。在训练对称文本(例如文档对)或更多文本时特别有用。

参考

要求
  1. 输入要求取决于所选的损失

  2. 通常在知识蒸馏设置和相关损失中与教师模型一起使用

示例

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 – 嵌入中非零(活动)元素数量的可选阈值。如果指定,只有非零(活动)元素数量超过此阈值的嵌入才会被考虑。这有助于忽略过于稀疏且可能对损失没有显著贡献的嵌入。

参考

关系
  • 作为 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) 模型实现了一个组合损失函数。

此损失结合了两个组件

  1. 一个重建损失 CSRReconstructionLoss,确保稀疏表示能够忠实地

    重建原始嵌入。

  2. 一个主要损失,在论文中是 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

要求
  1. 输入要求取决于所选的损失

  2. 使用 SparseEncoder 模型的自编码器组件

关系

示例

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) 模型的重建损失组件。

此损失通过三个组件确保稀疏编码能够准确地重建原始模型嵌入

  1. 主要重建损失 (L_k),衡量原始嵌入与其使用 top-k 稀疏组件重建后的误差。

  2. 次要重建损失 (L_4k),衡量使用 top-4k 稀疏组件的误差。

  3. 辅助损失 (L_aux),有助于学习残差信息。

参数:
  • model – 带有自编码器组件的 SparseEncoder 模型

  • beta – 辅助损失组件 (L_aux) 的权重

参考

要求
  1. 模型必须配置为输出必要的重建组件

  2. 与实现组合稀疏自编码的 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]

给定(锚点,正例)对或(锚点,正例,负例)三元组列表,此损失函数优化以下目标

  1. 给定一个锚点(例如问题),在批次中的所有正例和负例(例如所有答案)中,将其与对应的正例(即答案)分配最高的相似度。

如果您提供可选的负例,它们都将用作额外的选项,模型必须从中选择正确的正例。在合理范围内,这种“选择”越困难,模型就会变得越强大。因此,更高的批次大小会导致更多的批内负例,从而提高性能(达到一定程度)。

此损失函数非常适合训练用于检索设置的嵌入,在这些设置中您有正例对(例如(查询,答案)),因为它会在每个批次中随机采样 n-1 个负文档。

此损失函数也称为 InfoNCE 损失、SimCSE 损失、带批内负例的交叉熵损失,或简单地称为批内负例损失。

参数:
  • model – SparseEncoder 模型

  • scale – 相似度函数的输出乘以缩放值

  • similarity_fct – 句子嵌入之间的相似度函数。默认情况下为点积。也可以设置为余弦相似度(然后将 scale 设置为 20)

要求
  1. 需要在 SpladeLoss 或 CSRLoss 中用作损失函数。

  2. (锚点,正例)对或(锚点,正例,负例)三元组

输入

文本

标签

(锚点,正例)对

(锚点,正例,负例)三元组

(锚点,正例,负例_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 – 要使用的相似度函数。

参考

要求
  1. 需要在 SpladeLoss 或 CSRLoss 中用作损失函数。

  2. (查询,段落一,段落二)三元组或(查询,正例,负例_1,…,负例_n)

  3. 通常与微调过的教师 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。

参考

要求
  1. 需要在 SpladeLoss 或 CSRLoss 中用作损失函数。

  2. (查询,正例,负例_1,…,负例_n)示例

  3. 包含教师模型在查询-正例和查询-负例对之间的分数的标签

输入

文本

标签

(查询,正例,负例)

[教师(查询, 正例), 教师(查询, 负例)]

(查询,正例,负例_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 – 负例与锚点的距离应至少比正例远这么多。

参考

要求
  1. 需要在 SpladeLoss 或 CSRLoss 中用作损失函数。

  2. (锚点,正例,负例)三元组

输入

文本

标签

(锚点,正例,负例)三元组

示例

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_transformationcos_score_transformation 函数应用于 cosine_similarity 之上。默认情况下,使用恒等函数(即不变)。

要求
  • 需要在 SpladeLoss 或 CSRLoss 中用作损失函数。

  • 句子对及其对应的相似度分数,范围 [0, 1]

输入

文本

标签

(句子_A,句子_B)对

浮点相似度分数

关系

示例

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 – 相似度函数的输出乘以缩放值。表示逆温度。

参考

要求
  • 需要在 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 – 相似度函数的输出乘以缩放值。表示逆温度。

参考

要求
  • 需要在 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

要求
  1. 通常在知识蒸馏设置中使用微调过的教师 M 模型

输入

文本

标签

句子

模型句子嵌入

句子_1, 句子_2, …, 句子_N

模型句子嵌入

关系

示例

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()