损失
sentence_transformers.losses
定义了不同的损失函数,这些函数可用于在训练数据上微调嵌入模型。损失函数的选择在微调模型时起着至关重要的作用。它决定了我们的嵌入模型在特定下游任务中的表现。
遗憾的是,没有“一刀切”的损失函数。哪个损失函数合适取决于可用的训练数据和目标任务。考虑查看 损失概述 以帮助缩小您对损失函数(或多个函数)的选择范围。
BatchAllTripletLoss
- class sentence_transformers.losses.BatchAllTripletLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, distance_metric=<function BatchHardTripletLossDistanceFunction.eucledian_distance>, margin: float = 5)[source]
BatchAllTripletLoss 接收一个包含(句子,标签)对的批次,并计算所有可能的有效三元组的损失,即,锚点和正例必须具有相同的标签,锚点和负例必须具有不同的标签。标签必须是整数,相同的标签表示来自同一类别的句子。您的训练数据集必须包含每个标签类别至少 2 个示例。
- 参数:
model – SentenceTransformer 模型
distance_metric – 返回两个嵌入之间距离的函数。 SiameseDistanceMetric 类包含可以使用的预定义指标。
margin – 负样本应比正样本与锚点的距离至少远 margin。
参考文献
来源: https://github.com/NegatioN/OnlineMiningTripletLoss/blob/master/online_triplet_loss/losses.py
论文:In Defense of the Triplet Loss for Person Re-Identification, https://arxiv.org/abs/1703.07737
- 要求
每个句子必须标记一个类别。
您的数据集必须包含每个标签类别至少 2 个示例。
- 输入
文本
标签
单句
类别
- 建议
使用
BatchSamplers.GROUP_BY_LABEL
(文档
) 以确保每个批次包含每个标签类别 2 个以上的示例。
- 关系
BatchHardTripletLoss
仅使用最难的正例和负例样本,而不是所有可能的有效三元组。BatchHardSoftMarginTripletLoss
仅使用最难的正例和负例样本,而不是所有可能的有效三元组。此外,它不需要设置边距。BatchSemiHardTripletLoss
仅使用半难三元组,有效三元组,而不是所有可能的有效三元组。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") # E.g. 0: sports, 1: economy, 2: politics train_dataset = Dataset.from_dict({ "sentence": [ "He played a great game.", "The stock is up 20%", "They won 2-1.", "The last goal was amazing.", "They all voted against the bill.", ], "label": [0, 1, 0, 0, 2], }) loss = losses.BatchAllTripletLoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
BatchHardSoftMarginTripletLoss
- class sentence_transformers.losses.BatchHardSoftMarginTripletLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, distance_metric=<function BatchHardTripletLossDistanceFunction.eucledian_distance>)[source]
BatchHardSoftMarginTripletLoss 接收一个包含(句子,标签)对的批次,并计算所有可能的有效三元组的损失,即,锚点和正例必须具有相同的标签,锚点和负例必须具有不同的标签。标签必须是整数,相同的标签表示来自同一类别的句子。您的训练数据集必须包含每个标签类别至少 2 个示例。这种软边距变体不需要设置边距。
- 参数:
model – SentenceTransformer 模型
distance_metric – 返回两个嵌入之间距离的函数。 SiameseDistanceMetric 类包含可以使用的预定义指标。
- 定义
- 简单三元组:
损失为 0 的三元组,因为
distance(anchor, positive) + margin < distance(anchor, negative)
。- 难三元组:
负例比正例更接近锚点的三元组,即
distance(anchor, negative) < distance(anchor, positive)
。- 半难三元组:
负例不比正例更接近锚点,但仍然有正损失的三元组,即
distance(anchor, positive) < distance(anchor, negative) + margin
。
参考文献
来源: https://github.com/NegatioN/OnlineMiningTripletLoss/blob/master/online_triplet_loss/losses.py
论文:In Defense of the Triplet Loss for Person Re-Identification, https://arxiv.org/abs/1703.07737
- 要求
每个句子必须标记一个类别。
您的数据集必须包含每个标签类别至少 2 个示例。
您的数据集应包含难正例和负例。
- 输入
文本
标签
单句
类别
- 建议
使用
BatchSamplers.GROUP_BY_LABEL
(文档
) 以确保每个批次包含每个标签类别 2 个以上的示例。
- 关系
BatchHardTripletLoss
使用用户指定的边距,而此损失不需要设置边距。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") # E.g. 0: sports, 1: economy, 2: politics train_dataset = Dataset.from_dict({ "sentence": [ "He played a great game.", "The stock is up 20%", "They won 2-1.", "The last goal was amazing.", "They all voted against the bill.", ], "label": [0, 1, 0, 0, 2], }) loss = losses.BatchHardSoftMarginTripletLoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
BatchHardTripletLoss
- class sentence_transformers.losses.BatchHardTripletLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, distance_metric=<function BatchHardTripletLossDistanceFunction.eucledian_distance>, margin: float = 5)[source]
BatchHardTripletLoss 接收一个包含(句子,标签)对的批次,并计算所有可能的有效三元组的损失,即,锚点和正例必须具有相同的标签,锚点和负例必须具有不同的标签。然后,它查找最难的正例和最难的负例。标签必须是整数,相同的标签表示来自同一类别的句子。您的训练数据集必须包含每个标签类别至少 2 个示例。
- 参数:
model – SentenceTransformer 模型
distance_metric – 返回两个嵌入之间距离的函数。 SiameseDistanceMetric 类包含可以使用的预定义指标
margin – 负样本应比正样本与锚点的距离至少远 margin。
- 定义
- 简单三元组:
损失为 0 的三元组,因为
distance(anchor, positive) + margin < distance(anchor, negative)
。- 难三元组:
负例比正例更接近锚点的三元组,即
distance(anchor, negative) < distance(anchor, positive)
。- 半难三元组:
负例不比正例更接近锚点,但仍然有正损失的三元组,即
distance(anchor, positive) < distance(anchor, negative) + margin
。
参考文献
来源: https://github.com/NegatioN/OnlineMiningTripletLoss/blob/master/online_triplet_loss/losses.py
论文:In Defense of the Triplet Loss for Person Re-Identification, https://arxiv.org/abs/1703.07737
- 要求
每个句子必须标记一个类别。
您的数据集必须包含每个标签类别至少 2 个示例。
您的数据集应包含难正例和负例。
- 输入
文本
标签
单句
类别
- 建议
使用
BatchSamplers.GROUP_BY_LABEL
(文档
) 以确保每个批次包含每个标签类别 2 个以上的示例。
- 关系
BatchAllTripletLoss
使用所有可能的有效三元组,而不是仅使用最难的正例和负例样本。BatchSemiHardTripletLoss
仅使用半难三元组,有效三元组,而不是仅使用最难的正例和负例样本。BatchHardSoftMarginTripletLoss
不需要设置边距,而此损失需要。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") # E.g. 0: sports, 1: economy, 2: politics train_dataset = Dataset.from_dict({ "sentence": [ "He played a great game.", "The stock is up 20%", "They won 2-1.", "The last goal was amazing.", "They all voted against the bill.", ], "label": [0, 1, 0, 0, 2], }) loss = losses.BatchHardTripletLoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
BatchSemiHardTripletLoss
- class sentence_transformers.losses.BatchSemiHardTripletLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, distance_metric=<function BatchHardTripletLossDistanceFunction.eucledian_distance>, margin: float = 5)[source]
BatchSemiHardTripletLoss 接收一个包含(标签,句子)对的批次,并计算所有可能的有效三元组的损失,即,锚点和正例必须具有相同的标签,锚点和负例必须具有不同的标签。然后,它查找半难正例和负例。标签必须是整数,相同的标签表示来自同一类别的句子。您的训练数据集必须包含每个标签类别至少 2 个示例。
- 参数:
model – SentenceTransformer 模型
distance_metric – 返回两个嵌入之间距离的函数。 SiameseDistanceMetric 类包含可以使用的预定义指标
margin – 负样本应比正样本与锚点的距离至少远 margin。
- 定义
- 简单三元组:
损失为 0 的三元组,因为
distance(anchor, positive) + margin < distance(anchor, negative)
。- 难三元组:
负例比正例更接近锚点的三元组,即
distance(anchor, negative) < distance(anchor, positive)
。- 半难三元组:
负例不比正例更接近锚点,但仍然有正损失的三元组,即
distance(anchor, positive) < distance(anchor, negative) + margin
。
参考文献
来源: https://github.com/NegatioN/OnlineMiningTripletLoss/blob/master/online_triplet_loss/losses.py
论文:In Defense of the Triplet Loss for Person Re-Identification, https://arxiv.org/abs/1703.07737
- 要求
每个句子必须标记一个类别。
您的数据集必须包含每个标签类别至少 2 个示例。
您的数据集应包含半难正例和负例。
- 输入
文本
标签
单句
类别
- 建议
使用
BatchSamplers.GROUP_BY_LABEL
(文档
) 以确保每个批次包含每个标签类别 2 个以上的示例。
- 关系
BatchHardTripletLoss
仅使用最难的正例和负例样本,而不是仅使用半难正例和负例。BatchAllTripletLoss
使用所有可能的有效三元组,而不是仅使用半难正例和负例。BatchHardSoftMarginTripletLoss
仅使用最难的正例和负例样本,而不是仅使用半难正例和负例。此外,它不需要设置边距。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") # E.g. 0: sports, 1: economy, 2: politics train_dataset = Dataset.from_dict({ "sentence": [ "He played a great game.", "The stock is up 20%", "They won 2-1.", "The last goal was amazing.", "They all voted against the bill.", ], "label": [0, 1, 0, 0, 2], }) loss = losses.BatchSemiHardTripletLoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
ContrastiveLoss
- class sentence_transformers.losses.ContrastiveLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, distance_metric=<function SiameseDistanceMetric.<lambda>>, margin: float = 0.5, size_average: bool = True)[source]
对比损失。期望输入两个文本和一个标签(0 或 1)。如果标签 == 1,则减小两个嵌入之间的距离。如果标签 == 0,则增加嵌入之间的距离。
- 参数:
model – SentenceTransformer 模型
distance_metric – 返回两个嵌入之间距离的函数。 SiameseDistanceMetric 类包含可以使用的预定义指标
margin – 负样本(标签 == 0)的距离应至少为边距值。
size_average – 按小批量的大小取平均值。
参考文献
- 要求
(锚点,正例/负例)对
- 输入
文本
标签
(锚点,正例/负例)对
如果是正例,则为 1,如果是负例,则为 0
- 关系
OnlineContrastiveLoss
类似,但使用难正例和难负例对。它通常会产生更好的结果。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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."], "label": [1, 0], }) loss = losses.ContrastiveLoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
OnlineContrastiveLoss
- class sentence_transformers.losses.OnlineContrastiveLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, distance_metric=<function SiameseDistanceMetric.<lambda>>, margin: float = 0.5)[source]
此在线对比损失与
ConstrativeLoss
类似,但它选择难正例(距离较远的正例)和难负例对(距离较近的负例),并且仅针对这些对计算损失。此损失通常比 ContrastiveLoss 产生更好的性能。- 参数:
model – SentenceTransformer 模型
distance_metric – 返回两个嵌入之间距离的函数。 SiameseDistanceMetric 类包含可以使用的预定义指标
margin – 负样本(标签 == 0)的距离应至少为边距值。
参考文献
- 要求
(锚点,正例/负例)对
数据应包含难正例和难负例
- 输入
文本
标签
(锚点,正例/负例)对
如果是正例,则为 1,如果是负例,则为 0
- 关系
ContrastiveLoss
类似,但不使用难正例和难负例对。OnlineContrastiveLoss
通常会产生更好的结果。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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."], "label": [1, 0], }) loss = losses.OnlineContrastiveLoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
ContrastiveTensionLoss
- class sentence_transformers.losses.ContrastiveTensionLoss(model: SentenceTransformer)[source]
此损失仅期望单个句子,没有任何标签。正例和负例对通过随机抽样自动创建,使得正例对由两个相同的句子组成,而负例对由两个不同的句子组成。创建编码器模型的独立副本,用于编码每对句子的第一个句子。原始编码器模型对第二个句子进行编码。使用生成的标签(如果是正例,则为 1;如果是负例,则为 0)使用二元交叉熵目标来比较和评分嵌入。
请注意,您必须为此损失使用 ContrastiveTensionDataLoader 。 ContrastiveTensionDataLoader 的 pos_neg_ratio 可用于确定每个正例对的负例对数量。
通常,建议使用
ContrastiveTensionLossInBatchNegatives
而不是此损失,因为它提供了更强的训练信号。- 参数:
model – SentenceTransformer 模型
参考文献
具有对比张力的语义重新调整: https://openreview.net/pdf?id=Ov_sMNau-PF
- 输入
文本
标签
单句
无
- 关系
ContrastiveTensionLossInBatchNegatives
使用批内负采样,与此损失相比,它提供了更强的训练信号。
示例
from sentence_transformers import SentenceTransformer, losses from sentence_transformers.losses import ContrastiveTensionDataLoader model = SentenceTransformer('all-MiniLM-L6-v2') train_examples = [ 'This is the 1st sentence', 'This is the 2nd sentence', 'This is the 3rd sentence', 'This is the 4th sentence', 'This is the 5th sentence', 'This is the 6th sentence', 'This is the 7th sentence', 'This is the 8th sentence', 'This is the 9th sentence', 'This is the final sentence', ] train_dataloader = ContrastiveTensionDataLoader(train_examples, batch_size=3, pos_neg_ratio=3) train_loss = losses.ContrastiveTensionLoss(model=model) model.fit( [(train_dataloader, train_loss)], epochs=10, )
初始化内部模块状态,nn.Module 和 ScriptModule 共享该状态。
ContrastiveTensionLossInBatchNegatives
- class sentence_transformers.losses.ContrastiveTensionLossInBatchNegatives(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, scale: float = 20.0, similarity_fct=<function cos_sim>)[source]
此损失仅期望单个句子,没有任何标签。正例和负例对通过随机抽样自动创建,使得正例对由两个相同的句子组成,而负例对由两个不同的句子组成。创建编码器模型的独立副本,用于编码每对句子的第一个句子。原始编码器模型对第二个句子进行编码。与
ContrastiveTensionLoss
不同,此损失使用批次负采样策略,即负例对从批次中采样。与原始的ContrastiveTensionLoss
相比,使用批内负采样提供了更强的训练信号。性能通常会随着批次大小的增加而提高。请注意,对于此损失,您不应使用 ContrastiveTensionDataLoader ,而只需使用带有 InputExample 实例的普通 DataLoader。每个 InputExample 实例的两个文本应相同。
- 参数:
model – SentenceTransformer 模型
scale – 相似度函数的输出乘以 scale 值
similarity_fct – 句子嵌入之间的相似度函数。 默认情况下为 cos_sim。 也可以设置为点积(然后将 scale 设置为 1)
参考文献
具有对比张力的语义重新调整: https://openreview.net/pdf?id=Ov_sMNau-PF
- 关系
ContrastiveTensionLoss
不在批内选择负例对,导致训练信号弱于此损失。
- 输入
文本
标签
(锚点,锚点)对
无
示例
from sentence_transformers import SentenceTransformer, losses from torch.utils.data import DataLoader model = SentenceTransformer('all-MiniLM-L6-v2') train_examples = [ InputExample(texts=['This is a positive pair', 'Where the distance will be minimized'], label=1), InputExample(texts=['This is a negative pair', 'Their distance will be increased'], label=0), ] train_examples = [ InputExample(texts=['This is the 1st sentence', 'This is the 1st sentence']), InputExample(texts=['This is the 2nd sentence', 'This is the 2nd sentence']), InputExample(texts=['This is the 3rd sentence', 'This is the 3rd sentence']), InputExample(texts=['This is the 4th sentence', 'This is the 4th sentence']), InputExample(texts=['This is the 5th sentence', 'This is the 5th sentence']), ] train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=32) train_loss = losses.ContrastiveTensionLossInBatchNegatives(model=model) model.fit( [(train_dataloader, train_loss)], epochs=10, )
CoSENTLoss
- class sentence_transformers.losses.CoSENTLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, scale: float = 20.0, similarity_fct=<function pairwise_cos_sim>)[source]
此类实现了 CoSENT (Cosine Sentence) 损失函数。它期望每个 InputExample 都包含一对文本和一个浮点值标签,该标签表示这对文本之间预期的相似度得分。
它计算以下损失函数
loss = logsum(1+exp(s(i,j)-s(k,l))+exp...)
,其中(i,j)
和(k,l)
是批次中任何输入对,使得(i,j)
的预期相似度大于(k,l)
。求和是对批次中所有满足此条件的输入对组合进行的。轶事实验表明,此损失函数比
CosineSimilarityLoss
产生更强大的训练信号,从而实现更快的收敛速度和性能更优越的最终模型。因此,CoSENTLoss 可以用作任何训练脚本中CosineSimilarityLoss
的直接替代品。- 参数:
model – SentenceTransformerModel
similarity_fct – 用于计算嵌入之间成对相似度的函数。默认为
util.pairwise_cos_sim
。scale – 相似度函数的输出乘以 scale 值。表示逆温度。
参考文献
更多详情,请参阅: https://kexue.fm/archives/8847
- 要求
句子对及其对应的相似度得分,范围在相似度函数范围内。默认值为 [-1,1]。
- 输入
文本
标签
(句子 A,句子 B)对
浮点型相似度得分
- 关系
AnglELoss
是 CoSENTLoss 的变体,它使用pairwise_angle_sim
作为度量指标,而不是pairwise_cos_sim
。CosineSimilarityLoss
似乎比 CoSENTLoss 产生更弱的训练信号。在我们的实验中,建议使用 CoSENTLoss。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.CoSENTLoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
AnglELoss
- class sentence_transformers.losses.AnglELoss(model: SentenceTransformer, scale: float = 20.0)[source]
此类实现了 AnglE (Angle Optimized) 损失函数。这是
CoSENTLoss
的一种修改,旨在解决以下问题:当余弦函数接近其波形顶部或底部时,其梯度接近于 0。这可能会阻碍优化过程,因此 AnglE 建议优化复数空间中的角度差,以减轻这种影响。它期望每个 InputExample 都包含一对文本和一个浮点值标签,该标签表示这对文本之间预期的相似度得分。
它计算以下损失函数
loss = logsum(1+exp(s(k,l)-s(i,j))+exp...)
,其中(i,j)
和(k,l)
是批次中任何输入对,使得(i,j)
的预期相似度大于(k,l)
。求和是对批次中所有满足此条件的输入对组合进行的。这与 CoSENTLoss 相同,只是相似度函数不同。- 参数:
model – SentenceTransformerModel
scale – 相似度函数的输出乘以 scale 值。表示逆温度。
参考文献
更多详情,请参阅: https://arxiv.org/abs/2309.12871v1
- 要求
句子对及其对应的相似度得分,范围在相似度函数范围内。默认值为 [-1,1]。
- 输入
文本
标签
(句子 A,句子 B)对
浮点型相似度得分
- 关系
CoSENTLoss
是 AnglELoss 的变体,它使用pairwise_cos_sim
作为度量指标,而不是pairwise_angle_sim
。CosineSimilarityLoss
似乎比CoSENTLoss
或AnglELoss
产生更弱的训练信号。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.AnglELoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
CosineSimilarityLoss

