Python 多语言Bert语句向量捕获使用的语言多于意义-作为实习生工作?

Python 多语言Bert语句向量捕获使用的语言多于意义-作为实习生工作?,python,deep-learning,pytorch,multilingual,bert-language-model,Python,Deep Learning,Pytorch,Multilingual,Bert Language Model,与伯特一起玩,我下载了Huggingface多语言伯特,输入了三个句子,保存了它们的句子向量(嵌入[CLS]),然后通过Google Translate进行翻译,通过模型传递并保存了它们的句子向量 然后我用余弦相似性比较了结果 我惊讶地发现,每一个句子向量都与从它翻译出来的句子产生的向量相差甚远(0.15-0.27余弦距离),而来自同一种语言的不同句子却非常接近(0.02-0.04余弦距离) 因此,相同语言的不同句子之间的距离更近,而不是将意义相似(但语言不同)的句子组合在一起(在768维空间中

与伯特一起玩,我下载了Huggingface多语言伯特,输入了三个句子,保存了它们的句子向量(嵌入
[CLS]
),然后通过Google Translate进行翻译,通过模型传递并保存了它们的句子向量

然后我用余弦相似性比较了结果

我惊讶地发现,每一个句子向量都与从它翻译出来的句子产生的向量相差甚远(0.15-0.27余弦距离),而来自同一种语言的不同句子却非常接近(0.02-0.04余弦距离)

因此,相同语言的不同句子之间的距离更近,而不是将意义相似(但语言不同)的句子组合在一起(在768维空间中)

据我所知,多语言Bert的全部要点是跨语言迁移学习——例如,在一种语言的表示上训练模型(比如,和FC网络),并使该模型可以在其他语言中使用

如果(不同语言的)具有确切含义的句子被映射成比同一语言的不同句子更为相隔,那么这怎么可能起作用呢

我的代码:

import torch

import transformers
from transformers import AutoModel,AutoTokenizer

bert_name="bert-base-multilingual-cased"
tokenizer = AutoTokenizer.from_pretrained(bert_name)
MBERT = AutoModel.from_pretrained(bert_name)

#Some silly sentences
eng1='A cat jumped from the trees and startled the tourists'
e=tokenizer.encode(eng1, add_special_tokens=True)
ans_eng1=MBERT(torch.tensor([e]))

eng2='A small snake whispered secrets to large cats'
t=tokenizer.tokenize(eng2)
e=tokenizer.encode(eng2, add_special_tokens=True)
ans_eng2=MBERT(torch.tensor([e]))

eng3='A tiger sprinted from the bushes and frightened the guests'
e=tokenizer.encode(eng3, add_special_tokens=True)
ans_eng3=MBERT(torch.tensor([e]))

# Translated to Hebrew with Google Translate
heb1='חתול קפץ מהעץ והבהיל את התיירים'
e=tokenizer.encode(heb1, add_special_tokens=True)
ans_heb1=MBERT(torch.tensor([e]))

heb2='נחש קטן לחש סודות לחתולים גדולים'
e=tokenizer.encode(heb2, add_special_tokens=True)
ans_heb2=MBERT(torch.tensor([e]))

heb3='נמר רץ מהשיחים והפחיד את האורחים'
e=tokenizer.encode(heb3, add_special_tokens=True)
ans_heb3=MBERT(torch.tensor([e]))


from scipy import spatial
import numpy as np

# Compare Sentence Embeddings

result = spatial.distance.cosine(ans_eng1[1].data.numpy(), ans_heb1[1].data.numpy())

print ('Eng1-Heb1 - Translated sentences',result)


result = spatial.distance.cosine(ans_eng2[1].data.numpy(), ans_heb2[1].data.numpy())

print ('Eng2-Heb2 - Translated sentences',result)

result = spatial.distance.cosine(ans_eng3[1].data.numpy(), ans_heb3[1].data.numpy())

print ('Eng3-Heb3 - Translated sentences',result)

print ("\n---\n")

result = spatial.distance.cosine(ans_heb1[1].data.numpy(), ans_heb2[1].data.numpy())

print ('Heb1-Heb2 - Different sentences',result)

result = spatial.distance.cosine(ans_eng1[1].data.numpy(), ans_eng2[1].data.numpy())

print ('Heb1-Heb3 - Similiar sentences',result)

print ("\n---\n")

result = spatial.distance.cosine(ans_eng1[1].data.numpy(), ans_eng2[1].data.numpy())

print ('Eng1-Eng2 - Different sentences',result)

result = spatial.distance.cosine(ans_eng1[1].data.numpy(), ans_eng3[1].data.numpy())

print ('Eng1-Eng3 - Similiar sentences',result)

#Output:
"""
Eng1-Heb1 - Translated sentences 0.2074061632156372
Eng2-Heb2 - Translated sentences 0.15557605028152466
Eng3-Heb3 - Translated sentences 0.275478720664978

---

Heb1-Heb2 - Different sentences 0.044616520404815674
Heb1-Heb3 - Similar sentences 0.027982771396636963

---

Eng1-Eng2 - Different sentences 0.027982771396636963
Eng1-Eng3 - Similar sentences 0.024596810340881348
"""
附言

至少Heb1比Heb2更接近Heb3。
这一点也适用于英语对应词,但不太常见

[CLS]标记以某种方式表示输入序列,但其确切程度很难说。语言当然是句子的一个重要特征,可能不仅仅是意义。伯特模型是一种预训练模型,它试图对意义、结构和语言等特征进行建模。如果你想有一个模型,它可以帮助你识别两个不同语言的句子是否意味着同一件事,我可以想出两种不同的方法:

  • 方法:你可以在这个任务上训练分类器(SVM,逻辑回归,甚至一些神经网络,比如CNN)<代码>输入:两个[CLS]-标记,输出:相同含义或不相同含义。 作为训练数据,您可以选择不同语言的[CLS]-标记句对,这些句子的含义相同或不同。为了得到有意义的结果,你需要很多这样的句子对。幸运的是,你可以通过google translate生成它们,或者使用类似于圣经的平行文本(存在于许多语言中),并从中提取句子对

  • 方法:精确调整该任务的bert模型: 与前面的方法一样,您需要大量的培训数据。 伯特模型的样本输入如下所示: 一只猫从树上跳下来吓了游客一跳

    要对这些句子是否具有相同的含义进行分类,您需要在[CLS]-标记的顶部添加一个分类层,并在该任务上微调整个模型


  • 注意:我从来没有使用过多语言的伯特模型,这些方法就是我想要完成上述任务的方法。如果您尝试这些方法,我很想知道它们是如何执行的,但仍不完全了解多语言BERT的功能以及它的工作原理。最近有两篇论文(第一篇,第二篇)对此做了一些探讨

    从论文中可以看出,向量似乎倾向于按照语言(甚至语族)进行聚类,因此对语言进行分类非常容易。这是显示的群集:

    正因为如此,你可以从表达中减去语言的平均值,最终得到一个某种程度上的跨语言向量,这两篇论文都表明可以用于跨语言句子检索


    此外,似乎一千个平行句子(例如,在两种语言中)足以学习两种语言之间的投影。请注意,他们没有使用
    [CLS]
    向量,但他们的意思是将各个子词的向量集合起来。

    很有趣。在你看来,对于这两种方法,有多少数据就足够了?正如Jindřich提到的,每种语言1000个句子对可能就足够了,但如果它真的有效,你真的需要测试它。非常有趣!语言手段公布了吗?我不这么认为,但自己做应该不会太难。