【发布时间】:2020-03-20 16:33:54
【问题描述】:
我正在从 torch hub 加载一个语言模型(CamemBERT 一个基于法国 RoBERTa 的模型)并使用它嵌入一些法语句子:
import torch
camembert = torch.hub.load('pytorch/fairseq', 'camembert.v0')
camembert.eval() # disable dropout (or leave in train mode to finetune)
def embed(sentence):
tokens = camembert.encode(sentence)
# Extract all layer's features (layer 0 is the embedding layer)
all_layers = camembert.extract_features(tokens, return_all_hiddens=True)
embeddings = all_layers[0]
return embeddings
# Here we see that the shape of the embedding vector depends on the number of tokens in the sentence
u = embed(sentence="Bonjour, ça va ?")
u.shape # torch.Size([1, 7, 768])
v = embed(sentence="Salut, comment vas-tu ?")
v.shape # torch.Size([1, 9, 768])
现在想象一下,为了进行一些语义搜索,我想计算向量(在我们的例子中是张量)u 和 v 之间的 cosine distance:
cos = torch.nn.CosineSimilarity(dim=1)
cos(u, v) # will throw an error since the shape of `u` is different from the shape of `v`
我在问,为了始终获得 相同的嵌入形状的句子不管其标记的数量,最好使用什么方法?
=> 我想到的第一个解决方案是计算mean on axis=1(句子的嵌入是嵌入其标记的平均值),因为axis=0 和axis=2 始终具有相同的大小:
cos = torch.nn.CosineSimilarity(dim=1)
cos(u.mean(axis=1), v.mean(axis=1)) # works now and gives 0.7269
但是,我担心在计算平均值时会损害句子的嵌入,因为它为每个标记赋予相同的权重(可能乘以 TF-IDF?)。
=> 第二种解决方案是将较短的句子填充出来。这意味着:
- 一次提供要嵌入的句子列表(而不是逐句嵌入)
- 查找具有最长标记的句子并将其嵌入,得到它的形状
S - 对于嵌入的其余句子,然后填充零以获得相同的形状
S(句子的其余维度为 0)
你的想法是什么? 您还会使用哪些其他技术以及为什么?
提前致谢!
【问题讨论】:
标签: machine-learning deep-learning nlp pytorch word-embedding