bert层中的池化输出和序列输出有什么区别?

what is the difference between pooled output and sequence output in bert layer?

大家好!我正在阅读有关 Bert 的文章,并想用它的词嵌入来进行文本分类。我遇到了这行代码:

pooled_output, sequence_output = self.bert_layer([input_word_ids, input_mask, segment_ids])   

然后:

clf_output = sequence_output[:, 0, :]
out = Dense(1, activation='sigmoid')(clf_output)

但是我无法理解池化输出的使用。 序列输出不包含包括['CLS']的词嵌入在内的所有信息吗?如果是这样,为什么我们要合并输出?

提前致谢!

如果你给出了一个序列,“你在 Whosebug 上”。 sequence_output 将给出这四个词的 768 个嵌入。但是,池化输出只会给你一个 768 的嵌入,它会池化这四个词的嵌入。

序列输出 是 BERT 模型最后一层输出的隐藏状态(嵌入)序列。它包括 [CLS] 令牌的嵌入。因此,对于句子“You are on Whosebug”,它给出了 5 个嵌入:四个词中的每一个的一个嵌入(假设单词“Whosebug”被标记为单个标记)以及 [CLS] 标记的嵌入。 Pooled 输出 是 [CLS] 标记的嵌入(来自 序列输出 ),由线性层和 Tanh 激活函数进一步处理。线性层权重是在预训练期间从下一个句子预测(分类)objective 训练的。更多细节请参考BERT原论文

正如许多其他答案所指出的,sequence_output 是 token-level 具有 2 个维度——第一个维度对应于输入文本中的标记数。

pooled_output 是 one-dimensional 并且似乎是输入文本的某种 higher-order 上下文嵌入。

我最初觉得它们应该包含几乎相同的信息(或者 sequence_output 应该包含更多给定额外的 n_token 维度),但现在我正在训练基于以下内容的语义相似性模型与仅使用 sequence_output.

相比,Bert 和我在模型中同时使用 sequence_outputpooled_output 看到了明显更好的结果