Использование предварительно обученных вложений слов в модель керас? - PullRequest
3 голосов
/ 04 июля 2019

Я следовал этому github коду от команды keras о том, как использовать предварительно обученные вложения слов.Я был в состоянии понять большую часть этого, но у меня есть сомнения относительно размеров вектора.Я надеялся, что кто-нибудь сможет мне помочь.

Сначала мы определим Tokenizer(num_words=MAX_NUM_WORDS)

В соответствии с документами keras для Tokenizer() num_words только аргументрассмотрим MAX_NUM_WORDS - 1, поэтому, если MAX_NUM_WORDS=20000 у меня будет около 19999 слов.

num_words : максимальное количество слов для хранения, основанное на частоте слов.Будут сохранены только самые распространенные слова num_words-1.

Далее в коде мы подготовим Embedding Matrix на основе векторов перчаток.При этом мы рассматриваем матрицу размера (20001, 100) np.zeros((MAX_NUM_WORDS+1, 100)).Я не мог понять, почему мы рассматриваем матрицу из 20001, если в нашем словаре есть только 19999 слов.

Также тогда мы передаем num_words слою Embedding.В соответствии с документами слоя «Встраивание» для аргумента input_dim говорится:

input_dim : int> 0. Размер словаря, то есть максимальный целочисленный индекс + 1.

embedding_layer = Embedding(input_dim=num_words,
                            output_dim=EMBEDDING_DIM,
                            embeddings_initializer=Constant(embedding_matrix),
                            input_length=MAX_SEQUENCE_LENGTH,
trainable=False)

Здесь размер нашего словаря будет 19999 в соответствии с Tokenizer() функцией, верно?Так почему мы передаем 20001 как input_dim

Вот небольшой фрагмент кода, взятого из этой ссылки на github.

MAX_NUM_WORDS = 20000
MAX_SEQUENCE_LENGTH = 1000
EMBEDDING_DIR = 100

tokenizer = Tokenizer(num_words=MAX_NUM_WORDS)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)

data = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH)

# prepare embedding matrix
num_words = MAX_NUM_WORDS + 1
embedding_matrix = np.zeros((num_words, EMBEDDING_DIM))
for word, i in word_index.items():
    if i > MAX_NUM_WORDS:
        continue
    embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None:
        embedding_matrix[i] = embedding_vector

embedding_layer = Embedding(num_words,
                            EMBEDDING_DIM,
                            embeddings_initializer=Constant(embedding_matrix),
                            input_length=MAX_SEQUENCE_LENGTH,
                            trainable=False)

Ответы [ 2 ]

1 голос
/ 05 июля 2019

Я думаю, что ваши сомнения верны.Изменение было внесено в этого коммита кода для сохранения слова с index = MAX_NUM_WORDS.До этого был коммит на Tokenizer, чтобы заставить его хранить num_words слов вместо num_words - 1 слов.Но это изменение Tokenizer было отменено впоследствии.Поэтому я думаю, что автор примера обновления мог предположить, что Tokenizer сохранил num_words слов, когда обновление было зафиксировано.

1 голос
/ 04 июля 2019

Для встраивания input dim (num_words в приведенном ниже коде) - это размер словаря. Например, если ваши данные целочисленно закодированы в значения от 0 до 10, тогда размер словаря будет 11 слов. Именно поэтому 1 добавляется к минимуму len (word_index) и MAX_NUM_WORDS.

Матрица вложения будет иметь размер словарного размера и длину вектора

embedding_layer = Embedding(num_words,
                            EMBEDDING_DIM,
                            embeddings_initializer=Constant(embedding_matrix),
                            input_length=MAX_SEQUENCE_LENGTH,
                            trainable=False)

num_words = min(MAX_NUM_WORDS, len(word_index)) + 1

Для объяснения этого создали простой токенизатор.

t  = Tokenizer(num_words=5)
fit_text = ["The earth is an awesome place live"]
t.fit_on_texts(fit_text)
word_index = t.word_index
​
print('word_index : ',word_index)
print('len word_index : ',len(t.word_index))
word_index :  {'the': 1, 'earth': 2, 'is': 3, 'an': 4, 'awesome': 5, 'place': 6, 'live': 7}
len word_index :  7

В приведенном ниже примере вы используете словарь размера 4 только потому, что индексирование токенизатора начинается с 1.

embedding_matrix = np.zeros((5, 10))
embedding_matrix
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])

for word, i in word_index.items():
    if i < 5:       
        embedding_matrix[i] = [0,1,0,0,0,0,0,0,0,0]

print (embedding_matrix)
[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]]

В приведенном ниже случае вам нужно добавить 1 (5 + 1), чтобы покрыть словарь размера 5, чтобы покрыть для индекса 0

embedding_matrix = np.zeros((6, 10))
for word, i in word_index.items():
    if i < 6:       
        embedding_matrix[i] = [0,1,0,0,0,0,0,0,0,0]

print (embedding_matrix)

[[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...