为什么BERT NSP head linear layer有两个输出?

Why does the BERT NSP head linear layer have two outputs?

这是有问题的代码。

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

我认为它只是对一个句子跟随另一个句子的可能性进行排名?不就是一分吗?

这两个分数旨在表示模型中的非标准化概率 (logits)。如果我们对它们进行 softmax,我们就会得到我们的预测,其中索引 0 表示下一个句子,索引 1 表示随机。

这只是代表 HuggingFace 作者的风格选择,可能是为了保持损失函数的一致性。

这里是BertForPretrainingforward方法,其中self.clsBertOnlyNSPHead:

    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

对 MLM 和 NSP 使用相同的 CrossEntropyLoss 很方便。

正如您所描述的,这相当于让 NSP 产生单个输出,然后将该数字输入 sigmoid 以获得下一个句子的概率。然后我们可以用 BCEWithLogitsLoss 进行训练。 (其中 BCE 只是交叉熵损失的特殊二进制情况)。