拥抱脸源代码中,使用了
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] 令牌嵌入等效甚至更好?
句子嵌入是否与 [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)。