损失
sentence_transformers.cross_encoder.losses
定义了不同的损失函数,这些函数可用于在训练数据上微调 cross-encoder 模型。损失函数的选择在微调模型时起着至关重要的作用。它决定了我们的模型在特定下游任务中的表现。
遗憾的是,没有“一刀切”的损失函数。哪个损失函数合适取决于可用的训练数据和目标任务。考虑查看 损失概述 以帮助缩小您对损失函数(们)的选择范围。
BinaryCrossEntropyLoss
- class sentence_transformers.cross_encoder.losses.BinaryCrossEntropyLoss(model: CrossEncoder, activation_fn: Module = Identity(), pos_weight: Tensor | None = None, **kwargs)[source]
计算 CrossEncoder 模型的二元交叉熵损失。此损失用于训练模型,使其为正例对预测高 logit,为负例对预测低 logit。模型应使用
num_labels = 1
(即默认值)初始化,以预测一个类别。它已被用于训练许多强大的 CrossEncoder MS MARCO Reranker 模型。
- 参数:
model (
CrossEncoder
) – 要训练的 CrossEncoder 模型。activation_fn (
Module
) – 应用于 logits 的激活函数,在计算损失之前。默认为Identity
。pos_weight (Tensor, 可选) – 正例的权重。必须是类似
torch.Tensor
的torch.tensor(4)
,表示权重为 4。默认为 None。**kwargs – 传递给底层
torch.nn.BCEWithLogitsLoss
的其他关键字参数。
参考文献
- 要求
您的模型必须使用 num_labels = 1 (即默认值)初始化,以预测一个类别。
- 输入
文本
标签
模型输出标签的数量
(anchor, 正例/负例) 对
如果是正例则为 1,如果是负例则为 0
1
(sentence_A, sentence_B) 对
介于 0 和 1 之间的浮点相似度分数
1
- 建议
使用
mine_hard_negatives
和output_format="labeled-pair"
将问题-答案对转换为(anchor, 正例/负例) 对
格式,标签为 1 或 0,使用 hard negatives。
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset model = CrossEncoder("microsoft/mpnet-base") train_dataset = Dataset.from_dict({ "query": ["What are pandas?", "What are pandas?"], "response": ["Pandas are a kind of bear.", "Pandas are a kind of fish."], "label": [1, 0], }) loss = losses.BinaryCrossEntropyLoss(model) trainer = CrossEncoderTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
CrossEntropyLoss
- class sentence_transformers.cross_encoder.losses.CrossEntropyLoss(model: CrossEncoder, activation_fn: Module = Identity(), **kwargs)[source]
计算 CrossEncoder 模型的交叉熵损失。此损失用于训练模型,使其为给定的句子对预测正确的类别标签。类别数量应等于模型输出标签的数量。
- 参数:
model (
CrossEncoder
) – 要训练的 CrossEncoder 模型。activation_fn (
Module
) – 应用于 logits 的激活函数,在计算损失之前。默认为Identity
。**kwargs – 传递给底层
torch.nn.CrossEntropyLoss
的其他关键字参数。
参考文献
- 要求
您的模型可以使用 num_labels > 1 初始化,以预测多个类别。
数据集类别的数量应等于模型输出标签的数量 (model.num_labels)。
- 输入
文本
标签
模型输出标签的数量
(sentence_A, sentence_B) 对
类别
num_classes
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset model = CrossEncoder("microsoft/mpnet-base", num_labels=2) train_dataset = Dataset.from_dict({ "sentence1": ["How can I be a good geologist?", "What is the capital of France?"], "sentence2": ["What should I do to be a great geologist?", "What is the capital of Germany?"], "label": [1, 0], # 1: duplicate, 0: not duplicate }) loss = losses.CrossEntropyLoss(model) trainer = CrossEncoderTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
LambdaLoss
- class sentence_transformers.cross_encoder.losses.LambdaLoss(model: ~sentence_transformers.cross_encoder.CrossEncoder.CrossEncoder, weighting_scheme: ~sentence_transformers.cross_encoder.losses.LambdaLoss.BaseWeightingScheme | None = NDCGLoss2PPScheme( (ndcg_loss2): NDCGLoss2Scheme() (lambda_rank): LambdaRankScheme() ), k: int | None = None, sigma: float = 1.0, eps: float = 1e-10, reduction_log: ~typing.Literal['natural', 'binary'] = 'binary', activation_fn: ~torch.nn.modules.module.Module | None = Identity(), mini_batch_size: int | None = None)[source]
用于排序指标优化的 LambdaLoss 框架。此损失函数实现了用于排序指标优化的 LambdaLoss 框架,该框架提供了各种加权方案,包括 LambdaRank 和 NDCG 变体。该实现经过优化,可通过仅在模型推理期间处理有效文档来有效处理填充文档。
注意
每个查询的文档数量可能因
LambdaLoss
的样本而异。- 参数:
model (CrossEncoder) – 要训练的 CrossEncoder 模型
weighting_scheme (
BaseWeightingScheme
, optional) –用于损失的加权方案。
NoWeightingScheme
: 无加权方案 (weights = 1.0)NDCGLoss1Scheme
: NDCG Loss1 加权方案NDCGLoss2Scheme
: NDCG Loss2 加权方案LambdaRankScheme
: LambdaRank 加权方案NDCGLoss2PPScheme
: NDCG Loss2++ 加权方案
默认为 NDCGLoss2PPScheme。在原始 LambdaLoss 论文中,NDCGLoss2PPScheme 被证明达到了最强的性能,NDCGLoss2Scheme 紧随其后。
k (int, 可选) – 要考虑用于 NDCG@K 的文档数量。默认为 None(使用所有文档)。
sigma (float) – sigmoid 中使用的分数差异权重
eps (float) – 用于数值稳定性的一个小常数
reduction_log (str) – 要使用的对数类型 - “natural”: 自然对数 (log) - “binary”: 二进制对数 (log2)
activation_fn (
Module
) – 应用于 logits 的激活函数,在计算损失之前。默认为Identity
。mini_batch_size (int, 可选) –
每个前向传播中要处理的样本数。这对训练过程的内存消耗和速度有重大影响。有三种情况可能:
如果
mini_batch_size
为 None,则mini_batch_size
设置为批次大小。如果
mini_batch_size
大于 0,则批次将拆分为大小为mini_batch_size
的小批次。如果
mini_batch_size
小于等于 0,则整个批次一次处理。
默认为 None。
参考文献
用于排序指标优化的 LambdaLoss 框架: https://marc.najork.org/papers/cikm2018.pdf
Context-Aware Learning to Rank with Self-Attention: https://arxiv.org/abs/2005.10084
- 要求
具有多个文档的查询(列表式方法)
文档必须具有相关性分数/标签。支持二进制和连续标签。
- 输入
文本
标签
模型输出标签的数量
(query, [doc1, doc2, …, docN])
[score1, score2, …, scoreN]
1
- 建议
使用
mine_hard_negatives
和output_format="labeled-list"
将问题-答案对转换为所需的输入格式,并带有 hard negatives。
- 关系
LambdaLoss
据说比具有相同输入格式的其他损失函数表现更好。
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset model = CrossEncoder("microsoft/mpnet-base") train_dataset = Dataset.from_dict({ "query": ["What are pandas?", "What is the capital of France?"], "docs": [ ["Pandas are a kind of bear.", "Pandas are kind of like fish."], ["The capital of France is Paris.", "Paris is the capital of France.", "Paris is quite large."], ], "labels": [[1, 0], [1, 1, 0]], }) loss = losses.LambdaLoss(model) trainer = CrossEncoderTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
- class sentence_transformers.cross_encoder.losses.LambdaLoss.BaseWeightingScheme(*args, **kwargs)[source]
用于在 LambdaLoss 中实现加权方案的基类。
- class sentence_transformers.cross_encoder.losses.NoWeightingScheme(*args, **kwargs)[source]
无加权方案的实现 (weights = 1.0)。
- class sentence_transformers.cross_encoder.losses.NDCGLoss1Scheme(*args, **kwargs)[source]
NDCG Loss1 加权方案的实现。
它用于优化 NDCG 指标,但不建议使用此加权方案,因为 NDCGLoss2Scheme 和 NDCGLoss2PPScheme 在原始 LambdaLoss 论文中被证明达到了更优越的性能。
- class sentence_transformers.cross_encoder.losses.NDCGLoss2Scheme(*args, **kwargs)[source]
NDCG Loss2 加权方案的实现。
此方案使用比 NDCGLoss1Scheme 更严格的界限,并且在原始 LambdaLoss 论文中被证明达到了更优越的性能。它用于优化 NDCG 指标。
ListMLELoss
- class sentence_transformers.cross_encoder.losses.ListMLELoss(model: CrossEncoder, activation_fn: Module | None = Identity(), mini_batch_size: int | None = None, respect_input_order: bool = True)[source]
此损失函数实现了 ListMLE 排序学习算法,该算法使用基于排列最大似然估计的列表式方法。它最大化由真实标签引起的排列的似然性。
注意
每个查询的文档数量可以在使用
ListMLELoss
的样本之间变化。- 参数:
model (CrossEncoder) – 要训练的 CrossEncoder 模型
activation_fn (
Module
) – 应用于 logits 的激活函数,在计算损失之前。默认为Identity
。mini_batch_size (int, 可选) –
每个前向传播中要处理的样本数。这对训练过程的内存消耗和速度有重大影响。有三种情况可能:
如果
mini_batch_size
为 None,则mini_batch_size
设置为批次大小。如果
mini_batch_size
大于 0,则批次将拆分为大小为mini_batch_size
的小批次。如果
mini_batch_size
小于等于 0,则整个批次一次处理。
默认为 None。
respect_input_order (bool) – 是否尊重文档的原始输入顺序。如果为 True,则假定输入文档已按相关性排序(最相关的在前)。如果为 False,则按标签值对文档进行排序。默认为 True。
参考文献
- 要求
具有多个文档的查询(列表式方法)
文档必须具有相关性分数/标签。支持二进制和连续标签。
文档必须以定义的排序顺序排序。
- 输入
文本
标签
模型输出标签的数量
(query, [doc1, doc2, …, docN])
[score1, score2, …, scoreN]
1
- 建议
使用
mine_hard_negatives
和output_format="labeled-list"
将问题-答案对转换为所需的输入格式,并带有 hard negatives。
- 关系
PListMLELoss
是ListMLELoss
的扩展,并允许对损失进行位置加权。PListMLELoss
通常优于ListMLELoss
,建议使用前者。LambdaLoss
接受相同的输入,并且通常优于此损失。
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset model = CrossEncoder("microsoft/mpnet-base") train_dataset = Dataset.from_dict({ "query": ["What are pandas?", "What is the capital of France?"], "docs": [ ["Pandas are a kind of bear.", "Pandas are kind of like fish."], ["The capital of France is Paris.", "Paris is the capital of France.", "Paris is quite large."], ], "labels": [[1, 0], [1, 1, 0]], }) # Standard ListMLE loss respecting input order loss = losses.ListMLELoss(model) trainer = CrossEncoderTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
PListMLELoss
- class sentence_transformers.cross_encoder.losses.PListMLELoss(model: CrossEncoder, lambda_weight: PListMLELambdaWeight | None = PListMLELambdaWeight(), activation_fn: Module | None = Identity(), mini_batch_size: int | None = None, respect_input_order: bool = True)[source]
用于位置感知加权排序学习的 PListMLE 损失。此损失函数实现了 ListMLE 排序算法,该算法使用基于排列最大似然估计的列表式方法。它最大化由真实标签引起的排列的似然性,并具有位置感知加权。
此损失也称为位置感知 ListMLE 或 p-ListMLE。
注意
每个查询的文档数量可以在使用
PListMLELoss
的样本之间变化。- 参数:
model (CrossEncoder) – 要训练的 CrossEncoder 模型
lambda_weight (PListMLELambdaWeight, optional) – 要使用的加权方案。指定后,实现位置感知 ListMLE,该方法对不同的排名位置应用不同的权重。默认为 None(标准 PListMLE)。
activation_fn (
Module
) – 应用于 logits 的激活函数,在计算损失之前。默认为Identity
。mini_batch_size (int, 可选) –
每个前向传播中要处理的样本数。这对训练过程的内存消耗和速度有重大影响。有三种情况可能:
如果
mini_batch_size
为 None,则mini_batch_size
设置为批次大小。如果
mini_batch_size
大于 0,则批次将拆分为大小为mini_batch_size
的小批次。如果
mini_batch_size
小于等于 0,则整个批次一次处理。
默认为 None。
respect_input_order (bool) – 是否尊重文档的原始输入顺序。如果为 True,则假定输入文档已按相关性排序(最相关的在前)。如果为 False,则按标签值对文档进行排序。默认为 True。
参考文献
位置感知 ListMLE:排序的顺序学习过程:https://auai.org/uai2014/proceedings/individuals/164.pdf
- 要求
具有多个文档的查询(列表式方法)
文档必须具有相关性分数/标签。支持二进制和连续标签。
文档必须以定义的排序顺序排序。
- 输入
文本
标签
模型输出标签的数量
(query, [doc1, doc2, …, docN])
[score1, score2, …, scoreN]
1
- 建议
使用
mine_hard_negatives
和output_format="labeled-list"
将问题-答案对转换为所需的输入格式,并带有 hard negatives。
- 关系
PListMLELoss
是ListMLELoss
的扩展,并允许对损失进行位置加权。PListMLELoss
通常优于ListMLELoss
,建议使用前者。LambdaLoss
接受相同的输入,并且通常优于此损失。
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset model = CrossEncoder("microsoft/mpnet-base") train_dataset = Dataset.from_dict({ "query": ["What are pandas?", "What is the capital of France?"], "docs": [ ["Pandas are a kind of bear.", "Pandas are kind of like fish."], ["The capital of France is Paris.", "Paris is the capital of France.", "Paris is quite large."], ], "labels": [[1, 0], [1, 1, 0]], }) # Either: Position-Aware ListMLE with default weighting lambda_weight = losses.PListMLELambdaWeight() loss = losses.PListMLELoss(model, lambda_weight=lambda_weight) # or: Position-Aware ListMLE with custom weighting function def custom_discount(ranks): # e.g. ranks: [1, 2, 3, 4, 5] return 1.0 / torch.log1p(ranks) lambda_weight = losses.PListMLELambdaWeight(rank_discount_fn=custom_discount) loss = losses.PListMLELoss(model, lambda_weight=lambda_weight) trainer = CrossEncoderTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
ListNetLoss
- class sentence_transformers.cross_encoder.losses.ListNetLoss(model: CrossEncoder, activation_fn: Module | None = Identity(), mini_batch_size: int | None = None)[source]
用于排序学习的 ListNet 损失。此损失函数实现了 ListNet 排序算法,该算法使用列表式方法来学习排序模型。它最小化预测的排序分布与真实排序分布之间的交叉熵。该实现经过优化,可通过仅在模型推理期间处理有效文档来有效处理填充文档。
注意
每个查询的文档数量可以在使用
ListNetLoss
的样本之间变化。- 参数:
model (CrossEncoder) – 要训练的 CrossEncoder 模型
activation_fn (
Module
) – 应用于 logits 的激活函数,在计算损失之前。默认为Identity
。mini_batch_size (int, 可选) –
每个前向传播中要处理的样本数。这对训练过程的内存消耗和速度有重大影响。有三种情况可能:
如果
mini_batch_size
为 None,则mini_batch_size
设置为批次大小。如果
mini_batch_size
大于 0,则批次将拆分为大小为mini_batch_size
的小批次。如果
mini_batch_size
小于等于 0,则整个批次一次处理。
默认为 None。
参考文献
排序学习:从成对方法到列表式方法:https://www.microsoft.com/en-us/research/publication/learning-to-rank-from-pairwise-approach-to-listwise-approach/
Context-Aware Learning to Rank with Self-Attention: https://arxiv.org/abs/2005.10084
- 要求
具有多个文档的查询(列表式方法)
文档必须具有相关性分数/标签。支持二进制和连续标签。
- 输入
文本
标签
模型输出标签的数量
(query, [doc1, doc2, …, docN])
[score1, score2, …, scoreN]
1
- 建议
使用
mine_hard_negatives
和output_format="labeled-list"
将问题-答案对转换为所需的输入格式,并带有 hard negatives。
- 关系
LambdaLoss
接受相同的输入,并且通常优于此损失。
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset model = CrossEncoder("microsoft/mpnet-base") train_dataset = Dataset.from_dict({ "query": ["What are pandas?", "What is the capital of France?"], "docs": [ ["Pandas are a kind of bear.", "Pandas are kind of like fish."], ["The capital of France is Paris.", "Paris is the capital of France.", "Paris is quite large."], ], "labels": [[1, 0], [1, 1, 0]], }) loss = losses.ListNetLoss(model) trainer = CrossEncoderTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
MultipleNegativesRankingLoss
- class sentence_transformers.cross_encoder.losses.MultipleNegativesRankingLoss(model: CrossEncoder, num_negatives: int | None = 4, scale: int = 10.0, activation_fn: Module | None = Sigmoid())[source]
给定一个(anchor, positive)对列表或(anchor, positive, negative)三元组,此损失优化以下内容
给定一个 anchor(例如,一个问题),从批次中每个正例和负例(例如,所有答案)中,将最高相似度分配给相应的正例(即答案)。
如果您提供可选的负例,它们都将用作模型必须从中选择正确正例的额外选项。在合理的范围内,这种“选择”越难,模型就会变得越强大。因此,较高的批次大小会导致更多的批内负例,从而提高性能(达到一定程度)。
此损失函数非常适合训练用于检索设置的嵌入,在这些设置中,您具有正例对(例如(查询,答案)),因为它将在每个批次中随机采样
n-1
个负例文档。此损失也称为 InfoNCE 损失、SimCSE 损失、具有批内负例的交叉熵损失,或简称为批内负例损失。
- 参数:
model (
CrossEncoder
) – 要训练的 CrossEncoder 模型。num_negatives (int, optional) – 为每个 anchor 采样的批内负例数量。默认为 4。
scale (int, optional) – 相似度函数的输出乘以 scale 值。默认为 10.0。
activation_fn (
Module
) – 应用于 logits 的激活函数,之后计算损失。默认为Sigmoid
。
注意
当前的默认值将来可能会更改。建议进行实验。
参考文献
智能回复的高效自然语言回复建议,第 4.4 节:https://arxiv.org/pdf/1705.00652.pdf
- 要求
您的模型必须使用 num_labels = 1 (即默认值)初始化,以预测一个类别。
- 输入
文本
标签
模型输出标签的数量
(anchor, positive)对
无
1
(anchor, positive, negative)三元组
无
1
(anchor, positive, negative_1, …, negative_n)
无
1
- 建议
使用
BatchSamplers.NO_DUPLICATES
(docs
) 以确保没有批内负例是 anchor 或正例样本的重复项。使用
mine_hard_negatives
和output_format="n-tuple"
或output_format="triplet"
将问题-答案对转换为具有困难负例的三元组。
- 关系
CachedMultipleNegativesRankingLoss
等效于此损失,但它使用缓存,允许更大的批次大小(从而获得更好的性能),而无需额外的内存使用。但是,它速度稍慢。
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset model = CrossEncoder("microsoft/mpnet-base") train_dataset = Dataset.from_dict({ "query": ["What are pandas?", "What is the capital of France?"], "answer": ["Pandas are a kind of bear.", "The capital of France is Paris."], }) loss = losses.MultipleNegativesRankingLoss(model) trainer = CrossEncoderTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
CachedMultipleNegativesRankingLoss
- class sentence_transformers.cross_encoder.losses.CachedMultipleNegativesRankingLoss(model: CrossEncoder, num_negatives: int | None = 4, scale: float = 10.0, activation_fn: Module | None = Sigmoid(), mini_batch_size: int = 32, show_progress_bar: bool = False)[source]
提升版本的
MultipleNegativesRankingLoss
,它缓存 logits 相对于损失的梯度。这允许更大的批次大小,而无需额外的内存使用。但是,它速度稍慢。详细说明
它首先执行快速预测步骤,无需梯度/计算图即可获取所有 logits;
计算损失,反向传播到 logits 并缓存 logits 的梯度;
使用梯度/计算图执行第二个预测步骤,并将缓存的梯度连接到反向链中。
注意:所有步骤都使用小批量完成。在 GradCache 的原始实现中,(2)不是以小批量完成的,当批次大小很大时,需要大量内存。根据论文,梯度缓存会牺牲大约 20% 的计算时间。
给定一个(anchor, positive)对列表或(anchor, positive, negative)三元组,此损失优化以下内容
给定一个 anchor(例如,一个问题),从批次中每个正例和负例(例如,所有答案)中,将最高相似度分配给相应的正例(即答案)。
如果您提供可选的负例,它们都将用作模型必须从中选择正确正例的额外选项。在合理的范围内,这种“选择”越难,模型就会变得越强大。因此,较高的批次大小会导致更多的批内负例,从而提高性能(达到一定程度)。
此损失函数非常适合训练用于检索设置的嵌入,在这些设置中,您具有正例对(例如(查询,答案)),因为它将在每个批次中随机采样
n-1
个负例文档。此损失也称为带有 GradCache 的 InfoNCE 损失。
- 参数:
model (
CrossEncoder
) – 要训练的 CrossEncoder 模型。num_negatives (int, optional) – 为每个 anchor 采样的批内负例数量。默认为 4。
scale (int, optional) – 相似度函数的输出乘以 scale 值。默认为 10.0。
activation_fn (
Module
) – 应用于 logits 的激活函数,之后计算损失。默认为Sigmoid
。mini_batch_size (int, optional) – 前向传递的小批量大小。这会影响内存使用。默认为 32。
show_progress_bar (bool, optional) – 是否在前向传递期间显示进度条。默认为 False。
注意
当前的默认值将来可能会更改。建议进行实验。
参考文献
智能回复的高效自然语言回复建议,第 4.4 节:https://arxiv.org/pdf/1705.00652.pdf
在内存受限设置下扩展深度对比学习批次大小:https://arxiv.org/pdf/2101.06983.pdf
- 要求
您的模型必须使用 num_labels = 1 (即默认值)初始化,以预测一个类别。
应与较大的 per_device_train_batch_size 和较小的 mini_batch_size 一起使用,以获得卓越的性能,但训练时间比
MultipleNegativesRankingLoss
慢。
- 输入
文本
标签
模型输出标签的数量
(anchor, positive)对
无
1
(anchor, positive, negative)三元组
无
1
(anchor, positive, negative_1, …, negative_n)
无
1
- 建议
使用
BatchSamplers.NO_DUPLICATES
(docs
) 以确保没有批内负例是 anchor 或正例样本的重复项。使用
mine_hard_negatives
和output_format="n-tuple"
或output_format="triplet"
将问题-答案对转换为具有困难负例的三元组。
- 关系
等效于
MultipleNegativesRankingLoss
,但具有缓存,允许更大的批次大小(从而获得更好的性能),而无需额外的内存使用。此损失的训练速度也比MultipleNegativesRankingLoss
慢。
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset model = CrossEncoder("microsoft/mpnet-base") train_dataset = Dataset.from_dict({ "query": ["What are pandas?", "What is the capital of France?"], "answer": ["Pandas are a kind of bear.", "The capital of France is Paris."], }) loss = losses.CachedMultipleNegativesRankingLoss(model, mini_batch_size=32) trainer = CrossEncoderTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
MSELoss
- class sentence_transformers.cross_encoder.losses.MSELoss(model: CrossEncoder, activation_fn: Module = Identity(), **kwargs)[source]
计算计算出的查询-段落得分与目标查询-段落得分之间的 MSE 损失。此损失用于从教师交叉编码器模型或黄金标签中提炼交叉编码器模型。
- 参数:
model (
CrossEncoder
) – 要训练的 CrossEncoder 模型。activation_fn (
Module
) – 应用于 logits 的激活函数,之后计算损失。**kwargs – 传递给底层
torch.nn.MSELoss
的其他关键字参数。
注意
请注意标签和模型生成结果的量级。如果教师模型生成带有 Sigmoid 的 logits 以将其限制在 [0, 1] 范围内,则您可能希望在损失中使用 Sigmoid 激活函数。
参考文献
通过跨架构知识蒸馏改进高效神经排序模型:https://arxiv.org/abs/2010.02666
- 要求
您的模型必须使用 num_labels = 1 (即默认值)初始化,以预测一个类别。
通常在知识蒸馏设置中使用微调的交叉编码器教师模型 M。
- 输入
文本
标签
模型输出标签的数量
(sentence_A, sentence_B) 对
相似度得分
1
- 关系
MarginMSELoss
与此损失类似,但通过负例对具有边距。
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset student_model = CrossEncoder("microsoft/mpnet-base") teacher_model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L12-v2") train_dataset = Dataset.from_dict({ "query": ["What are pandas?", "What is the capital of France?"], "answer": ["Pandas are a kind of bear.", "The capital of France is Paris."], }) def compute_labels(batch): return { "label": teacher_model.predict(list(zip(batch["query"], batch["answer"]))) } train_dataset = train_dataset.map(compute_labels, batched=True) loss = losses.MSELoss(student_model) trainer = CrossEncoderTrainer( model=student_model, train_dataset=train_dataset, loss=loss, ) trainer.train()
MarginMSELoss
- class sentence_transformers.cross_encoder.losses.MarginMSELoss(model: CrossEncoder, activation_fn: Module = Identity(), **kwargs)[source]
计算
|sim(Query, Pos) - sim(Query, Neg)|
和|gold_sim(Query, Pos) - gold_sim(Query, Neg)|
之间的 MSE 损失。此损失通常用于从教师交叉编码器模型或黄金标签中提炼交叉编码器模型。与
MultipleNegativesRankingLoss
相比,两个段落不必严格为正例和负例,两者都可能与给定的查询相关或不相关。这可能是 MarginMSELoss 相对于 MultipleNegativesRankingLoss 的优势。注意
请注意标签和模型生成结果的量级。如果教师模型生成带有 Sigmoid 的 logits 以将其限制在 [0, 1] 范围内,则您可能希望在损失中使用 Sigmoid 激活函数。
- 参数:
model (
CrossEncoder
) – 要训练的 CrossEncoder 模型。activation_fn (
Module
) – 应用于 logits 的激活函数,之后计算损失。**kwargs – 传递给底层
torch.nn.MSELoss
的其他关键字参数。
参考文献
通过跨架构知识蒸馏改进高效神经排序模型:https://arxiv.org/abs/2010.02666
- 要求
您的模型必须使用 num_labels = 1 (即默认值)初始化,以预测一个类别。
通常在知识蒸馏设置中使用微调的交叉编码器教师模型 M。
- 输入
文本
标签
模型输出标签的数量
(query, passage_one, passage_two)三元组
gold_sim(query, passage_one) - gold_sim(query, passage_two)
1
- 关系
MSELoss
与此损失类似,但没有通过负例对的边距。
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset student_model = CrossEncoder("microsoft/mpnet-base") teacher_model = CrossEncoder("cross-encoder/ms-marco-MiniLM-L12-v2") train_dataset = Dataset.from_dict({ "query": ["What are pandas?", "What is the capital of France?"], "positive": ["Pandas are a kind of bear.", "The capital of France is Paris."], "negative": ["Pandas are a kind of fish.", "The capital of France is Berlin."], }) def compute_labels(batch): positive_scores = teacher_model.predict(list(zip(batch["query"], batch["positive"]))) negative_scores = teacher_model.predict(list(zip(batch["query"], batch["negative"]))) return { "label": positive_scores - negative_scores } train_dataset = train_dataset.map(compute_labels, batched=True) loss = losses.MarginMSELoss(student_model) trainer = CrossEncoderTrainer( model=student_model, train_dataset=train_dataset, loss=loss, ) trainer.train()
RankNetLoss
- class sentence_transformers.cross_encoder.losses.RankNetLoss(model: CrossEncoder, k: int | None = None, sigma: float = 1.0, eps: float = 1e-10, reduction_log: Literal['natural', 'binary'] = 'binary', activation_fn: Module | None = Identity(), mini_batch_size: int | None = None)[source]
用于排序学习的 RankNet 损失实现。此损失函数实现了 RankNet 算法,该算法通过使用神经网络优化成对文档比较来学习排序函数。该实现经过优化,可通过仅在模型推理期间处理有效文档来有效处理填充文档。
- 参数:
model (CrossEncoder) – 要训练的 CrossEncoder 模型
sigma (float) – sigmoid 中使用的分数差权重(默认值:1.0)
eps (float) – 用于数值稳定性的极小常数(默认值:1e-10)
activation_fn (
Module
) – 应用于 logits 的激活函数,在计算损失之前。默认为Identity
。mini_batch_size (int, optional) – 每次前向传递中要处理的样本数。这对训练过程的内存消耗和速度有重大影响。有三种可能的情况:- 如果
mini_batch_size
为 None,则mini_batch_size
设置为批次大小。- 如果mini_batch_size
大于 0,则批次将拆分为大小为mini_batch_size
的小批量。- 如果mini_batch_size
小于等于 0,则一次处理整个批次。默认为 None。
参考文献
- 要求
具有多个文档的查询(成对方法)
文档必须具有相关性分数/标签。支持二进制和连续标签。
- 输入
文本
标签
模型输出标签的数量
(query, [doc1, doc2, …, docN])
[score1, score2, …, scoreN]
1
- 建议
使用
mine_hard_negatives
和output_format="labeled-list"
将问题-答案对转换为所需的输入格式,并带有 hard negatives。
- 关系
LambdaLoss
可以看作是此损失的扩展,其中每个分数对都被加权。或者,此损失可以看作是LambdaLoss
在没有加权方案的情况下的特例。LambdaLoss
及其默认的 NDCGLoss2++ 加权方案,据传言,在相同的输入格式下,性能优于其他损失。
示例
from sentence_transformers.cross_encoder import CrossEncoder, CrossEncoderTrainer, losses from datasets import Dataset model = CrossEncoder("microsoft/mpnet-base") train_dataset = Dataset.from_dict({ "query": ["What are pandas?", "What is the capital of France?"], "docs": [ ["Pandas are a kind of bear.", "Pandas are kind of like fish."], ["The capital of France is Paris.", "Paris is the capital of France.", "Paris is quite large."], ], "labels": [[1, 0], [1, 1, 0]], }) loss = losses.RankNetLoss(model) trainer = CrossEncoderTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()