用于文档嵌入的longformer的最后一层

问题描述

使用longformer API返回有限数量的图层的正确方法是什么?

与基本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,truncation=True)
output = model(**encoded_input,output_hidden_states=True)

好的,现在让我们看一下输出[2],这是元组的第三项:

>>> len(output[2])
13

假设我们要查看13层中的最后3层:

>>> [pair[0].shape for pair in output[2][-3:]]
[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)

将它们平均在一起似乎无法提供有效的嵌入效果(用于余弦相似度等比较)。

解决方法

output是一个由两个元素组成的元组:

  1. sequence_output(即最后一个编码器块)
  2. pooled_output

为了获取所有隐藏层,您需要将参数output_hidden_states设置为true:

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

现在输出包含3个元素,第三个元素包含嵌入层和每个编码层的输出。

,
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] 作为嵌入。