1

我想在 TensorFlow Hub嵌入上使用Universal Sentence Encoder 计算Word Mover 的距离。

我已经在spaCy 上尝试了 WMD-relax的示例,它从 spaCy 加载“en”模型,但我找不到另一种方法来提供其他嵌入。

gensim中,它似乎只接受load_word2vec_format文件(file.bin)或load文件(file.vec)。

据我所知,有人基于 pytorch 编写了一个用于令牌嵌入的 Bert,但它并未推广到 tf-hub 上的其他模型。

有没有其他方法可以将 tf-hub 上的预训练模型转换为 spaCy 格式或 word2vec 格式?

4

2 回答 2

0

是spacy中WMD的实现。您可以创建一个 WMD 对象并加载您自己的嵌入:

import numpy
from wmd import WMD
embeddings_numpy_array = # your array with word vectors
calc = WMD(embeddings_numpy_array, ...)

或者,如例所示,您可以创建自己的类:

import spacy
spacy_nlp = spacy.load('en_core_web_lg')

class SpacyEmbeddings(object):
    def __getitem__(self, item):
        return spacy_nlp.vocab[item].vector # here you can return your own vector instead

calc = WMD(SpacyEmbeddings(), documents)
...
...
calc.nearest_neighbors("some text")
...

于 2020-06-29T16:54:38.607 回答
0

你需要两种不同的东西。

首先告诉 SpaCy 为您的文档、跨度或标记使用外部向量。这可以通过设置 user_hooks: -user_hooks["vector"]用于文档向量 -user_span_hooks["vector"]用于跨度向量 -user_token_hooks["vector"]用于标记向量

鉴于您有一个函数可以从 TF Hub 检索 Doc/Span/Token 的向量(它们都具有属性text):

import spacy
import tensorflow_hub as hub


model = hub.load(TFHUB_URL)
def embed(element):
    # get the text
    text = element.text
    # then get your vector back. The signature is for batches/arrays
    results = model([text])
    # get the first element because we queried with just one text
    result = np.array(results)[0]
    return result

您可以编写以下管道组件,它告诉 spacy 如何检索文档、跨度和令牌的自定义嵌入:

def overwrite_vectors(doc):
    doc.user_hooks["vector"] = embed
    doc.user_span_hooks["vector"] = embed
    doc.user_token_hooks["vector"] = embed

# add this to your nlp pipeline to get it on every document
nlp = spacy.blank('en') # or any other Language
nlp.add_pipe(overwrite_vectors)

对于您与自定义距离相关的问题,还有一个用户挂钩:

def word_mover_similarity(a, b):
    vector_a = a.vector
    vector_b = b.vector
    # your distance score needs to be converted to a similarity score
    similarity = TODO_IMPLEMENT(vector_a, vector_b)
    return similarity

def overwrite_similarity(doc):
    doc.user_hooks["similarity"] = word_mover_similarity
    doc.user_span_hooks["similarity"] = word_mover_similarity
    doc.user_token_hooks["similarity"] = word_mover_similarity

# as before, add this to the pipeline
nlp.add_pipe(overwrite_similarity)

user_hooks我有一个以这种方式使用的 TF Hub 通用句子编码器的实现: https ://github.com/MartinoMensio/spacy-universal-sentence-encoder-tfhub

于 2020-04-22T14:00:47.273 回答