如何在 HuggingFace Transformers 库中获取中间层的预训练 BERT 模型输出?

Posted

技术标签:

【中文标题】如何在 HuggingFace Transformers 库中获取中间层的预训练 BERT 模型输出?【英文标题】:How to get intermediate layers' output of pre-trained BERT model in HuggingFace Transformers library? 【发布时间】:2020-08-11 09:00:33 【问题描述】:

(我正在关注thispytorch 关于BERT 词嵌入的教程,在教程中作者访问了BERT 模型的中间层。)

我想要的是使用 HuggingFace 的 Transformers 库访问 TensorFlow2 中 BERT 模型的单个输入标记的最后 4 层,比如说,最后 4 层。因为每一层输出一个长度为 768 的向量,所以最后 4 层的形状为4*768=3072(对于每个标记)。

如何在 TF/keras/TF2 中实现这一点,以获得输入标记的预训练模型的中间层? (稍后我会尝试获取句子中每个token的token,但现在一个token就足够了)。

我正在使用 HuggingFace 的 BERT 模型:

!pip install transformers
from transformers import (TFBertModel, BertTokenizer)

bert_model = TFBertModel.from_pretrained("bert-base-uncased")  # Automatically loads the config
bert_tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
sentence_marked = "hello"
tokenized_text = bert_tokenizer.tokenize(sentence_marked)
indexed_tokens = bert_tokenizer.convert_tokens_to_ids(tokenized_text)

print (indexed_tokens)
>> prints [7592]

输出是一个令牌 ([7592]),它应该是 BERT 模型的输入。

【问题讨论】:

我建议您更改您的标签,因为您提出了有关 PyTorch 的问题并标记了 tensorflow。它具有误导性,对您也无济于事。 通过“获取预训练模型的中间层”,我假设您指的是中间层的隐藏状态,对吧?请注意,BERT 会产生上下文令牌表示,因此使用基于仅包含该令牌的输入序列的令牌表示是没有意义的。此外,它使用词片来标记输入,因此一个词可以表示为两个或多个词片标记,因此该词的两个或多个表示向量(需要组合回来以获得该词的一个向量)。 @today 是的,我知道 BERT 必须获取句子的上下文才能获得最佳嵌入。但我的问题是如何获得中间层的输出 - BERT 的 12 个层中的每一个都为每个令牌输出一个包含 764 个值的数组,我的问题是如何访问这些值 【参考方案1】:

BERT 模型输出的第三个元素是一个元组,它由嵌入层的输出以及中间层的隐藏状态组成。来自documentation:

hidden_​​states(tuple(tf.Tensor),可选,config.output_hidden_states=True时返回): tf.Tensor 的元组(一个用于嵌入的输出 + 一个用于每一层的输出),形状为 (batch_size, sequence_length, hidden_size)

每层输出的模型隐藏状态加上初始嵌入输出。

对于bert-base-uncased 模型,config.output_hidden_states 默认为True。因此,要访问 12 个中间层的隐藏状态,您可以执行以下操作:

outputs = bert_model(input_ids, attention_mask)
hidden_states = outputs[2][1:]

hidden_states元组中有12个元素对应从头到尾的所有层,每个元素都是一个形状为(batch_size, sequence_length, hidden_size)的数组。因此,例如,要访问批次中所有样本的第五个令牌的第三层隐藏状态,您可以这样做:hidden_states[2][:,4]


请注意,如果您正在加载的模型默认不返回隐藏状态,那么您可以使用 BertConfig 类加载配置并传递 output_hidden_state=True 参数,如下所示:

config = BertConfig.from_pretrained("name_or_path_of_model",
                                    output_hidden_states=True)

bert_model = TFBertModel.from_pretrained("name_or_path_of_model",
                                         config=config)

【讨论】:

以上是关于如何在 HuggingFace Transformers 库中获取中间层的预训练 BERT 模型输出?的主要内容,如果未能解决你的问题,请参考以下文章

如何下载 HuggingFace 模型“transformers.trainer.Trainer”?

如何在 Huggingface Trainer 课程中恢复训练时避免迭代 Dataloader?

如何在 HuggingFace Transformers GPT-2 中使用过去?

如何在 HuggingFace Transformers 库中获取中间层的预训练 BERT 模型输出?

将 AllenNLP 解释与 HuggingFace 模型一起使用

使用 Huggingface TFTrainer 类微调模型时如何指定损失函数?