损失函数

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(稀疏词汇扩展)模型的损失函数,它结合了主损失函数和正则化项来控制效率。

此损失函数通过对查询和文档表示进行正则化以使其稀疏,从而平衡了有效性(通过主损失)和效率,减少了推理时的计算需求。

参数:
  • model – SparseEncoder 模型

  • loss – 可以使用的主要损失函数是 SparseEncoder 的任何损失,除了 CSR 相关损失和 FLOPs 损失。

  • 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 实现对比稀疏表示 (CSR) 模型的组合损失函数。

此损失结合了两个组件:

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

    重建原始嵌入。

  2. 一个主损失,在论文中是 SparseMultipleNegativesRankingLoss,它确保语义

    相似的句子具有相似的表示。

总损失是这两个损失的线性组合。

参数:
  • model – SparseEncoder 模型

  • loss – 主要损失函数可以是 SparseEncoder 的任何损失,除了 flops 损失和 CSRReconstruction 损失。如果为 None,则使用默认损失,即 SparseMultipleNegativesRankingLoss。

  • beta – 重建损失中 L_aux 组件的权重。默认为 0.1。

  • gamma – 主损失组件(默认的 MNRL,也称为 InfoNCE)的权重。默认为 1.0。

参考文献

  • 有关更多详细信息,请参阅论文“超越 Matryoshka:重新审视稀疏编码以实现自适应表示”

https://hugging-face.cn/papers/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 实现对比稀疏表示 (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>, gather_across_devices: bool = False)[source]

给定一个 (anchor, positive) 对或 (anchor, positive, negative) 三元组列表,此损失函数优化以下目标

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

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

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

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

参数:
  • model – SparseEncoder 模型

  • scale – 相似度函数的输出乘以 scale 值。在某些文献中,缩放参数被称为温度,它是 scale 的倒数。简而言之:scale = 1 / temperature,因此 scale=20.0 等同于 temperature=0.05。点积相似度通常使用 scale 为 1.0,余弦相似度通常使用 20.0 到 50.0 之间的值。

  • similarity_fct – 句子嵌入之间的相似度函数。默认使用点积。也可以设置为余弦相似度(然后将 scale 设置为例如 20.0)。

  • gather_across_devices – 如果为 True,则在计算损失之前收集所有设备上的嵌入。建议在多 GPU 上训练时使用,因为它允许更大的批量大小,但可能会由于通信开销而减慢训练速度,并可能导致内存不足错误。

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

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

输入

文本

标签

(锚点, 正例) 对

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

(anchor, positive, negative_1, ..., negative_n)

建议
  • 使用 BatchSamplers.NO_DUPLICATES (docs) 来确保批次中的负样本不是锚点或正面样本的重复项。

关系
  • 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(Query, Pos) - sim(Query, Neg)||gold_sim(Query, Pos) - gold_sim(Query, Neg)| 之间的 MSE 损失。默认情况下,sim() 是点积。gold_sim 通常是教师模型的相似度分数。

SparseMultipleNegativesRankingLoss 相比,这两个 passage 不必严格为正面和负面,它们都可以与给定查询相关或不相关。这可能是 SparseMarginMSELoss 相对于 SparseMultipleNegativesRankingLoss 的优势,但请注意,SparseMarginMSELoss 的训练速度要慢得多。对于 SparseMultipleNegativesRankingLoss,在批量大小为 64 的情况下,我们将一个查询与 128 个 passage 进行比较。对于 SparseMarginMSELoss,我们只将一个查询与两个 passage 进行比较。也可以使用 SparseMarginMSELoss 中的多个负样本,但训练会更慢。

参数:
  • model – SparseEncoder

  • similarity_fct – 要使用的相似度函数。

参考文献

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

  2. (查询,passage_one,passage_two)三元组或(查询,正面,负面_1,…,负面_n)

  3. 通常在知识蒸馏设置中与微调的教师 M 一起使用

输入

文本

标签

(查询, 段落_一, 段落_二) 三元组

M(query, passage_one) - M(query, passage_two)

(查询, 段落_一, 段落_二) 三元组

[M(query, passage_one), M(query, passage_two)]

(查询, 正例, 负例_1, ..., 负例_n)

[M(query, positive) - M(query, negative_i) for i in 1..n]

(查询, 正例, 负例_1, ..., 负例_n)

[M(query, positive), M(query, negative_1), …, M(query, negative_n)]

关系
  • SparseMSELoss 与此损失类似,但没有通过负对实现的边距。

示例

使用黄金标签,例如,如果您有句子的硬评分。假设您希望模型将具有相似“质量”的句子彼此靠近地嵌入。如果“text1”的质量为 5 分(满分 5 分),“text2”的质量为 1 分(满分 5 分),“text3”的质量为 3 分(满分 5 分),则一对的相似度可以定义为质量分数之差。因此,“text1”和“text2”之间的相似度为 4,“text1”和“text3”之间的相似度为 2。如果我们以此作为我们的“教师模型”,则标签变为 similraity(“text1”,“text2”)- similarity(“text1”,“text3”)= 4 - 2 = 2。

正值表示第一个 passage 比第二个 passage 更接近查询,而负值表示相反。

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. 包含查询-正面和查询-负面对之间教师模型分数的标签

输入

文本

标签

(查询, 正例, 负例)

[Teacher(query, positive), Teacher(query, negative)]

(查询, 正例, 负例_1, ..., 负例_n)

[Teacher(query, positive), Teacher(query, negative_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(||anchor - positive|| - ||anchor - negative|| + margin, 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_transformation – cos_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(余弦句子)。它期望 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 值。表示反温度。

参考文献

要求
  • 需要在 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(角度优化)。这是 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 值。表示反温度。

参考文献

要求
  • 需要在 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 损失。此损失用于在我们的出版物“通过知识蒸馏使单语句子嵌入多语化”中所述的将句子嵌入扩展到新语言时。

参数:

model – SparseEncoder

要求
  1. 通常在知识蒸馏设置中与微调的教师 M 一起使用

输入

文本

标签

句子

模型句子嵌入

sentence_1, sentence_2, ..., sentence_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()