我有一个拥抱脸部的模型,想用它来进行单词比较。起初我想对感兴趣的单词进行一系列相似度计算,但很快我发现这个问题会随着单词数量的增加而呈指数级增长。
我想到的一个解决方案是绘制一个跳图,其中所有单词都在二维平面上生成,然后可以简单地在坐标上执行聚类以查找相似的单词。这里的问题是,这需要一个 bert 模型和一个可以映射的低嵌入层。
由于我有一个预训练的模型,我不知道是否可以用它创建一个skip gram。我希望计算嵌入,并通过使用转换,将嵌入转换为我可以自己绘制的坐标。我虽然不知道这是否可能或合理
我尝试使用下面的代码来做到这一点
from sklearn.manifold import TSNE
from transformers import AutoModel, AutoTokenizer
# target word
word = ["Slartibartfast"]
# model setup
model = 'Alibaba-NLP/gte-multilingual-base'
tokenizer = AutoTokenizer.from_pretrained(model)
auto_model = AutoModel.from_pretrained(model, trust_remote_code=True)
# embbed and calculate
batch_dict = self.tokenizer(text_list, max_length=8192, padding=True, truncation=True, return_tensors='pt')
result = auto_model(**batch_dict)
embeddings = outputs.last_hidden_state[:, 0][:768]
# transform to coordinates
clayer = TSNE(n_components=3, learning_rate='auto', init='random', perplexity=50)
embedding_numpy = embeddings.detach().numpy()
clayer.fit_transform(embedding_numpy) # crashes here saying perplexity must be less than n_samples
经过更多阅读后,我注意到不可能按照我希望的方式使用 TSNE,因为 TSNE 生成的维度仅代表训练数据。进一步拟合新数据或转换不在训练集中的数据将导致输出不在相似范围内,因此不可比较。
我找到了 TSNE 的替代品,称为 umap。 umap 也用于降维,但它可以多次拟合,并且数据可以沿着相同的范围进行转换。
我将探索 umap 并看看它是否能满足我的需要。