KOB*_*KOB 20 python nlp vector cosine-similarity huggingface-transformers
我正在使用 HuggingFace Transformers 包来访问预训练模型。由于我的用例需要英语和阿拉伯语的功能,因此我使用了bert-base-multilingual- cased 预训练模型。我需要能够使用诸如余弦相似度之类的东西来比较句子的相似度。要使用它,我首先需要为每个句子获取一个嵌入向量,然后可以计算余弦相似度。
首先,从 BERT 模型中提取语义嵌入的最佳方法是什么?在输入句子后获取模型的最后一个隐藏状态就足够了吗?
import torch
from transformers import BertModel, BertTokenizer
model_class = BertModel
tokenizer_class = BertTokenizer
pretrained_weights = 'bert-base-multilingual-cased'
tokenizer = tokenizer_class.from_pretrained(pretrained_weights)
model = model_class.from_pretrained(pretrained_weights)
sentence = 'this is a test sentence'
input_ids = torch.tensor([tokenizer.encode(sentence, add_special_tokens=True)])
with torch.no_grad():
output_tuple = model(input_ids)
last_hidden_states = output_tuple[0]
print(last_hidden_states.size(), last_hidden_states)
Run Code Online (Sandbox Code Playgroud)
其次,如果这是从我的句子中获得嵌入的充分方法,我现在还有另一个问题,即嵌入向量的长度取决于原始句子的长度。形状输出是[1, n, vocab_size],其中n可以有任何值。
为了计算两个向量的余弦相似度,它们需要具有相同的长度。我怎么能在这里做到这一点?像第一次求和这样幼稚的事情axis=1还能奏效吗?我还有什么其他选择?
den*_*ger 18
除了一个已经被广泛接受的答案之外,我还想向您指出sentence-BERT,它更详细地讨论了特定指标(如余弦相似度)的相似性方面和含义。他们也有一个非常方便的在线实施。这里的主要优点是,与“天真的”句子嵌入比较相比,它们似乎获得了很多处理速度,但我对实现本身还不够熟悉。
重要的是,在您想要查看的相似性方面,通常也有更细粒度的区别。专门为此,SemEval 2014(SICK 数据集)的一篇任务论文中也有一个很好的讨论,其中更详细地介绍了这一点。根据您的任务描述,我假设您已经在使用来自后来的 SemEval 任务之一的数据,这也将其扩展到多语言相似性。
Swi*_*ier 10
您可以使用[CLS]令牌作为整个序列的表示。此标记通常在预处理步骤中添加到您的句子中。此令牌通常用于分类任务(参见BERT 论文中的图 2 和第 3.2 段)。
它是嵌入的第一个标记。
或者,您可以采用序列的平均向量(就像您在第一个(?)轴上所说的那样),根据Huggingface 文档(第三个技巧)可以产生更好的结果。
请注意,BERT 不是为使用余弦距离的句子相似性而设计的,但根据我的经验,它确实产生了不错的结果。
您不应该使用 BERT 的输出作为语义相似性的句子嵌入。BERT 没有针对语义相似性进行预训练,这会导致结果很差,甚至比简单的 Glove Embeddings 还要糟糕。请参阅下面 Jacob Devlin(BERT 论文第一作者)的评论和 Sentence-BERT 论文中的一篇文章,其中详细讨论了句子嵌入。
Jacob Devlin 的评论:我不确定这些向量是什么,因为 BERT 不会生成有意义的句子向量。这似乎是对单词标记进行平均池化以获得句子向量,但我们从未建议这将生成有意义的句子表示。即使它们在被输入到为下游任务训练的 DNN 中时是不错的表示,但这并不意味着它们在余弦距离方面是有意义的。(因为余弦距离是一个线性空间,其中所有维度的权重相等)。(https://github.com/google-research/bert/issues/164#issuecomment-441324222)
来自Sentence-BERT论文:结果表明,直接使用BERT的输出会导致性能相当差。对 BERT 嵌入进行平均仅实现 54.81 的平均相关性,而使用 CLS 令牌输出仅实现 29.19 的平均相关性。两者都比计算平均 GloVe 嵌入要差。(https://arxiv.org/pdf/1908.10084.pdf)
您应该使用专门针对句子相似度进行预训练的模型,例如 Sentence-BERT。Sentence-BERT 和其他几个用于句子相似性的预训练模型可在句子转换器库 ( https://www.sbert.net/docs/pretrained_models.html ) 中找到,它与令人惊叹的 HuggingFace 转换器库完全兼容。使用这些库,您只需一行代码即可获得句子嵌入。
| 归档时间: |
|
| 查看次数: |
9332 次 |
| 最近记录: |