从BERT

时间:2020-05-03 05:10:34

标签: python tensorflow nlp huggingface-transformers bert-language-model

在将令牌传递给BERT之前,我想对它们的嵌入(嵌入查找层的结果)进行一些处理。 HuggingFace BERT TensorFlow implementation允许我们使用以下命令访问嵌入查找的输出:

import tensorflow as tf
from transformers import BertConfig, BertTokenizer, TFBertModel

bert_tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

input_ids = tf.constant(bert_tokenizer.encode("Hello, my dog is cute", add_special_tokens=True))[None, :]
attention_mask = tf.stack([tf.ones(shape=(len(sent),)) for sent in input_ids])
token_type_ids = tf.stack([tf.ones(shape=(len(sent),)) for sent in input_ids])

config = BertConfig.from_pretrained('bert-base-uncased', output_hidden_states=True)
bert_model = TFBertModel.from_pretrained('bert-base-uncased', config=config)

result = bert_model(inputs={'input_ids': input_ids, 
                            'attention_mask': attention_mask, 
                            'token_type_ids': token_type_ids})
inputs_embeds = result[-1][0]  # output of embedding lookup

随后,可以处理inputs_embeds,然后使用以下命令将其作为输入发送到同一模型:

inputs_embeds = process(inputs_embeds)  # some processing on inputs_embeds done here (dimensions kept the same)
result = bert_model(inputs={'inputs_embeds': inputs_embeds, 
                            'attention_mask': attention_mask, 
                            'token_type_ids': token_type_ids})
output = result[0]

其中output现在包含已修改输入的BERT输出。但是,这需要两次通过BERT。我不只是一直执行BERT来执行嵌入查找,而是想获取嵌入查找层的输出。 这可能吗?如果可能,怎么办?

1 个答案:

答案 0 :(得分:3)

将第一个输出result[-1][0]视为嵌入查找的结果实际上是不正确的。原始的嵌入查询由以下给出:

embeddings = bert_model.bert.get_input_embeddings()
word_embeddings = embeddings.word_embeddings
inputs_embeds = tf.gather(word_embeddings, input_ids)

result[-1][0]给出嵌入查找 plus 位置嵌入和令牌类型嵌入。上面的代码不需要完全通过BERT,并且可以在将结果输入BERT的其余层之前对其进行处理。

编辑:要获得将附加位置和令牌类型嵌入的结果嵌入到任意inputs_embeds中,可以使用:

full_embeddings = embeddings(inputs=[None, None, token_type_ids, inputs_embeds])

在这里,call对象的embeddings方法接受一个列表,该列表被馈送到_embeddings方法中。第一个值为input_ids,第二个值为position_ids,第三个值为token_type_ids,第四个值为inputs_embeds。 (有关更多详细信息,请参见here。)如果一个输入中有多个句子,则可能需要设置position_ids