Последние слои лонгформера для встраивания документов

Как правильно вернуть ограниченное количество слоев с помощью API longformer?

В отличие от этого случая в базовом BERT мне не ясно из возвращаемого типа, как получить только последние N слоев.

Итак, я запускаю это:

from transformers import LongformerTokenizer, LongformerModel

text = "word " * 4096 # long document!

tokenizer = LongformerTokenizer.from_pretrained('allenai/longformer-base-4096')
model = LongformerModel.from_pretrained("allenai/longformer-base-4096")

encoded_input = tokenizer(text, return_tensors="pt", max_length=4096, truncation=True)
output = model(**encoded_input)

А по возвращении получаю такие размеры:

>>> output[0].shape
torch.Size([1, 4096, 768])

>>> output[1].shape
torch.Size([1, 768])

Вы можете видеть, что форма [0] любопытно похожа на мое количество жетонов. Я считаю, что нарезка этого просто дала бы мне меньше токенов, а не только последние N слоев.

Обновление из ответа ниже

Даже при запросе output_hidden_states размеры все равно выглядят нечеткими, и мне не ясно, как уменьшить их до векторного размера, 1-мерного встраивания. Вот что я имею в виду:

encoded_input = tokenizer(text, return_tensors="pt", max_length=4096, truncation=True)
output = model(**encoded_input, output_hidden_states=True)

Хорошо, теперь давайте посмотрим на output [2], третий элемент кортежа:

>>> len(output[2])
13

Предположим, мы хотим увидеть последние 3 из 13 слоев:

>>> [pair[0].shape for pair in output[2][-3:]]
[torch.Size([4096, 768]), torch.Size([4096, 768]), torch.Size([4096, 768])]

Итак, мы видим, что каждый из 13 слоев имеет форму (4096 x 768), и они выглядят так:

>>> [pair[0] for pair in output[2][-3:]]
[tensor([[-0.1494,  0.0190,  0.0389,  ..., -0.0470,  0.0259,  0.0609],

У нас все еще есть размер 4096, поскольку он соответствует моему количеству токенов:

>>> np.mean(np.stack([pair[0].detach().numpy() for pair in output[2][-3:]]), axis=0).shape
(4096, 768)

Усреднение их вместе, похоже, не дало бы действительного вложения (для сравнений, таких как косинусное сходство).


person Mittenchops    schedule 05.10.2020    source источник


Ответы (2)


output - это кортеж, состоящий из двух элементов:

  1. sequence_output (т.е. последний блок кодировщика)
  2. pooled_output

Чтобы получить все скрытые слои, необходимо установить параметр output_hidden_states в значение true:

output = model(**encoded_input, output_hidden_states=True)

Выходные данные теперь имеют 3 элемента, а третий элемент содержит выходные данные уровня внедрения и каждого уровня кодирования.

person cronoik    schedule 06.10.2020
comment
Спасибо, это полезно, но я думаю, что я все еще сбит с толку после того, как тот же подозрительный размер, что и мое количество токенов. - person Mittenchops; 06.10.2020
comment
@Mittenchops Пожалуйста, не изменяйте свои вопросы настолько, чтобы мой ответ стал бесполезным. Вместо этого откройте новый вопрос. В общем, считаю, что ваш подход неправильный. Не уверен насчет Longformer, но BERT не создает осмысленных представлений предложений это можно использовать для косинусного подобия или чего-то подобного, потому что для этого требуется, чтобы все измерения имели одинаковый масштаб. Думаю, это относится и к Longformer. Вместо этого вы можете попробовать преобразователи предложений. - person cronoik; 07.10.2020
comment
Спасибо, @cronoik. Я нашел ваш ответ полезным, чтобы увидеть, что есть третий кортеж, который я мог бы запросить, но все еще существует разрыв между этим и получением действительных встраиваний, поэтому казалось целесообразным его обновить. У меня наверняка были закрытые вопросы из-за того, что они были / слишком похожи / на предыдущие, если бы я просто воспринял обновление как новый вопрос. Модераторы посоветовали мне делать обновления для ясности. - person Mittenchops; 07.10.2020
comment
Я также понимаю, что довольно часто используются терминальные уровни вложений BERT для использования в таких приложениях, как подобие: stackoverflow.com/a/63464865/ 1052117 и статью по Бертологии, на которую он ссылается: arxiv.org/pdf/2002.12327.pdf - person Mittenchops; 07.10.2020
comment
@Mittenchops Я опубликовал свой ответ как ответ на ваш другой вопрос. - person cronoik; 07.10.2020

print(outputs.keys())            
#odict_keys(['last_hidden_state', 'pooler_output', 'hidden_states'])

print("outputs[0] gives us sequence_output: \n", outputs[0].shape) #torch.Size([1, 34, 768])

print("outputs[1] gives us pooled_output  \n",outputs[1]) #Embeddings ( last hidden state) #[768]
            
print("outputs[2]: gives us Hidden_output: \n ",outputs[2][0].shape) #torch.Size([1, 512, 768]) 
          

Для вашего варианта использования вы можете использовать output [1] как вложения.

person MAC    schedule 19.07.2021