这是有问题的代码。
https://github.com/huggingface/transformers/blob/master/src/transformers/modeling_bert.py#L491
class BertOnlyNSPHead(nn.Module):
def __init__(self, config):
super().__init__()
self.seq_relationship = nn.Linear(config.hidden_size, 2)
def forward(self, pooled_output):
seq_relationship_score = self.seq_relationship(pooled_output)
return seq_relationship_score
我认为这只是在对一个句子跟另一个句子的可能性进行排名?不是一个分数吗?
答案 0 :(得分:3)
这两个分数旨在表示模型中的非标准化概率(logits
)。如果对它们进行softmax运算,我们将得到预测,其中索引0表示下一个句子,索引1表示随机。
这只是代表HuggingFace作者的一种风格选择,可能会使损失函数保持一致。
这是forward
的{{1}}方法,其中BertForPretraining
是self.cls
:
BertOnlyNSPHead
对于MLM和NSP使用相同的CrossEntropyLoss很方便。
正如您所描述的,这等于让NSP生成单个输出,然后通过S型字输入该数字以获得下一个句子的概率。然后,我们可以使用 prediction_scores, seq_relationship_score = self.cls(sequence_output, pooled_output)
outputs = (prediction_scores, seq_relationship_score,) + outputs[
2:
] # add hidden states and attention if they are here
if masked_lm_labels is not None and next_sentence_label is not None:
loss_fct = CrossEntropyLoss()
masked_lm_loss = loss_fct(prediction_scores.view(-1, self.config.vocab_size), masked_lm_labels.view(-1))
next_sentence_loss = loss_fct(seq_relationship_score.view(-1, 2), next_sentence_label.view(-1))
total_loss = masked_lm_loss + next_sentence_loss
outputs = (total_loss,) + outputs
进行训练。 (其中BCEWithLogitsLoss
只是交叉熵损失的特殊二进制情况)。