BertForSequenceClassification 是不是在 CLS 向量上进行分类?
Posted
技术标签:
【中文标题】BertForSequenceClassification 是不是在 CLS 向量上进行分类?【英文标题】:Does BertForSequenceClassification classify on the CLS vector?BertForSequenceClassification 是否在 CLS 向量上进行分类? 【发布时间】:2020-07-07 15:00:17 【问题描述】:我正在使用 Huggingface Transformer 包和带有 PyTorch 的 BERT。我正在尝试进行 4 向情感分类,并正在使用 BertForSequenceClassification 构建一个模型,最终最终导致 4 向 softmax。
我阅读 BERT 论文的理解是,输入 CLS
标记的最终密集向量用作整个文本字符串的表示:
每个序列的第一个标记始终是一个特殊的分类标记 ([CLS])。这个token对应的最终隐藏状态作为分类任务的聚合序列表示。
那么,BertForSequenceClassification
真的会训练并使用这个向量来执行最终分类吗?
我问的原因是因为当我print(model)
时,CLS
向量正在被使用对我来说并不明显。
model = BertForSequenceClassification.from_pretrained(
model_config,
num_labels=num_labels,
output_attentions=False,
output_hidden_states=False
)
print(model)
这是输出的底部:
(11): BertLayer(
(attention): BertAttention(
(self): BertSelfAttention(
(query): Linear(in_features=768, out_features=768, bias=True)
(key): Linear(in_features=768, out_features=768, bias=True)
(value): Linear(in_features=768, out_features=768, bias=True)
(dropout): Dropout(p=0.1, inplace=False)
)
(output): BertSelfOutput(
(dense): Linear(in_features=768, out_features=768, bias=True)
(LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
(dropout): Dropout(p=0.1, inplace=False)
)
)
(intermediate): BertIntermediate(
(dense): Linear(in_features=768, out_features=3072, bias=True)
)
(output): BertOutput(
(dense): Linear(in_features=3072, out_features=768, bias=True)
(LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)
(dropout): Dropout(p=0.1, inplace=False)
)
)
)
)
(pooler): BertPooler(
(dense): Linear(in_features=768, out_features=768, bias=True)
(activation): Tanh()
)
)
(dropout): Dropout(p=0.1, inplace=False)
(classifier): Linear(in_features=768, out_features=4, bias=True)
我看到有一个池化层 BertPooler
通向一个 Dropout
通向一个 Linear
,这大概执行了最终的 4-way softmax。但是,我不清楚BertPooler
的使用。它是仅在 CLS
的隐藏状态上运行,还是对所有输入标记的隐藏状态进行某种池化?
感谢您的帮助。
【问题讨论】:
【参考方案1】:简短的回答:是的,你是对的。事实上,他们将 CLS 令牌(仅此而已)用于BertForSequenceClassification
。
查看BertPooler
的实现表明它正在使用第一个隐藏状态,它对应于[CLS]
标记。
我简要检查了另一个模型(RoBERTa),看看这在模型之间是否一致。在这里,也只根据 [CLS]
标记进行分类,尽管不太明显(检查行 539-542 here)。
【讨论】:
感谢您在BertPooler
中找到该代码。这个名称具有误导性,因为深度学习中的“池化”通常意味着对多个值进行操作,例如平均池化或最大池化。他们应该把它称为GetHiddenStateOfFirstToken
。
哈哈,没错。就个人而言,我认为在池选项(仅第一个令牌与平均顺序)之间进行选择也会很好。可能最初的意图是后一种情况,在这种情况下,pooler 将是一个好名字。 ;-)以上是关于BertForSequenceClassification 是不是在 CLS 向量上进行分类?的主要内容,如果未能解决你的问题,请参考以下文章