Получение встраиваемого результата поиска из BERT - PullRequest
0 голосов
/ 03 мая 2020

Прежде чем передать свои токены через BERT, я хотел бы выполнить некоторую обработку их вложений (результат слоя поиска внедрения). Реализация HuggingFace BERT TensorFlow позволяет нам получить доступ к выводу встраиваемого поиска, используя:

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 голосов
/ 10 мая 2020

На самом деле некорректно обрабатывать первый вывод 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] дает поиск встраивания плюс позиционные вложения и вложения типа токена. Приведенный выше код не требует полного прохождения через BERT, и результат может быть обработан до подачи в оставшиеся слои BERT.

EDIT : получить результат сложения позиционно и Вложение типа токена в произвольный 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. (Подробнее см. здесь .) Если у вас есть несколько предложений в одном входе, вам может потребоваться установить position_ids.

...