Как получить промежуточные слои предварительно обученной модели BERT в библиотеке HuggingFace Transformers?

(Я следую этому руководству pytorch о слове BERT вложения, а в учебнике автор получает доступ к промежуточным уровням модели BERT.)

Я хочу получить доступ к последним, скажем, 4 последним слоям одного входного токена модели BERT в TensorFlow2 с использованием библиотеки Transformers HuggingFace. Поскольку каждый уровень выводит вектор длиной 768, последние 4 уровня будут иметь форму 4*768=3072 (для каждого токена).

Как я могу реализовать это в TF / keras / TF2, чтобы получить промежуточные уровни предварительно обученной модели для входного токена? (позже я попытаюсь получить токены для каждого токена в предложении, но пока достаточно одного токена).

Я использую модель BERT HuggingFace:

!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.


comment
Я бы предложил изменить ваши теги, поскольку вы задали вопрос о PyTorch и отметили тензорный поток. Это вводит в заблуждение и вам тоже не поможет.   -  person chrisgiffy    schedule 27.04.2020
comment
Я предполагаю, что, получив промежуточные уровни предварительно обученной модели, вы имеете в виду скрытые состояния промежуточных слоев, верно? И обратите внимание, что BERT создает контекстные представления токенов, и поэтому нет смысла использовать представление токена на основе входной последовательности, которая содержит только этот токен. Кроме того, он использует фрагменты слова для разметки ввода, поэтому одно слово может быть представлено как два или более маркера словарного запаса, следовательно, два или более вектора представления для этого слова (которые необходимо объединить обратно, чтобы получить один единственный вектор для этого слова).   -  person today    schedule 28.04.2020
comment
@today да, я знаю, что BERT должен получить контекст предложения в порядке, чтобы получить лучшие вложения. Но мой вопрос в том, как получить выходные данные средних слоев - каждый из 12 слоев BERT выводит массив из 764 значений для каждого токена, и мой вопрос в том, как получить доступ к этим значениям.   -  person Yagel    schedule 29.04.2020


Ответы (1)


Третий элемент вывода модели BERT - это кортеж, который состоит из вывода слоя внедрения, а также скрытых состояний промежуточных слоев. Из документации:

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)
person today    schedule 29.04.2020