fastText встраивает векторы предложений? - PullRequest
0 голосов
/ 14 января 2019

Я хотел понять, как создаются векторы fastText для предложений. Согласно этой проблеме 309 , векторы для предложений получаются путем усреднения векторов для слов.

Чтобы подтвердить это, я написал следующий скрипт:

import numpy as np
import fastText as ft

# Loading model for Finnish.
model = ft.load_model('cc.fi.300.bin')

# Getting word vectors for 'one' and 'two'.
one = model.get_word_vector('yksi')
two = model.get_word_vector('kaksi')

# Getting the sentence vector for the sentence "one two" in Finnish.
one_two = model.get_sentence_vector('yksi kaksi')
one_two_avg = (one + two) / 2

# Checking if the two approaches yield the same result.
is_equal = np.array_equal(one_two, one_two_avg)

# Printing the result.
print(is_equal)

# Result: FALSE

Но, похоже, полученные векторы не похожи.

Почему оба значения не одинаковы? Будет ли это связано с тем, как я усредняю ​​векторы? Или, может быть, что-то мне не хватает?

Ответы [ 2 ]

0 голосов
/ 24 мая 2019

Во-первых, вы пропустили ту часть, что get_sentence_vector - это не просто «среднее». Перед тем как FastText суммирует каждый вектор слова, каждый вектор делится с его нормой (нормой L2), а затем в процесс усреднения включаются только векторы, которые имеют положительное значение нормы L2.

Во-вторых, предложение всегда заканчивается EOS. Поэтому, если вы пытаетесь вычислить вручную, вам нужно поставить EOS, прежде чем вычислять среднее значение.

попробуйте это (я предполагаю, что норма L2 каждого слова положительна):


def l2_norm(x):
   return np.sqrt(np.sum(x**2))

def div_norm(x):
   norm_value = l2_norm(x)
   if norm_value > 0:
       return x * ( 1.0 / norm_value)
   else:
       return x

# Getting word vectors for 'one' and 'two'.
one = model.get_word_vector('yksi')
two = model.get_word_vector('kaksi')
eos = model.get_word_vector('\n')

# Getting the sentence vector for the sentence "one two" in Finnish.
one_two = model.get_sentence_vector('yksi kaksi')
one_two_avg = (div_norm(one) + div_norm(two) + div_norm(eos)) / 3

Вы можете увидеть исходный код здесь или посмотреть обсуждение здесь .

0 голосов
/ 14 января 2019

Возможно, вы столкнулись с проблемой математики с плавающей запятой - например, если одно добавление было сделано на процессоре, а другое на графическом процессоре, они могли бы отличаться.

Лучший способ проверить, выполняет ли он то, что вам нужно, - убедиться, что векторы почти одинаковы.

Возможно, вы захотите распечатать два вектора и вручную проверить их, или сделать точечный продукт one_two минус one_two_avg на себе (то есть на длине разницы между ними). ​​

...