BertForSequenceClassification 使用的是 CLS 向量吗?

问题描述 投票:0回答:1

拥抱脸源代码中,使用了

pooled_output = outputs[1]

        outputs = self.bert(
            input_ids,
            attention_mask=attention_mask,
            token_type_ids=token_type_ids,
            position_ids=position_ids,
            head_mask=head_mask,
            inputs_embeds=inputs_embeds,
            output_attentions=output_attentions,
            output_hidden_states=output_hidden_states,
            return_dict=return_dict,
        )

        pooled_output = outputs[1]

不应该是

pooled_output = outputs[0]
吗? (这个answer提到BertPooler似乎已经过时了)

基于this答案,CLS 令牌似乎学习了句子级表示。我很困惑为什么/如何屏蔽语言模型会导致开始标记学习句子级表示。 (我认为

BertForSequenceClassification
冻结了Bert模型,只训练分类头,但也许事实并非如此)

句子嵌入是否与 [CLS] 令牌嵌入等效甚至更好?

nlp huggingface-transformers bert-language-model
1个回答
0
投票

句子嵌入是否与 [CLS] 令牌嵌入等效甚至更好?

句子嵌入是将输入序列表示为数值向量的一切。问题是这种嵌入是否具有语义意义(例如,我们可以将它与相似性度量一起使用)。例如,谷歌发布的预训练 Bert 权重就不是这种情况(请参阅此 answer 了解更多信息)。

CLS token 是句子嵌入吗?是的。 某种池化是一种句子嵌入吗?是的。 对于谷歌发布的 Bert 权重来说,它们在语义上有意义吗?没有。

不应该是 pooled_output =outputs[0] 吗?

不,因为当你检查代码时,你会看到元组的第一个元素是last_hidden_state

sequence_output = encoder_outputs[0]
pooled_output = self.pooler(sequence_output) if self.pooler is not None else None

if not return_dict:
    return (sequence_output, pooled_output) + encoder_outputs[1:]

我很困惑为什么/如何屏蔽语言模型会导致起始标记学习句子级表示。

因为它包含在每个训练序列中,并且

[CLS]
“吸收”其他标记。你也可以在注意力机制中看到这一点(比较 Revealing the Dark Secrets of BERT paper)。如上所述,问题是它们在没有任何进一步微调的情况下是否具有语义意义。否(比较此 StackOverflow answer)。

© www.soinside.com 2019 - 2024. All rights reserved.