如何用XLNet做句子相似度?

spa*_*del 5 python nlp embedding transformer-model cosine-similarity

我想执行句子相似度任务并尝试了以下操作:

from transformers import XLNetTokenizer, XLNetModel
import torch
import scipy
import torch.nn as nn
import torch.nn.functional as F

tokenizer = XLNetTokenizer.from_pretrained('xlnet-large-cased')
model = XLNetModel.from_pretrained('xlnet-large-cased')

input_ids = torch.tensor(tokenizer.encode("Hello, my animal is cute", add_special_tokens=False)).unsqueeze(0)
outputs = model(input_ids)
last_hidden_states = outputs[0]

input_ids = torch.tensor(tokenizer.encode("I like your cat", add_special_tokens=False)).unsqueeze(0) 

outputs1 = model(input_ids)
last_hidden_states1 = outputs1[0]

cos = nn.CosineSimilarity(dim=1, eps=1e-6)
output = cos(last_hidden_states, last_hidden_states1)
Run Code Online (Sandbox Code Playgroud)

但是,我收到以下错误:

RuntimeError: The size of tensor a (7) must match the size of tensor b (4) at non-singleton dimension 1
Run Code Online (Sandbox Code Playgroud)

谁能告诉我,我做错了什么?有更好的方法吗?

Jin*_*ich 0

您做错了几件事。

  1. add_special_tokens应设置为True. 该模型使用<sep>用于分隔句子的标记和<cls>用于句子分类的标记进行训练。由于训练测试数据不匹配,不使用会导致奇怪的行为。

  2. outputs[0]给出单成员 Python 元组的第一个元素。Transformer 包中的所有模型都返回元组,因此是单成员元组。它包含每个输入标记一个向量,包括特殊的向量。

  3. 与 BERT 的[CLS]token 是第一个不同,这里的<cls>token 是最后一个(参见Transformers 文档)。如果你想比较分类向量,你应该从序列中取出最后一个向量,即outputs[0][:, -1]

或者,您可能想要比较嵌入的平均值(平均池)而不是<cls>令牌嵌入。在这种情况下,你可以这样做output[0].mean(1)