损失¶
sentence_transformers.losses 定义了不同的损失函数,这些函数可以用于在训练数据上微调嵌入模型。在微调模型时,损失函数的选择起着关键作用。它决定了我们的嵌入模型在特定下游任务中的表现。
遗憾的是,没有一种“一刀切”的损失函数。哪种损失函数合适取决于可用的训练数据和目标任务。建议查看损失概览,以帮助缩小损失函数的选择范围。
BatchAllTripletLoss¶
- class sentence_transformers.losses.BatchAllTripletLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, distance_metric=<function BatchHardTripletLossDistanceFunction.eucledian_distance>, margin: float = 5)[源代码][源代码]¶
BatchAllTripletLoss 接受一个包含 (句子, 标签) 对的批次,并计算所有可能的、有效的三元组的损失,即锚点和正样本必须具有相同的标签,锚点和负样本具有不同的标签。标签必须是整数,相同标签表示来自同一类的句子。您的训练数据集必须至少包含每个标签类别的两个示例。
- 参数:
model -- SentenceTransformer 模型
distance_metric -- 返回两个嵌入之间距离的函数。类 SiameseDistanceMetric 包含可以使用的预定义度量。
margin -- 负样本应至少比正样本离锚点远一个边距。
引用
源代码: https://github.com/NegatioN/OnlineMiningTripletLoss/blob/master/online_triplet_loss/losses.py
论文: 《为行人重识别辩护的三重损失》,https://arxiv.org/abs/1703.07737
博客文章: https://omoindrot.github.io/triplet-loss
- 要求:
每句话必须带有类别标签。
您的数据集每个标签类别至少需要包含2个示例。
- 输入:
文本
标签
单句
类
- 推荐:
使用
BatchSamplers.GROUP_BY_LABEL
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保每个批次包含每个标签类别的2个以上示例。
- 关系:
:class:
BatchHardTripletLoss
仅使用最难的正样本和负样本,而不是所有可能的有效三元组。:class:
BatchHardSoftMarginTripletLoss
仅使用最难的正样本和负样本,而不是所有可能的有效三元组。此外,它不需要设置边界。:class:
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>)[源代码][源代码]¶
BatchHardSoftMarginTripletLoss 接受一个包含 (句子, 标签) 对的批次,并计算所有可能的有效三元组的损失,即锚点和正样本必须具有相同的标签,锚点和负样本具有不同的标签。标签必须是整数,相同标签表示来自同一类的句子。您的训练数据集必须至少包含每个标签类别的 2 个示例。这种软边距变体不需要设置边距。
- 参数:
model -- SentenceTransformer 模型
distance_metric -- 返回两个嵌入之间距离的函数。类 SiameseDistanceMetric 包含可以使用的预定义度量。
- 定义:
- 简单的三元组:
因为
distance(anchor, positive) + margin < distance(anchor, negative)
而损失为0的三元组。- 困难三元组:
负样本比正样本更接近锚点的三元组,即
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
论文: 《为行人重识别辩护的三重损失》,https://arxiv.org/abs/1703.07737
博客文章: https://omoindrot.github.io/triplet-loss
- 要求:
每句话必须带有类别标签。
您的数据集每个标签类别至少需要包含2个示例。
你的数据集应包含硬正例和硬负例。
- 输入:
文本
标签
单句
类
- 推荐:
使用
BatchSamplers.GROUP_BY_LABEL
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保每个批次包含每个标签类别的2个以上示例。
- 关系:
:class:
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)[源代码][源代码]¶
BatchHardTripletLoss 接受一个包含 (句子, 标签) 对的批次,并计算所有可能的有效三元组的损失,即锚点和正样本必须具有相同的标签,锚点和负样本具有不同的标签。然后它会寻找最难的正样本和最难的负样本。标签必须是整数,相同标签表示来自同一类的句子。您的训练数据集必须至少包含每个标签类别的2个示例。
- 参数:
model -- SentenceTransformer 模型
distance_metric -- 返回两个嵌入之间距离的函数。类 SiameseDistanceMetric 包含可以使用的预定义度量。
margin -- 负样本应至少比正样本离锚点远一个边距。
- 定义:
- 简单的三元组:
因为
distance(anchor, positive) + margin < distance(anchor, negative)
而损失为0的三元组。- 困难三元组:
负样本比正样本更接近锚点的三元组,即
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
论文: 《为行人重识别辩护的三重损失》,https://arxiv.org/abs/1703.07737
博客文章: https://omoindrot.github.io/triplet-loss
- 要求:
每句话必须带有类别标签。
您的数据集每个标签类别至少需要包含2个示例。
你的数据集应包含硬正例和硬负例。
- 输入:
文本
标签
单句
类
- 推荐:
使用
BatchSamplers.GROUP_BY_LABEL
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保每个批次包含每个标签类别的2个以上示例。
- 关系:
:class:
BatchAllTripletLoss
使用所有可能的、有效的三元组,而不是仅使用最难的正样本和负样本。:class:
BatchSemiHardTripletLoss
仅使用半硬三元组,有效的三元组,而不是仅使用最难的正样本和负样本。:class:
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)[源代码][源代码]¶
BatchSemiHardTripletLoss 接受一个包含 (标签, 句子) 对的批次,并计算所有可能的有效三元组的损失,即锚点和正样本必须具有相同的标签,锚点和负样本具有不同的标签。然后它会寻找半硬正样本和负样本。标签必须是整数,相同标签表示来自同一类的句子。您的训练数据集必须至少包含每个标签类别的2个示例。
- 参数:
model -- SentenceTransformer 模型
distance_metric -- 返回两个嵌入之间距离的函数。类 SiameseDistanceMetric 包含可以使用的预定义度量。
margin -- 负样本应至少比正样本离锚点远一个边距。
- 定义:
- 简单的三元组:
因为
distance(anchor, positive) + margin < distance(anchor, negative)
而损失为0的三元组。- 困难三元组:
负样本比正样本更接近锚点的三元组,即
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
论文: 《为行人重识别辩护的三重损失》,https://arxiv.org/abs/1703.07737
博客文章: https://omoindrot.github.io/triplet-loss
- 要求:
每句话必须带有类别标签。
您的数据集每个标签类别至少需要包含2个示例。
你的数据集应包含半硬正样本和负样本。
- 输入:
文本
标签
单句
类
- 推荐:
使用
BatchSamplers.GROUP_BY_LABEL
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保每个批次包含每个标签类别的2个以上示例。
- 关系:
:class:
BatchHardTripletLoss
仅使用最难的正样本和负样本,而不是仅使用半难的正样本和负样本。:class:
BatchAllTripletLoss
使用所有可能的、有效的三元组,而不是仅使用半硬正样本和负样本。:class:
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()
对比损失¶
- class sentence_transformers.losses.ContrastiveLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, distance_metric=<function SiameseDistanceMetric.<lambda>>, margin: float = 0.5, size_average: bool = True)[源代码][源代码]¶
对比损失。期望输入两个文本和一个标签,标签为0或1。如果标签 == 1,则两个嵌入之间的距离减小。如果标签 == 0,则嵌入之间的距离增加。
- 参数:
model -- SentenceTransformer 模型
distance_metric -- 返回两个嵌入之间距离的函数。类 SiameseDistanceMetric 包含可以使用的预定义度量。
margin -- 负样本(标签 == 0)应至少具有边距值的距离。
size_average -- 按小批量的大小进行平均。
引用
更多信息: http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf
训练示例 > Quora 重复问题 <../../examples/training/quora_duplicate_questions/README.html>
_
- 要求:
(锚点, 正/负) 对
- 输入:
文本
标签
(锚点, 正/负) 对
1 如果为正,0 如果为负
- 关系:
:class:
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()
在线对比损失¶
- class sentence_transformers.losses.OnlineContrastiveLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, distance_metric=<function SiameseDistanceMetric.<lambda>>, margin: float = 0.5)[源代码][源代码]¶
这种在线对比损失类似于 :class:
ConstrativeLoss
,但它选择难正样本(相距较远的正样本)和难负样本(相距较近的负样本),并且仅针对这些样本对计算损失。这种损失通常比 ContrastiveLoss 产生更好的性能。- 参数:
model -- SentenceTransformer 模型
distance_metric -- 返回两个嵌入之间距离的函数。类 SiameseDistanceMetric 包含可以使用的预定义度量。
margin -- 负样本(标签 == 0)应至少具有边距值的距离。
引用
训练示例 > Quora 重复问题 <../../examples/training/quora_duplicate_questions/README.html>
_
- 要求:
(锚点, 正/负) 对
数据应包括难正例和难负例
- 输入:
文本
标签
(锚点, 正/负) 对
1 如果为正,0 如果为负
- 关系:
:class:
ContrastiveLoss
类似,但不使用硬正样本和硬负样本对。
:class:
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()
对比张力损失¶
- class sentence_transformers.losses.ContrastiveTensionLoss(model: SentenceTransformer)[源代码][源代码]¶
此损失函数仅期望单句,不带任何标签。正负对通过随机采样自动创建,使得正对由两个相同的句子组成,负对由两个不同的句子组成。创建编码器模型的独立副本,用于编码每对中的第一个句子。原始编码器模型编码第二个句子。使用生成的标签(正对为1,负对为0)通过二元交叉熵目标比较和评分嵌入。
请注意,您必须使用
ContrastiveTensionDataLoader
来实现此损失。ContrastiveTensionDataLoader
的pos_neg_ratio
可以用来确定每个正样本对的负样本对数量。通常,建议使用 :class:
ContrastiveTensionLossInBatchNegatives
而不是此损失,因为它提供了更强的训练信号。- 参数:
model -- SentenceTransformer 模型
引用
基于对比张力的语义重调:https://openreview.net/pdf?id=Ov_sMNau-PF
无监督学习 > CT <../../examples/unsupervised_learning/CT/README.html>
_
- 输入:
文本
标签
单句
无
- 关系:
:class:
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>)[源代码][源代码]¶
此损失仅期望单个句子,不带任何标签。正负对通过随机抽样自动创建,使得正对由两个相同的句子组成,负对由两个不同的句子组成。创建了编码器模型的独立副本,用于编码每对中的第一个句子。原始编码器模型编码第二个句子。与 :class:
ContrastiveTensionLoss
不同,此损失使用批次负采样策略,即负对从批次中采样。使用批次内负采样比原始的 :class:ContrastiveTensionLoss
提供更强的训练信号。性能通常随着批次大小的增加而提高。请注意,对于这种损失,你不应该使用
ContrastiveTensionDataLoader
,而应该使用一个带有InputExample
实例的普通 DataLoader。每个InputExample
实例的两个文本应该是相同的。- 参数:
model -- SentenceTransformer 模型
scale -- 相似度函数的输出乘以比例值
similarity_fct -- 句子嵌入之间的相似度函数。默认情况下,使用余弦相似度(cos_sim)。也可以设置为点积(然后设置比例为1)。
引用
基于对比张力的语义重调:https://openreview.net/pdf?id=Ov_sMNau-PF
无监督学习 > CT (批内负样本) <../../examples/unsupervised_learning/CT_In-Batch_Negatives/README.html>
_
- 关系:
:class:
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>)[源代码][源代码]¶
这个类实现了 CoSENT (Cosine Sentence) 损失。它期望每个 InputExamples 包含一对文本和一个浮点值标签,表示这对文本之间的预期相似度分数。
它计算以下损失函数:
loss = logsum(1+exp(s(k,l)-s(i,j))+exp...)
,其中(i,j)
和(k,l)
是批次中任意输入对,使得(i,j)
的预期相似度大于(k,l)
。求和是对批次中所有满足此条件的输入对进行的。轶事实验表明,这种损失函数比 :class:
CosineSimilarityLoss
产生更强的训练信号,从而导致更快的收敛和性能更优的最终模型。因此,CoSENTLoss 可以作为 :class:CosineSimilarityLoss
在任何训练脚本中的即插即用替代品。- 参数:
model -- SentenceTransformerModel
similarity_fct -- 计算嵌入之间成对相似度的函数。默认是
util.pairwise_cos_sim
。scale -- 相似度函数的输出乘以比例值。表示逆温度。
引用
更多详情,请参阅:https://kexue.fm/archives/8847
- 要求:
具有相应相似度分数的句子对,其范围在相似度函数的范围内。默认值为 [-1,1]。
- 输入:
文本
标签
(sentence_A, sentence_B) 对
浮点相似度分数
- 关系:
:class:
AnglELoss
是使用pairwise_angle_sim
作为度量标准的 CoSENTLoss,而不是pairwise_cos_sim
。:class:
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)[源代码][源代码]¶
这个类实现了 AnglE(角度优化)损失。这是对 :class:
CoSENTLoss
的一种修改,旨在解决以下问题:余弦函数的梯度在波形接近顶部或底部时趋近于 0。这可能会阻碍优化过程,因此 AnglE 提出在复空间中优化角度差异,以减轻这种影响。它期望每个 InputExamples 由一对文本和一个浮点值标签组成,表示这对文本之间的预期相似度得分。
它计算以下损失函数:
loss = logsum(1+exp(s(k,l)-s(i,j))+exp...)
,其中(i,j)
和(k,l)
是批次中任意输入对,使得(i,j)
的期望相似度大于(k,l)
。求和是对批次中所有满足此条件的输入对进行的。这与 CoSENTLoss 相同,只是相似度函数不同。- 参数:
model -- SentenceTransformerModel
scale -- 相似度函数的输出乘以比例值。表示逆温度。
引用
更多详情,请参阅:https://arxiv.org/abs/2309.12871v1
- 要求:
具有相应相似度分数的句子对,其范围在相似度函数的范围内。默认值为 [-1,1]。
- 输入:
文本
标签
(sentence_A, sentence_B) 对
浮点相似度分数
- 关系:
:class:
CoSENTLoss
是 AnglELoss,使用pairwise_cos_sim
作为度量标准,而不是pairwise_angle_sim
。:class:
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()
余弦相似度损失¶
对于每一对句子,我们将句子A和句子B通过我们的网络,得到嵌入向量u和v。这些嵌入向量的相似度使用余弦相似度计算,结果与黄金相似度分数进行比较。
这使得我们的网络能够微调以识别句子的相似性。
- class sentence_transformers.losses.CosineSimilarityLoss(model: SentenceTransformer, loss_fct: Module = MSELoss(), cos_score_transformation: Module = Identity())[源代码][源代码]¶
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 函数应用于 cosine_similarity 之上。默认情况下,使用 identify 函数(即不进行任何更改)。
引用
训练示例 > 语义文本相似性 <../../examples/training/sts/README.html>
_
- 要求:
在范围
[0, 1]
内具有相应相似度分数的句子对
- 输入:
文本
标签
(sentence_A, sentence_B) 对
浮点相似度分数
- 关系:
:class:
CoSENTLoss
似乎比 CosineSimilarityLoss 产生更强的训练信号。在我们的实验中,推荐使用 CoSENTLoss。:class:
AnglELoss
是使用pairwise_angle_sim
作为度量标准的 :class:CoSENTLoss
,而不是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()
去噪自编码器损失¶
- class sentence_transformers.losses.DenoisingAutoEncoderLoss(model: SentenceTransformer, decoder_name_or_path: str | None = None, tie_encoder_decoder: bool = True)[源代码][源代码]¶
此损失函数期望输入为一对损坏的句子和相应的原始句子。在训练过程中,解码器从编码的句子嵌入中重建原始句子。这里的参数 '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。
引用
TSDAE 论文: https://arxiv.org/pdf/2104.06979.pdf
无监督学习 > TSDAE <../../examples/unsupervised_learning/TSDAE/README.html>
_
- 要求:
解码器应有一个名为 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)[源代码][源代码]¶
此损失用于使用 GISTEmbed 算法训练 SentenceTransformer 模型。它接受一个模型和一个引导模型作为输入,并使用引导模型来指导批次内负样本的选择。余弦相似度用于计算损失,温度参数用于缩放余弦相似度。
- 参数:
model -- 基于
transformers
模型的 SentenceTransformer 模型。guide -- SentenceTransformer 模型用于指导批次内负样本的选择。
temperature -- 温度参数用于调整余弦相似度的比例。
引用
更多详情,请参阅:https://arxiv.org/abs/2402.16829
- 要求:
(锚点, 正样本, 负样本) 三元组
(锚点, 正例) 对
- 输入:
文本
标签
(锚点, 正样本, 负样本) 三元组
无
(锚点, 正例) 对
无
- 推荐:
使用
BatchSamplers.NO_DUPLICATES
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保批次内的负样本不是锚点或正样本的重复。
- 关系:
:class:
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)[源代码][源代码]¶
这个损失是 :class:
GISTEmbedLoss
和 :class:CachedMultipleNegativesRankingLoss
的组合。通常,:class:MultipleNegativesRankingLoss
需要更大的批量大小以获得更好的性能。由于使用引导模型进行批内负样本选择,:class:GISTEmbedLoss
比 :class:MultipleNegativesRankingLoss
产生更强的训练信号。同时,:class:CachedMultipleNegativesRankingLoss
通过将计算分为嵌入和损失计算两个阶段,允许批量大小的扩展,这两个阶段都可以通过小批量进行扩展(https://arxiv.org/pdf/2101.06983.pdf)。通过结合 :class:
GISTEmbedLoss
的引导选择和 :class:CachedMultipleNegativesRankingLoss
的梯度缓存,可以在保持与 :class:GISTEmbedLoss
相当的性能水平的同时减少内存使用。- 参数:
model -- SentenceTransformer 模型
guide -- SentenceTransformer 模型用于指导批次内负样本的选择。
temperature -- 温度参数用于调整余弦相似度的比例。
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
GISTEmbed: 文本嵌入微调中训练负样本的引导样本内选择 https://arxiv.org/abs/2402.16829
- 要求:
(锚点, 正样本) 对 或 (锚点, 正样本, 负样本对)
应与大批量大小一起使用以获得卓越性能,但训练时间比 :class:
MultipleNegativesRankingLoss
更长。
- 输入:
文本
标签
(锚点, 正例) 对
无
(锚点, 正样本, 负样本) 三元组
无
- 推荐:
使用
BatchSamplers.NO_DUPLICATES
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保批次内的负样本不是锚点或正样本的重复。
- 关系:
等同于 :class:
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) trainer = SentenceTransformerTrainer( model=model, train_dataset=train_dataset, loss=loss, ) trainer.train()
MSELoss¶
- class sentence_transformers.losses.MSELoss(model: SentenceTransformer)[源代码][源代码]¶
计算计算出的句子嵌入与目标句子嵌入之间的均方误差损失。如我们的出版物《使用知识蒸馏使单语句子嵌入多语言化》中所述,在将句子嵌入扩展到新语言时使用此损失。
例如,请参阅
蒸馏文档 <../../examples/training/distillation/README.html>
_ ,了解如何将语言模型扩展到新语言。- 参数:
model -- SentenceTransformerModel
引用
使用知识蒸馏使单语句嵌入多语言化:https://arxiv.org/abs/2004.09813
训练 > 模型蒸馏 <../../examples/training/distillation/README.html>
_`训练 > 多语言模型 <../../examples/training/multilingual/README.html>
_
- 要求:
通常在知识蒸馏设置中使用微调后的教师模型 M。
- 输入:
文本
标签
句子
模型句子嵌入
sentence_1, sentence_2, ..., sentence_N
模型句子嵌入
- 关系:
:class:
MarginMSELoss
等同于这个损失,但通过负对增加了边际。
示例
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: ~sentence_transformers.SentenceTransformer.SentenceTransformer, similarity_fct=<function pairwise_dot_score>)[源代码][源代码]¶
计算
|sim(Query, Pos) - sim(Query, Neg)|
和|gold_sim(Query, Pos) - gold_sim(Query, Neg)|
之间的 MSE 损失。默认情况下,sim() 是点积。gold_sim 通常是教师模型的相似度分数。与 :class:
MultipleNegativesRankingLoss
相比,这两个段落不必严格为正例和负例,两者都可以与给定的查询相关或不相关。这可能是 MarginMSELoss 相对于 MultipleNegativesRankingLoss 的一个优势,但请注意,MarginMSELoss 的训练速度要慢得多。使用 MultipleNegativesRankingLoss 时,在批量大小为 64 的情况下,我们将一个查询与 128 个段落进行比较。而使用 MarginMSELoss 时,我们只将一个查询与两个段落进行比较。- 参数:
model -- SentenceTransformerModel
similarity_fct -- 使用哪个相似度函数。
引用
更多详情,请参阅 https://arxiv.org/abs/2010.02666。
训练示例 > MS MARCO <../../examples/training/ms_marco/README.html>
_无监督学习 > 领域适应 <../../examples/domain_adaptation/README.html>
_
- 要求:
(查询, 段落一, 段落二) 三元组
通常在知识蒸馏设置中与微调后的教师模型 M 一起使用
- 输入:
文本
标签
(查询, 段落一, 段落二) 三元组
M(查询, 段落一) - M(查询, 段落二)
- 关系:
:class:
MSELoss
等同于这个损失,但没有通过负对来设置的边际。
示例
使用黄金标签,例如,如果你有句子的硬得分。想象一下,你希望一个模型将具有相似“质量”的句子嵌入到彼此接近的位置。如果“text1”的质量是5分之5,“text2”的质量是5分之1,“text3”的质量是5分之3,那么一对的相似性可以定义为质量得分的差异。因此,“text1”和“text2”之间的相似性是4,“text1”和“text3”之间的相似性是2。如果我们使用这个作为我们的“教师模型”,标签就变成了相似性(“text1”,“text2”)- 相似性(“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: Module, matryoshka_dims: list[int], matryoshka_weights: list[float | int] | None = None, n_dims_per_step: int = -1)[源代码][源代码]¶
MatryoshkaLoss 可以被视为一个损失 修饰器,它允许你在不同的嵌入维度上使用其他损失函数。当你想训练一个模型,用户可以选择降低嵌入维度以提高他们的嵌入比较速度和成本时,这是非常有用的。
- 参数:
model -- SentenceTransformer 模型
loss -- 要使用的损失函数,例如 :class:
MultipleNegativesRankingLoss
、:class: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
套娃嵌入 <../../examples/training/matryoshka/README.html>
_
- 要求:
基本损失不能是 :class:
CachedMultipleNegativesRankingLoss
或 :class:CachedGISTEmbedLoss
。
- 输入:
文本
标签
任何
任何
- 关系:
- :class:
Matryoshka2dLoss
结合 :class:AdaptiveLayerLoss
使用此损失,这允许 层减少以加速推理。
- :class:
示例
from sentence_transformers import SentenceTransformer, losses, InputExample from torch.utils.data import DataLoader model = SentenceTransformer("microsoft/mpnet-base") train_examples = [ InputExample(texts=['Anchor 1', 'Positive 1']), InputExample(texts=['Anchor 2', 'Positive 2']), ] train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=32) train_loss = losses.MultipleNegativesRankingLoss(model=model) train_loss = losses.MatryoshkaLoss(model, train_loss, [768, 512, 256, 128, 64]) model.fit( [(train_dataloader, train_loss)], epochs=10, )
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)[源代码][源代码]¶
Matryoshka2dLoss 可以被视为一个损失 修饰器,它结合了 :class:
AdaptiveLayerLoss
和 :class:MatryoshkaLoss
。这使得你可以训练一个嵌入模型,该模型 1) 允许用户指定要使用的模型层数,以及 2) 允许用户指定要使用的输出维度。前者在用户希望选择减少使用的层数以提高推理速度和内存使用时很有用,后者在用户希望选择降低输出维度以提高下游任务(如检索)的效率或降低存储成本时很有用。
注意,这使用了
n_layers_per_step=1
和n_dims_per_step=1
作为默认值,遵循原始的 2DMSE 实现。- 参数:
model -- SentenceTransformer 模型
loss -- 要使用的损失函数,例如 :class:
MultipleNegativesRankingLoss
、:class: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句子嵌入(2DMSE)论文:https://arxiv.org/abs/2402.14776
套娃嵌入 <../../examples/training/matryoshka/README.html>
_自适应层 <../../examples/training/adaptive_layer/README.html>
_
- 要求:
基本损失不能是 :class:
CachedMultipleNegativesRankingLoss
。
- 输入:
文本
标签
任何
任何
- 关系:
:class:
MatryoshkaLoss
用于此损失函数中,它负责降维。:class:
AdaptiveLayerLoss
用于此损失中,它负责层减少。
示例
from sentence_transformers import SentenceTransformer, losses, InputExample from torch.utils.data import DataLoader model = SentenceTransformer("microsoft/mpnet-base") train_examples = [ InputExample(texts=['Anchor 1', 'Positive 1']), InputExample(texts=['Anchor 2', 'Positive 2']), ] train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=32) train_loss = losses.MultipleNegativesRankingLoss(model=model) train_loss = losses.Matryoshka2dLoss(model, train_loss, [768, 512, 256, 128, 64]) model.fit( [(train_dataloader, train_loss)], epochs=10, )
AdaptiveLayerLoss¶
- class sentence_transformers.losses.AdaptiveLayerLoss(model: SentenceTransformer, loss: 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)[源代码][源代码]¶
AdaptiveLayerLoss 可以被视为一个损失 修改器,它允许你在 Sentence Transformer 模型的非最终层使用其他损失函数。当你想要训练一个模型,并且用户可以选择减少使用的层数以提高推理速度和内存使用时,这非常有用。
- 参数:
model -- SentenceTransformer 模型
loss -- 要使用的损失函数,例如 :class:
MultipleNegativesRankingLoss
、:class: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
自适应层 <../../examples/training/adaptive_layer/README.html>
_
- 要求:
基本损失不能是 :class:
CachedMultipleNegativesRankingLoss
或 :class:CachedGISTEmbedLoss
。
- 输入:
文本
标签
任何
任何
- 关系:
- :class:
Matryoshka2dLoss
结合 :class:MatryoshkaLoss
使用此损失,这允许 输出维度缩减以加速下游任务(例如检索)。
- :class:
示例
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)[源代码][源代码]¶
给定一大批(如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(锚点, 正样本) 应该大于 positive_margin
negative_margin -- 负边距,cos(锚点, 负样本) 应小于 负边距
use_mini_batched_version -- 由于大批量需要大量内存,我们可以使用小批量版本。我们将大批量分解为包含较少示例的较小批量。
mini_batch_size -- mini-batch 的大小。应为数据加载器中批量大小的除数。
引用
这个损失函数受到 ParaNMT 论文的启发:https://www.aclweb.org/anthology/P18-1042/
- 要求:
(锚点, 正例) 对
大批量(500个或更多样本)
- 输入:
文本
标签
(锚点, 正例) 对
无
- 推荐:
使用
BatchSamplers.NO_DUPLICATES
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保批次内的负样本不是锚点或正样本的重复。
示例
from sentence_transformers import SentenceTransformer, InputExample, losses from torch.utils.data import DataLoader model = SentenceTransformer('all-MiniLM-L6-v2') total_examples = 500 train_batch_size = 250 train_mini_batch_size = 32 train_examples = [ InputExample(texts=[f"This is sentence number {i}", f"This is sentence number {i+1}"]) for i in range(total_examples) ] train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=train_batch_size) train_loss = losses.MegaBatchMarginLoss(model=model, mini_batch_size=train_mini_batch_size) model.fit( [(train_dataloader, train_loss)], epochs=10, )
MultipleNegativesRankingLoss¶
如果你只有正样本对,例如,只有相似文本对(如同义句对、重复问题对、(查询,响应)对,或(源语言,目标语言)对),MultipleNegativesRankingLoss 是一个很好的损失函数。
- class sentence_transformers.losses.MultipleNegativesRankingLoss(model: ~sentence_transformers.SentenceTransformer.SentenceTransformer, scale: float = 20.0, similarity_fct=<function cos_sim>)[源代码][源代码]¶
此损失期望输入由句子对
(a_1, p_1), (a_2, p_2)..., (a_n, p_n)
组成的批次,其中我们假设(a_i, p_i)
是一个正样本对,而(a_i, p_j)
对于i != j
是一个负样本对。对于每个
a_i
,它使用所有其他p_j
作为负样本,即对于a_i
,我们有 1 个正样本 (p_i
) 和n-1
个负样本 (p_j
)。然后它最小化 softmax 归一化分数的负对数似然。这个损失函数非常适合用于训练检索设置中的嵌入,其中你有正样本对(例如(查询,相关文档)),因为它将在每个批次中随机抽取
n-1
个负样本文档。性能通常随着批量大小的增加而提高。
你也可以通过以下方式为每个锚点-正样本对提供一个或多个硬负样本:
(a_1, p_1, n_1), (a_2, p_2, n_2)
。然后,n_1
是(a_1, p_1)
的硬负样本。损失函数将使用对于对(a_i, p_i)
的所有p_j
(其中j != i
)和所有n_j
作为负样本。- 参数:
model -- SentenceTransformer 模型
scale -- 相似度函数的输出乘以比例值
similarity_fct -- 句子嵌入之间的相似度函数。默认情况下,使用余弦相似度(cos_sim)。也可以设置为点积(然后设置比例为1)。
引用
智能回复的高效自然语言响应建议,第4.4节: https://arxiv.org/pdf/1705.00652.pdf
训练示例 > 自然语言推理 <../../examples/training/nli/README.html>
_训练示例 > 释义数据 <../../examples/training/paraphrases/README.html>
_训练示例 > Quora 重复问题 <../../examples/training/quora_duplicate_questions/README.html>
_训练示例 > MS MARCO <../../examples/training/ms_marco/README.html>
_无监督学习 > SimCSE <../../examples/unsupervised_learning/SimCSE/README.html>
_`无监督学习 > GenQ <../../examples/unsupervised_learning/query_generation/README.html>
_
- 要求:
(锚点, 正样本) 对 或 (锚点, 正样本, 负样本) 三元组
- 输入:
文本
标签
(锚点, 正例) 对
无
(锚点, 正样本, 负样本) 三元组
无
- 推荐:
使用
BatchSamplers.NO_DUPLICATES
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保批次内的负样本不是锚点或正样本的重复。
- 关系:
:class:
CachedMultipleNegativesRankingLoss
等同于这个损失,但它使用了缓存,允许在不增加额外内存使用的情况下实现更高的批量大小(从而提高性能)。然而,它的速度稍慢。:class:
MultipleNegativesSymmetricRankingLoss
等同于这个损失,但有一个额外的损失项。:class:
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)[源代码][源代码]¶
通过 GradCache (https://arxiv.org/pdf/2101.06983.pdf) 增强的 MultipleNegativesRankingLoss (https://arxiv.org/pdf/1705.00652.pdf) 版本。
对比学习(这里我们的MNRL损失)与批次内负样本通常由于(GPU)内存限制而难以处理大批量。即使使用像梯度缩放这样的批次缩放方法,它也无法工作。这是因为批次内负样本使得同一批次内的数据点非独立,因此批次不能被分解为小批次。GradCache是一种解决这个问题的聪明方法。它通过将计算分为嵌入和损失计算两个阶段来实现目标,这两个阶段都可以通过小批次进行缩放。因此,恒定大小的内存(例如,适用于批次大小=32)现在可以处理更大的批次(例如,65536)。
详细来说:
首先,它进行一个快速的嵌入步骤,不使用梯度/计算图来获取所有嵌入;
计算损失,反向传播到嵌入层并缓存相对于嵌入层的梯度;
第二次嵌入步骤,包含梯度/计算图,并将缓存的梯度连接到反向链中。
注释:所有步骤都是通过小批量完成的。在GradCache的原始实现中,(2)不是通过小批量完成的,当批量大小较大时需要大量内存。一个缺点是速度。根据论文,GradCache将牺牲大约20%的计算时间。
- 参数:
model -- SentenceTransformer 模型
scale -- 相似度函数的输出乘以比例值
similarity_fct -- 句子嵌入之间的相似度函数。默认情况下,使用余弦相似度(cos_sim)。也可以设置为点积(然后设置比例为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
- 要求:
(锚点, 正样本) 对 或 (锚点, 正样本, 负样本对)
应与大批量大小一起使用以获得卓越性能,但训练时间比 :class:
MultipleNegativesRankingLoss
更长。
- 输入:
文本
标签
(锚点, 正例) 对
无
(锚点, 正样本, 负样本) 三元组
无
- 推荐:
使用
BatchSamplers.NO_DUPLICATES
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保批次内的负样本不是锚点或正样本的重复。
- 关系:
等同于 :class:
MultipleNegativesRankingLoss
,但具有缓存功能,允许更大的批处理大小。
(从而获得更好的性能)而无需额外的内存使用。这种损失也比 :class:
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.CachedGISTEmbedLoss(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>)[源代码][源代码]¶
给定一组 (锚点, 正样本) 对,此损失函数求和以下两种损失:
正向损失:给定一个锚点,从批次中的所有正样本中找到相似度最高的样本。这等同于 :class:
MultipleNegativesRankingLoss
。反向损失:给定一个正样本,从批次中的所有锚点中找到相似度最高的样本。
例如,在问答对中,:class:
MultipleNegativesRankingLoss
仅计算给定问题找到答案的损失,但 :class:MultipleNegativesSymmetricRankingLoss
还额外计算给定答案找到问题的损失。注意:如果你传递三元组,负条目将被忽略。锚点仅针对正条目进行搜索。
- 参数:
model -- SentenceTransformer 模型
scale -- 相似度函数的输出乘以比例值
similarity_fct -- 句子嵌入之间的相似度函数。默认情况下,使用余弦相似度(cos_sim)。也可以设置为点积(然后设置比例为1)。
- 要求:
(锚点, 正例) 对
- 输入:
文本
标签
(锚点, 正例) 对
无
- 推荐:
使用
BatchSamplers.NO_DUPLICATES
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保批次内的负样本不是锚点或正样本的重复。
- 关系:
类似于 :class:
MultipleNegativesRankingLoss
,但增加了一个额外的损失项。:class:
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)[源代码][源代码]¶
通过 GradCache 增强的 :class:
MultipleNegativesSymmetricRankingLoss
(MNSRL) 版本(https://arxiv.org/pdf/2101.06983.pdf)。给定一组 (锚点, 正样本) 对,MNSRL 求和以下两种损失:
前向损失:给定一个锚点,在批次中的所有正样本中找到相似度最高的样本。
反向损失:给定一个正样本,从批次中的所有锚点中找到相似度最高的样本。
例如,在问答对中,前向损失为给定的问题找到答案,而后向损失为给定的答案找到问题。这种损失在语义文本相似性等对称任务中很常见。
缓存修改允许在大批量(提供更好的训练信号)下保持恒定的内存使用,使您能够在常规硬件上达到最佳训练信号。
注意:如果你传递三元组,负值条目将被忽略。锚点仅针对正值进行搜索。
- 参数:
model -- SentenceTransformer 模型
scale -- 相似度函数的输出乘以比例值
similarity_fct -- 句子嵌入之间的相似度函数。默认情况下,使用余弦相似度(cos_sim)。也可以设置为点积(然后设置比例为1)。
mini_batch_size -- 前向传递的迷你批次大小,这表示在训练和评估期间实际使用的内存量。迷你批次越大,训练的内存效率越高,但训练速度会越慢。
show_progress_bar -- 如果为真,则在处理过程中显示进度条
- 要求:
(锚点, 正例) 对
应使用较大的批量大小以获得更佳性能,但训练时间比非缓存版本慢。
- 输入:
文本
标签
(锚点, 正例) 对
无
- 推荐:
使用
BatchSamplers.NO_DUPLICATES
(:class:文档 <sentence_transformers.training_args.BatchSamplers>
) 以确保批次内的负样本不是锚点或正样本的重复。
- 关系:
类似于 :class:
MultipleNegativesRankingLoss
,但额外增加了一个对称损失项和缓存机制。受 :class:
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())[源代码][源代码]¶
这种损失函数在我们 SBERT 的出版物(https://arxiv.org/abs/1908.10084)中用于在 NLI 数据上训练 SentenceTransformer 模型。它在两个变换器网络的输出之上添加了一个 softmax 分类器。
:class:
MultipleNegativesRankingLoss
是一种替代损失函数,根据 https://arxiv.org/abs/2004.09813 的描述,它通常能产生更好的结果。- 参数:
model (SentenceTransformer) -- SentenceTransformer 模型。
sentence_embedding_dimension (int) -- 句子嵌入的维度。
num_labels (int) -- 不同标签的数量。
concatenation_sent_rep (bool) -- 是否将向量 u,v 连接用于 softmax 分类器。默认为 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: 使用孪生BERT网络的句子嵌入: https://arxiv.org/abs/1908.10084
训练示例 > 自然语言推理 <../../examples/training/nli/README.html>
_
- 要求:
带有类标签的句子对
- 输入:
文本
标签
(sentence_A, sentence_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)[源代码][源代码]¶
此类实现了三元组损失。给定一个三元组(锚点、正样本、负样本),损失函数在最小化锚点与正样本之间距离的同时,最大化锚点与负样本之间的距离。它计算以下损失函数:
loss = max(||anchor - positive|| - ||anchor - negative|| + margin, 0)
.Margin 是一个重要的超参数,需要分别进行调整。
- 参数:
model -- SentenceTransformerModel
distance_metric -- 计算两个嵌入之间距离的函数。类 TripletDistanceMetric 包含可使用的常见距离度量。
triplet_margin -- 负样本应至少比正样本离锚点更远。
引用
更多详情,请参阅: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()