对于每个句子对,我们将句子 A 和句子 B 通过我们的网络,生成嵌入 u 和 v。这些嵌入的相似度使用余弦相似度计算,并将结果与黄金相似度得分进行比较。
这使得我们的网络能够进行微调,以识别句子的相似性。
- class sentence_transformers.losses.CosineSimilarityLoss(model: SentenceTransformer, loss_fct: Module = MSELoss(), cos_score_transformation: Module = Identity())[source]
CosineSimilarityLoss 期望 InputExamples 包含两个文本和一个浮点标签。它计算向量
u = model(sentence_A)
和v = model(sentence_B)
,并测量两者之间的余弦相似度。默认情况下,它最小化以下损失:||input_label - cos_score_transformation(cosine_sim(u,v))||_2
。- 参数:
model – SentenceTransformer 模型
loss_fct – 应该使用哪个 PyTorch 损失函数来比较
cosine_similarity(u, v)
和 input_label?默认情况下,使用 MSE:||input_label - cosine_sim(u, v)||_2
cos_score_transformation – cos_score_transformation 函数应用于余弦相似度之上。默认情况下,使用恒等函数(即,不更改)。
参考文献
- 要求
句子对及其对应的相似度得分,范围为 [0, 1]
- 输入
文本
标签
(句子 A,句子 B)对
浮点型相似度得分
- 关系
CoSENTLoss
似乎比 CosineSimilarityLoss 产生更强的训练信号。在我们的实验中,建议使用 CoSENTLoss。AnglELoss
是CoSENTLoss
的变体,它使用pairwise_angle_sim
作为度量指标,而不是pairwise_cos_sim
。它也比 CosineSimilarityLoss 产生更强的训练信号。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.CosineSimilarityLoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
DenoisingAutoEncoderLoss
- class sentence_transformers.losses.DenoisingAutoEncoderLoss(model: SentenceTransformer, decoder_name_or_path: str | None = None, tie_encoder_decoder: bool = True)[source]
此损失函数期望输入为成对的损坏句子和对应的原始句子。在训练期间,解码器从编码后的句子嵌入中重建原始句子。 此处,参数 'decoder_name_or_path' 指示用作解码器的预训练模型(Hugging Face 支持)。 由于包含解码过程,因此解码器应具有名为 XXXLMHead 的类(在 Hugging Face 的 Transformers 上下文中)。 'tie_encoder_decoder' 标志指示是否绑定编码器和解码器的可训练参数,这已被证明有利于模型性能,同时限制了所需的内存量。 只有当编码器和解码器来自相同的架构时,标志 'tie_encoder_decoder' 才能工作。
数据生成过程(即“损坏”过程)已在
DenoisingAutoEncoderDataset
中实现,允许您仅提供常规句子。- 参数:
model (SentenceTransformer) – SentenceTransformer 模型。
decoder_name_or_path (str, optional) – 用于初始化解码器的模型名称或路径(与 Hugging Face 的 Transformers 兼容)。默认为 None。
tie_encoder_decoder (bool) – 是否绑定编码器和解码器的可训练参数。默认为 True。
参考文献
- 要求
解码器应具有名为 XXXLMHead 的类(在 Hugging Face 的 Transformers 上下文中)
应使用大型语料库
- 输入
文本
标签
(损坏的句子,原始句子)对
无
通过
DenoisingAutoEncoderDataset
馈送的句子无
示例
from sentence_transformers import SentenceTransformer, losses from sentence_transformers.datasets import DenoisingAutoEncoderDataset from torch.utils.data import DataLoader model_name = "bert-base-cased" model = SentenceTransformer(model_name) train_sentences = [ "First training sentence", "Second training sentence", "Third training sentence", "Fourth training sentence", ] batch_size = 2 train_dataset = DenoisingAutoEncoderDataset(train_sentences) train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, drop_last=True) train_loss = losses.DenoisingAutoEncoderLoss( model, decoder_name_or_path=model_name, tie_encoder_decoder=True ) model.fit( train_objectives=[(train_dataloader, train_loss)], epochs=10, )
GISTEmbedLoss
- class sentence_transformers.losses.GISTEmbedLoss(model: SentenceTransformer, guide: SentenceTransformer, temperature: float = 0.01, margin_strategy: Literal['absolute', 'relative'] = 'absolute', margin: float = 0.0)[source]
此损失函数用于使用 GISTEmbed 算法训练 SentenceTransformer 模型。 它以模型和引导模型作为输入,并使用引导模型来指导批内负样本选择。 余弦相似度用于计算损失,温度参数用于缩放余弦相似度。
您可以应用不同的假阴性过滤策略来丢弃与正样本过于相似的硬负样本。 支持两种策略
“absolute”:丢弃相似度得分大于或等于
positive_score - margin
的负样本。“relative”:丢弃相似度得分大于或等于
positive_score * (1 - margin)
的负样本。
- 参数:
model – 基于 transformers 模型的 SentenceTransformer 模型。
guide – 用于指导批内负样本选择的 SentenceTransformer 模型。
temperature – 用于缩放余弦相似度的温度参数。
margin_strategy – 用于假阴性过滤的策略。为 {“absolute”, “relative”} 之一。
margin – 用于过滤负样本的 margin 值。 默认为 0.0,与 “absolute” 策略一起使用时,这仅删除比正样本更类似于查询的负样本。
参考文献
更多详情,请参阅: https://arxiv.org/abs/2402.16829
- 要求
(锚点,正样本,负样本)三元组
(锚点,正样本)对
- 输入
文本
标签
(锚点,正样本,负样本)三元组
无
(锚点,正样本)对
无
- 建议
使用
BatchSamplers.NO_DUPLICATES
(docs
) 以确保批内负样本不是锚点或正样本的重复项。
- 关系
MultipleNegativesRankingLoss
与此损失函数类似,但它不使用引导模型来指导批内负样本选择。 GISTEmbedLoss 以一些训练开销为代价,产生了更强的训练信号。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") guide = SentenceTransformer("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."], }) loss = losses.GISTEmbedLoss(model, guide) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
CachedGISTEmbedLoss
- class sentence_transformers.losses.CachedGISTEmbedLoss(model: SentenceTransformer, guide: SentenceTransformer, temperature: float = 0.01, mini_batch_size: int = 32, show_progress_bar: bool = False, margin_strategy: Literal['absolute', 'relative'] = 'absolute', margin: float = 0.0)[source]
此损失函数是
GISTEmbedLoss
和CachedMultipleNegativesRankingLoss
的组合。 通常,MultipleNegativesRankingLoss
需要更大的批次大小才能获得更好的性能。GISTEmbedLoss
由于使用了引导模型进行批内负样本选择,因此比MultipleNegativesRankingLoss
产生更强的训练信号。 同时,CachedMultipleNegativesRankingLoss
允许通过将计算分为嵌入和损失计算两个阶段来扩展批次大小,这两个阶段都可以通过小批量进行缩放(https://arxiv.org/pdf/2101.06983.pdf)。通过结合来自
GISTEmbedLoss
的引导选择和来自CachedMultipleNegativesRankingLoss
的梯度缓存,可以在减少内存使用量的同时,保持与GISTEmbedLoss
相当的性能水平。您可以应用不同的假阴性过滤策略来丢弃与正样本过于相似的硬负样本。 支持两种策略
“absolute”:丢弃相似度得分大于或等于
positive_score - margin
的负样本。“relative”:丢弃相似度得分大于或等于
positive_score * (1 - margin)
的负样本。
- 参数:
model – SentenceTransformer 模型
guide – 用于指导批内负样本选择的 SentenceTransformer 模型。
temperature – 用于缩放余弦相似度的温度参数。
mini_batch_size – 前向传递的小批量大小,这表示训练和评估期间实际使用的内存量。 小批量大小越大,训练的内存效率越高,但训练速度会越慢。 建议将其设置为 GPU 内存允许的最大值。 默认值为 32。
show_progress_bar – 如果为 True,则在训练期间显示小批量的进度条。 默认为 False。
margin_strategy – 用于假阴性过滤的策略。为 {“absolute”, “relative”} 之一。
margin – 用于过滤负样本的 margin 值。 默认为 0.0,与 “absolute” 策略一起使用时,这仅删除比正样本更类似于查询的负样本。
参考文献
智能回复的高效自然语言回复建议,第 4.4 节: https://arxiv.org/pdf/1705.00652.pdf
内存受限设置下深度对比学习批次大小的缩放: https://arxiv.org/pdf/2101.06983.pdf
GISTEmbed:用于文本嵌入微调的训练负样本的引导式样本内选择 https://arxiv.org/abs/2402.16829
- 要求
(锚点,正样本)对 或 (锚点,正样本,负样本对)
应与大批次大小一起使用以获得卓越的性能,但训练时间比
MultipleNegativesRankingLoss
慢
- 输入
文本
标签
(锚点,正样本)对
无
(锚点,正样本,负样本)三元组
无
(锚点,正样本,负样本_1,…,负样本_n)
无
- 建议
使用
BatchSamplers.NO_DUPLICATES
(docs
) 以确保批内负样本不是锚点或正样本的重复项。
- 关系
等效于
GISTEmbedLoss
,但具有允许更大批次大小的缓存
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") guide = SentenceTransformer("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."], }) loss = losses.CachedGISTEmbedLoss( model, guide, mini_batch_size=64, margin_strategy="absolute", # or "relative" (e.g., margin=0.05 for max. 95% of positive similarity) margin=0.1 ) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
MSELoss
- class sentence_transformers.losses.MSELoss(model: SentenceTransformer)[source]
计算计算出的句子嵌入和目标句子嵌入之间的 MSE 损失。当将句子嵌入扩展到新语言时,使用此损失,如我们的出版物“使用知识蒸馏使单语句子嵌入多语言化”中所述。
有关示例,请参阅 关于将语言模型扩展到新语言的蒸馏文档。
- 参数:
model – SentenceTransformerModel
参考文献
使用知识蒸馏使单语句子嵌入多语言化: https://arxiv.org/abs/2004.09813
- 要求
通常在知识蒸馏设置中使用微调的教师模型 M
- 输入
文本
标签
句子
模型句子嵌入
句子_1,句子_2,…,句子_N
模型句子嵌入
- 关系
MarginMSELoss
等效于此损失,但通过负样本对具有 margin。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset student_model = SentenceTransformer("microsoft/mpnet-base") teacher_model = SentenceTransformer("all-mpnet-base-v2") 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"]) } train_dataset = train_dataset.map(compute_labels, batched=True) loss = losses.MSELoss(student_model) trainer = SentenceTransformerTrainer( model=student_model, train_dataset=train_dataset, loss=loss, ) trainer.train()
MarginMSELoss
- class sentence_transformers.losses.MarginMSELoss(model: SentenceTransformer, 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 通常是来自教师模型的相似度得分。与
MultipleNegativesRankingLoss
相比,两个段落不必严格地为正样本和负样本,两者都可能与给定查询相关或不相关。 这可能是 MarginMSELoss 相对于 MultipleNegativesRankingLoss 的一个优势,但请注意,MarginMSELoss 的训练速度要慢得多。 使用 MultipleNegativesRankingLoss,批次大小为 64 时,我们将一个查询与 128 个段落进行比较。 使用 MarginMSELoss,我们仅将一个查询与两个段落进行比较。- 参数:
model – SentenceTransformerModel
similarity_fct – 要使用的相似度函数。
参考文献
有关更多详细信息,请参阅 https://arxiv.org/abs/2010.02666。
- 要求
(查询,段落一,段落二)三元组
通常在知识蒸馏设置中使用微调的教师模型 M
- 输入
文本
标签
(查询,段落一,段落二)三元组
M(查询,段落一) - M(查询,段落二)
- 关系
MSELoss
与此损失函数类似,但没有通过负样本对的 margin。
示例
使用黄金标签,例如,如果您有句子的硬性得分。 想象一下,您希望模型将具有相似“质量”的句子嵌入到彼此附近。 如果 “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 sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.MarginMSELoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
我们还可以使用教师模型来计算相似度得分。 在这种情况下,我们可以使用教师模型来计算相似度得分,并将其用作银标签。 这通常用于知识蒸馏。
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset student_model = SentenceTransformer("microsoft/mpnet-base") teacher_model = SentenceTransformer("all-mpnet-base-v2") 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) # In this example, the labels become -0.036 and 0.68, respectively loss = losses.MarginMSELoss(student_model) trainer = SentenceTransformerTrainer( model=student_model, train_dataset=train_dataset, loss=loss, ) trainer.train()
MatryoshkaLoss
- class sentence_transformers.losses.MatryoshkaLoss(model: SentenceTransformer, loss: nn.Module, matryoshka_dims: list[int], matryoshka_weights: list[float | int] | None = None, n_dims_per_step: int = -1)[source]
MatryoshkaLoss 可以被视为一种损失修饰符,允许您在各种不同的嵌入维度上使用其他损失函数。当您想要训练一个模型,让用户可以选择降低嵌入维度以提高其嵌入比较速度和成本时,这非常有用。
这种损失也与 Cached… 损失兼容,后者是批内负例损失,允许更大的批大小。更大的批大小允许更多的负例,并且通常会产生更强大的模型。
- 参数:
model – SentenceTransformer 模型
loss – 要使用的损失函数,例如
MultipleNegativesRankingLoss
、CoSENTLoss
等。matryoshka_dims – 用于损失函数的嵌入维度列表,例如 [768, 512, 256, 128, 64]。
matryoshka_weights – 用于损失函数的权重列表,例如 [1, 1, 1, 1, 1]。如果为 None,则所有维度的权重都将设置为 1。
n_dims_per_step – 每步使用的维度数。如果为 -1,则使用所有维度。如果 > 0,则每步使用 n_dims_per_step 个维度的随机样本。默认值为 -1。
参考文献
这个概念是在这篇论文中提出的: https://arxiv.org/abs/2205.13147
- 输入
文本
标签
any
any
- 关系
Matryoshka2dLoss
将此损失与AdaptiveLayerLoss
结合使用,后者允许减少层数以加快推理速度。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.MultipleNegativesRankingLoss(model) loss = losses.MatryoshkaLoss(model, loss, [768, 512, 256, 128, 64]) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
Matryoshka2dLoss
- class sentence_transformers.losses.Matryoshka2dLoss(model: SentenceTransformer, loss: Module, matryoshka_dims: list[int], matryoshka_weights: list[float | int] | None = None, n_layers_per_step: int = 1, n_dims_per_step: int = 1, last_layer_weight: float = 1.0, prior_layers_weight: float = 1.0, kl_div_weight: float = 1.0, kl_temperature: float = 0.3)[source]
Matryoshka2dLoss 可以被视为一种损失修饰符,它结合了
AdaptiveLayerLoss
和MatryoshkaLoss
。这允许您训练一个嵌入模型,该模型 1) 允许用户指定要使用的模型层数,以及 2) 允许用户指定要使用的输出维度。前者在您希望用户可以选择降低使用的层数以提高其推理速度和内存使用率时非常有用,而后者在您希望用户可以选择降低输出维度以提高其下游任务(例如检索)效率或降低其存储成本时非常有用。
请注意,此方法默认使用 n_layers_per_step=1 和 n_dims_per_step=1,遵循原始的 2DMSE 实现。
- 参数:
model – SentenceTransformer 模型
loss – 要使用的损失函数,例如
MultipleNegativesRankingLoss
、CoSENTLoss
等。matryoshka_dims – 用于损失函数的嵌入维度列表,例如 [768, 512, 256, 128, 64]。
matryoshka_weights – 用于损失函数的权重列表,例如 [1, 1, 1, 1, 1]。如果为 None,则所有维度的权重都将设置为 1。
n_layers_per_step – 每步使用的层数。如果为 -1,则使用所有层。如果 > 0,则每步使用 n_layers_per_step 层的随机样本。2DMSE 论文使用 n_layers_per_step=1。默认值为 -1。
n_dims_per_step – 每步使用的维度数。如果为 -1,则使用所有维度。如果 > 0,则每步使用 n_dims_per_step 个维度的随机样本。默认值为 -1。
last_layer_weight – 用于最后一层损失的权重。增加此值以更关注使用所有层时的性能。默认值为 1.0。
prior_layers_weight – 用于先前层损失的权重。增加此值以更关注使用较少层时的性能。默认值为 1.0。
kl_div_weight – 用于 KL 散度损失的权重,该损失用于使先前层与最后一层匹配。增加此值以更关注使用较少层时的性能。默认值为 1.0。
kl_temperature – 用于 KL 散度损失的温度。如果为 0,则不使用 KL 散度损失。默认值为 1.0。
参考文献
请参阅 2D Matryoshka Sentence Embeddings (2DMSE) 论文: https://arxiv.org/abs/2402.14776
- 要求
- 输入
文本
标签
any
any
- 关系
MatryoshkaLoss
在此损失中使用,它负责降维。AdaptiveLayerLoss
在此损失中使用,它负责减少层数。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.MultipleNegativesRankingLoss(model) loss = losses.Matryoshka2dLoss(model, loss, [768, 512, 256, 128, 64]) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
AdaptiveLayerLoss
- class sentence_transformers.losses.AdaptiveLayerLoss(model: SentenceTransformer, loss: nn.Module, n_layers_per_step: int = 1, last_layer_weight: float = 1.0, prior_layers_weight: float = 1.0, kl_div_weight: float = 1.0, kl_temperature: float = 0.3)[source]
AdaptiveLayerLoss 可以被视为一种损失修饰符,允许您在 Sentence Transformer 模型的非最终层使用其他损失函数。当您想要训练一个模型,让用户可以选择降低使用的层数以提高其推理速度和内存使用率时,这非常有用。
- 参数:
model – SentenceTransformer 模型
loss – 要使用的损失函数,例如
MultipleNegativesRankingLoss
、CoSENTLoss
等。n_layers_per_step – 每步使用的层数。如果为 -1,则使用所有层。如果 > 0,则每步使用 n_layers_per_step 层的随机样本,与始终使用的最后一层分开。2DMSE 论文使用 n_layers_per_step=1。默认值为 1。
last_layer_weight – 用于最后一层损失的权重。增加此值以更关注使用所有层时的性能。默认值为 1.0。
prior_layers_weight – 用于先前层损失的权重。增加此值以更关注使用较少层时的性能。默认值为 1.0。
kl_div_weight – 用于 KL 散度损失的权重,该损失用于使先前层与最后一层匹配。增加此值以更关注使用较少层时的性能。默认值为 1.0。
kl_temperature – 用于 KL 散度损失的温度。如果为 0,则不使用 KL 散度损失。默认值为 1.0。
参考文献
这个概念的灵感来自 2DMSE 论文: https://arxiv.org/abs/2402.14776
- 要求
- 输入
文本
标签
any
any
- 关系
Matryoshka2dLoss
将此损失与MatryoshkaLoss
结合使用,后者允许降低输出维度以加快下游任务(例如检索)。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.MultipleNegativesRankingLoss(model=model) loss = losses.AdaptiveLayerLoss(model, loss) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
MegaBatchMarginLoss
- class sentence_transformers.losses.MegaBatchMarginLoss(model: SentenceTransformer, positive_margin: float = 0.8, negative_margin: float = 0.3, use_mini_batched_version: bool = True, mini_batch_size: int = 50)[source]
给定一个大型批次(例如 500 个或更多示例)的 (anchor_i, positive_i) 对,对于批次中的每对,找到最难的负例,即找到 j != i,使得 cos_sim(anchor_i, positive_j) 最大。然后由此创建一个三元组 (anchor_i, positive_i, positive_j),其中 positive_j 用作此三元组的负例。
然后像三元组损失一样进行训练。
- 参数:
model – SentenceTransformerModel
positive_margin – 正例边距,cos(anchor, positive) 应 > positive_margin
negative_margin – 负例边距,cos(anchor, negative) 应 < negative_margin
use_mini_batched_version – 由于大批次大小需要大量内存,我们可以使用小批量版本。我们将大批次分解为示例较少的小批次。
mini_batch_size – 小批量大小。应为数据加载器中批次大小的除数。
参考文献
此损失函数的灵感来自 ParaNMT 论文: https://www.aclweb.org/anthology/P18-1042/
- 要求
(锚点,正样本)对
大型批次(500 个或更多示例)
- 输入
文本
标签
(锚点,正样本)对
无
- 建议
使用
BatchSamplers.NO_DUPLICATES
(docs
) 以确保批内负样本不是锚点或正样本的重复项。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainingArguments, SentenceTransformerTrainer, losses from datasets import Dataset train_batch_size = 250 train_mini_batch_size = 32 model = SentenceTransformer('all-MiniLM-L6-v2') train_dataset = Dataset.from_dict({ "anchor": [f"This is sentence number {i}" for i in range(500)], "positive": [f"This is sentence number {i}" for i in range(1, 501)], }) loss = losses.MegaBatchMarginLoss(model=model, mini_batch_size=train_mini_batch_size) args = SentenceTransformerTrainingArguments( output_dir="output", per_device_train_batch_size=train_batch_size, ) trainer = SentenceTransformerTrainer( model=model, args=args, train_dataset=train_dataset, loss=loss, ) trainer.train()
MultipleNegativesRankingLoss
MultipleNegativesRankingLoss 是一个很棒的损失函数,如果您只有正例对,例如,只有相似文本对,如释义对、重复问题对、(query, response) 对或 (source_language, target_language) 对。
- class sentence_transformers.losses.MultipleNegativesRankingLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, scale: float = 20.0, similarity_fct=<function cos_sim>)[source]
给定 (anchor, positive) 对或 (anchor, positive, negative) 三元组列表,此损失优化以下内容
- 给定一个 anchor(例如一个问题),将最高相似度分配给批次中每个正例和负例(例如所有答案)中对应的正例(即答案)。
从批次中的每个正例和负例(例如所有答案)中,为对应的正例(即答案)分配最高的相似度。
如果您提供可选的负例,它们都将用作额外选项,模型必须从中选择正确的正例。在合理的范围内,这种“选择”越难,模型就会变得越强大。因此,较高的批次大小会导致更多的批内负例,从而提高性能(达到一定程度)。
此损失函数非常适合训练检索设置的嵌入,在检索设置中,您具有正例对(例如(query, answer)),因为它将在每个批次中随机抽样
n-1
个负例文档。这种损失也称为 InfoNCE 损失、SimCSE 损失、具有批内负例的交叉熵损失,或简称为批内负例损失。
- 参数:
model – SentenceTransformer 模型
scale – 相似度函数的输出乘以 scale 值
similarity_fct – 句子嵌入之间的相似度函数。 默认情况下为 cos_sim。 也可以设置为点积(然后将 scale 设置为 1)
参考文献
智能回复的高效自然语言回复建议,第 4.4 节: https://arxiv.org/pdf/1705.00652.pdf
- 要求
(anchor, positive) 对或 (anchor, positive, negative) 三元组
- 输入
文本
标签
(锚点,正样本)对
无
(锚点,正样本,负样本)三元组
无
(锚点,正样本,负样本_1,…,负样本_n)
无
- 建议
使用
BatchSamplers.NO_DUPLICATES
(docs
) 以确保批内负样本不是锚点或正样本的重复项。
- 关系
CachedMultipleNegativesRankingLoss
等效于此损失,但它使用缓存,允许更大的批次大小(从而获得更好的性能),而无需额外的内存使用。但是,它稍微慢一些。MultipleNegativesSymmetricRankingLoss
等效于此损失,但具有额外的损失项。GISTEmbedLoss
等效于此损失,但使用引导模型来指导批内负例样本选择。GISTEmbedLoss 以一定的训练开销为代价,产生更强的训练信号。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.MultipleNegativesRankingLoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
CachedMultipleNegativesRankingLoss
- class sentence_transformers.losses.CachedMultipleNegativesRankingLoss(model: SentenceTransformer, scale: float = 20.0, similarity_fct: callable[[Tensor, Tensor], Tensor] = <function cos_sim>, mini_batch_size: int = 32, show_progress_bar: bool = False)[source]
MultipleNegativesRankingLoss 的增强版本(https://arxiv.org/pdf/1705.00652.pdf),通过 GradCache (https://arxiv.org/pdf/2101.06983.pdf)。
使用批内负例的对比学习(此处为我们的 MNRL 损失)通常难以处理大批次大小,因为(GPU)内存限制。即使使用梯度缩放等批次缩放方法,也无法工作。这是因为批内负例使同一批次内的数据点非独立,因此批次无法分解为小批次。GradCache 是一种解决此问题的巧妙方法。它通过将计算分为嵌入和损失计算两个阶段来实现目标,这两个阶段都可以通过小批次进行缩放。因此,恒定大小的内存(例如,适用于批次大小 = 32 的内存)现在可以处理更大的批次(例如 65536)。
详细信息
它首先执行快速嵌入步骤,无需梯度/计算图即可获得所有嵌入;
计算损失,反向传播到嵌入,并缓存关于嵌入的梯度;
第 2 个嵌入步骤,带有梯度/计算图,并将缓存的梯度连接到反向链中。
注意:所有步骤均使用小批次完成。在 GradCache 的原始实现中,(2) 不是以小批次完成的,当批次大小较大时,需要大量内存。一个缺点是速度。根据论文,梯度缓存会牺牲大约 20% 的计算时间。
- 参数:
model – SentenceTransformer 模型
scale – 相似度函数的输出乘以 scale 值
similarity_fct – 句子嵌入之间的相似度函数。 默认情况下为 cos_sim。 也可以设置为点积(然后将 scale 设置为 1)
mini_batch_size – 前向传递的小批量大小,这表示训练和评估期间实际使用的内存量。 小批量大小越大,训练的内存效率越高,但训练速度会越慢。 建议将其设置为 GPU 内存允许的最大值。 默认值为 32。
show_progress_bar – 如果为 True,则在训练期间显示小批量的进度条。 默认为 False。
参考文献
智能回复的高效自然语言回复建议,第 4.4 节: https://arxiv.org/pdf/1705.00652.pdf
内存受限设置下深度对比学习批次大小的缩放: https://arxiv.org/pdf/2101.06983.pdf
- 要求
(锚点,正样本)对 或 (锚点,正样本,负样本对)
应与较大的 per_device_train_batch_size 和较小的 mini_batch_size 一起使用,以获得卓越的性能,但训练时间比
MultipleNegativesRankingLoss
慢。
- 输入
文本
标签
(锚点,正样本)对
无
(锚点,正样本,负样本)三元组
无
(锚点,正样本,负样本_1,…,负样本_n)
无
- 建议
使用
BatchSamplers.NO_DUPLICATES
(docs
) 以确保批内负样本不是锚点或正样本的重复项。
- 关系
等效于
MultipleNegativesRankingLoss
,但具有缓存,允许更大的批次大小(从而获得更好的性能),而无需额外的内存使用。此损失的训练速度也比MultipleNegativesRankingLoss
慢大约 2 倍到 2.4 倍。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.CachedMultipleNegativesRankingLoss(model, mini_batch_size=64) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
MultipleNegativesSymmetricRankingLoss
- class sentence_transformers.losses.MultipleNegativesSymmetricRankingLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, scale: float = 20.0, similarity_fct=<function cos_sim>)[source]
给定 (anchor, positive) 对列表,此损失将以下两个损失相加
前向损失:给定一个 anchor,在批次中的所有正例中找到相似度最高的样本。这等效于
MultipleNegativesRankingLoss
。后向损失:给定一个正例,在批次中的所有 anchor 中找到相似度最高的样本。
例如,对于问答对,
MultipleNegativesRankingLoss
仅计算在给定问题的情况下查找答案的损失,但MultipleNegativesSymmetricRankingLoss
还会额外计算在给定答案的情况下查找问题的损失。注意:如果您传递三元组,则会忽略负例条目。仅搜索正例的 anchor。
- 参数:
model – SentenceTransformer 模型
scale – 相似度函数的输出乘以 scale 值
similarity_fct – 句子嵌入之间的相似度函数。 默认情况下为 cos_sim。 也可以设置为点积(然后将 scale 设置为 1)
- 要求
(锚点,正样本)对
- 输入
文本
标签
(锚点,正样本)对
无
- 建议
使用
BatchSamplers.NO_DUPLICATES
(docs
) 以确保批内负样本不是锚点或正样本的重复项。
- 关系
类似于
MultipleNegativesRankingLoss
,但具有额外的损失项。CachedMultipleNegativesSymmetricRankingLoss
等效于此损失,但它使用缓存,允许更大的批次大小(从而获得更好的性能),而无需额外的内存使用。但是,它稍微慢一些。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.MultipleNegativesSymmetricRankingLoss(model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
CachedMultipleNegativesSymmetricRankingLoss
- class sentence_transformers.losses.CachedMultipleNegativesSymmetricRankingLoss(model: SentenceTransformer, scale: float = 20.0, similarity_fct: callable[[Tensor, Tensor], Tensor] = <function cos_sim>, mini_batch_size: int = 32, show_progress_bar: bool = False)[source]
MultipleNegativesSymmetricRankingLoss
(MNSRL) 的增强版本,通过 GradCache (https://arxiv.org/pdf/2101.06983.pdf)。给定 (anchor, positive) 对列表,MNSRL 将以下两个损失相加
前向损失:给定一个 anchor,在批次中的所有正例中找到相似度最高的样本。
后向损失:给定一个正例,在批次中的所有 anchor 中找到相似度最高的样本。
例如,对于问答对,前向损失查找给定问题的答案,后向损失查找给定答案的问题。这种损失在对称任务中很常见,例如语义文本相似度。
缓存修改允许使用大批次大小(提供更好的训练信号),并具有恒定的内存使用量,从而使您可以使用常规硬件达到最佳训练信号。
注意:如果您传递三元组,则会忽略负例条目。仅搜索正例的 anchor。
- 参数:
model – SentenceTransformer 模型
scale – 相似度函数的输出乘以 scale 值
similarity_fct – 句子嵌入之间的相似度函数。 默认情况下为 cos_sim。 也可以设置为点积(然后将 scale 设置为 1)
mini_batch_size – 前向传递的小批量大小,这表示训练和评估期间实际使用的内存量。小批量大小越大,训练的内存效率越高,但训练速度越慢。
show_progress_bar – 如果为 True,则在处理期间显示进度条
- 要求
(锚点,正样本)对
应与大批次大小一起使用以获得卓越的性能,但训练时间比非缓存版本慢
- 输入
文本
标签
(锚点,正样本)对
无
- 建议
使用
BatchSamplers.NO_DUPLICATES
(docs
) 以确保批内负样本不是锚点或正样本的重复项。
- 关系
类似于
MultipleNegativesRankingLoss
,但具有额外的对称损失项和缓存机制。灵感来自
CachedMultipleNegativesRankingLoss
,适用于对称损失计算。
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.CachedMultipleNegativesSymmetricRankingLoss(model, mini_batch_size=32) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
参考文献
智能回复的高效自然语言回复建议,第 4.4 节: https://arxiv.org/pdf/1705.00652.pdf
内存受限设置下深度对比学习批次大小的缩放: https://arxiv.org/pdf/2101.06983.pdf
SoftmaxLoss
- class sentence_transformers.losses.SoftmaxLoss(model: SentenceTransformer, sentence_embedding_dimension: int, num_labels: int, concatenation_sent_rep: bool = True, concatenation_sent_difference: bool = True, concatenation_sent_multiplication: bool = False, loss_fct: Callable = CrossEntropyLoss())[source]
此损失在我们的 SBERT 出版物 (https://arxiv.org/abs/1908.10084) 中用于在 NLI 数据上训练 SentenceTransformer 模型。它在两个 Transformer 网络的输出之上添加了一个 softmax 分类器。
MultipleNegativesRankingLoss
是另一种损失函数,通常会产生更好的结果,如 https://arxiv.org/abs/2004.09813 所示。- 参数:
model (SentenceTransformer) – SentenceTransformer 模型。
sentence_embedding_dimension (int) – 句子嵌入的维度。
num_labels (int) – 不同标签的数量。
concatenation_sent_rep (bool) – 是否为 softmax 分类器连接向量 u,v。默认为 True。
concatenation_sent_difference (bool) – 是否为 softmax 分类器添加 abs(u-v)。默认为 True。
concatenation_sent_multiplication (bool) – 是否为 softmax 分类器添加 u*v。默认为 False。
loss_fct (Callable) – 自定义 pytorch 损失函数。如果未设置,则使用 nn.CrossEntropyLoss()。默认为 nn.CrossEntropyLoss()。
参考文献
Sentence-BERT:使用 Siamese BERT 网络的句子嵌入:https://arxiv.org/abs/1908.10084
- 要求
带有类别标签的句子对
- 输入
文本
标签
(句子 A,句子 B)对
类别
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") train_dataset = Dataset.from_dict({ "sentence1": [ "A person on a horse jumps over a broken down airplane.", "A person on a horse jumps over a broken down airplane.", "A person on a horse jumps over a broken down airplane.", "Children smiling and waving at camera", ], "sentence2": [ "A person is training his horse for a competition.", "A person is at a diner, ordering an omelette.", "A person is outdoors, on a horse.", "There are children present.", ], "label": [1, 2, 0, 0], }) loss = losses.SoftmaxLoss(model, model.get_sentence_embedding_dimension(), num_labels=3) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
TripletLoss
- class sentence_transformers.losses.TripletLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, distance_metric=<function TripletDistanceMetric.<lambda>>, triplet_margin: float = 5)[source]
此类实现了 triplet loss。给定一个 (anchor, positive, negative) 三元组,该损失函数旨在最小化 anchor 和 positive 之间的距离,同时最大化 anchor 和 negative 之间的距离。它计算以下损失函数
loss = max(||anchor - positive|| - ||anchor - negative|| + margin, 0)
.Margin 是一个重要的超参数,需要分别进行调整。
- 参数:
model – SentenceTransformerModel
distance_metric – 用于计算两个嵌入之间距离的函数。TripletDistanceMetric 类包含可以使用的常用距离度量。
triplet_margin – negative 应该比 positive 至少远离 anchor 这么多距离。
参考文献
有关更多详细信息,请参阅:https://en.wikipedia.org/wiki/Triplet_loss
- 要求
(锚点,正样本,负样本)三元组
- 输入
文本
标签
(锚点,正样本,负样本)三元组
无
示例
from sentence_transformers import SentenceTransformer, SentenceTransformerTrainer, losses from datasets import Dataset model = SentenceTransformer("microsoft/mpnet-base") 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.TripletLoss(model=model) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()