Использование раздражения с Torchtext для поиска ближайшего соседа - PullRequest
0 голосов
/ 15 апреля 2020

Я использую Torchtext для некоторых задач НЛП, в частности, для встроенных вложений.

Я хочу иметь возможность выполнять поиск в обратном векторе: создать вектор с шумом, найти ближайший вектор затем верните слово, которое «ближе всего» к шумному вектору.

Из torchtext docs , вот как прикрепить вложения к встроенному набору данных:

from torchtext.vocab import GloVe
from torchtext import data

embedding = GloVe(name='6B', dim=100)

# Set up fields
TEXT = data.Field(lower=True, include_lengths=True, batch_first=True)
LABEL = data.Field(sequential=False, is_target=True)

# make splits for data
train, test = datasets.IMDB.splits(TEXT, LABEL)

# build the vocabulary
TEXT.build_vocab(train, vectors=embedding, max_size=100000)
LABEL.build_vocab(train)

# Get an example vector
embedding.get_vecs_by_tokens("germany")

Затем мы можем построить индекс раздражения:

from annoy import AnnoyIndex

num_trees = 50

ann_index = AnnoyIndex(embedding_dims, 'angular')

# Iterate through each vector in the embedding and add it to the index
for vector_num, vector in enumerate(TEXT.vocab.vectors):
    ann_index.add_item(vector_num, vector) # Here's the catch: will vector_num correspond to torchtext.vocab.Vocab.itos?

ann_index.build(num_trees)

Затем скажите, что я хочу получить слово, используя вектор с шумом:

# Get an existing vector
original_vec = embedding.get_vecs_by_tokens("germany")
# Add some noise to it
noise = generate_noise_vector(ndims=100)
noisy_vector = original_vec + noise
# Get the vector closest to the noisy vector
closest_item_idx = ann_index.get_nns_by_vector(noisy_vector, 1)[0]
# Get word from noisy item
noisy_word = TEXT.vocab.itos[closest_item_idx]

Мой вопрос последние две строки выше: ann_index был построен с использованием enumerate над объектом embedding, который является тензором Факела.

Объект [vocab][2] имеет свой собственный список itos, который дал index возвращает слово.

У меня такой вопрос: могу ли я быть уверен, что порядок, в котором слова появляются в списке itos, совпадает с порядком в TEXT.vocab.vectors? Как я могу сопоставить один индекс с другим?

1 Ответ

1 голос
/ 19 апреля 2020

Могу ли я быть уверен, что порядок, в котором слова появляются в списке itos, совпадает с порядком в TEXT.vocab.vectors?

Да.

Класс Field всегда будет создавать экземпляр объекта Vocab ( source ), и, поскольку вы передаете предварительно обученные векторы в TEXT.build_vocab, конструктор Vocab будет вызывать функция load_vectors.

if vectors is not None:
    self.load_vectors(vectors, unk_init=unk_init, cache=vectors_cache)

В load_vectors vectors заполнены путем перечисления слов в itos.

for i, token in enumerate(self.itos):
    start_dim = 0
    for v in vectors:
        end_dim = start_dim + v.dim
        self.vectors[i][start_dim:end_dim] = v[token.strip()]
        start_dim = end_dim
    assert(start_dim == tot_dim)

Следовательно, вы можете быть уверены, что itos и vectors будут иметь одинаковый порядок.

...