Вложение слоя в Keras: Vocab Размер +1 - PullRequest
1 голос
/ 19 февраля 2020

Из ряда примеров, которые я видел, когда мы используем text_tokenizer от keras, при указании размера входа для входного слоя, мы используем размер Vocab +1. Это, естественно, дает пространство для вложения с +1 «строк».

Например, я подгоняю простую модель для оценки векторов внедрения для словаря размера 3 = I like turtles. Пространство вложения имеет длину 5 на слово в нашем словаре.

Веса вложения:

0.01209533  0.034303080 -0.04666784 0.02803965  -0.03691160
-0.01302978 -0.030584216    -0.02506201 0.04771456  0.01906699
0.02800793  0.042204402 0.05223191  -0.01184921 0.02000498
0.02692273  -0.008792922    0.01560913  -0.02783649 0.02692282

Мой вопрос: я предполагаю, что первой "строкой" в нашей матрице является 0- на основе вектора, так что строки 2, 3 и 4 будут связаны с «I», «like» и «turtle» соответственно.

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

1 Ответ

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

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

Кроме того, этот токенизатор немного беспорядок , Вы увидите, что я имею в виду ниже.

Поскольку токенизатор будет фильтровать слова (предполагая нетривиальный словарь), я не хочу предполагать, что слова хранятся в том порядке, в котором они находятся , Поэтому здесь я программно определяю словарь, используя word_index. Затем я явно проверяю, какие слова маркируются после фильтрации для наиболее часто используемых слов. (Word_index запоминает все слов; т.е. предварительно отфильтрованные значения.)

import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
corpus = 'I like turtles'
num_words = len(corpus.split())
oov = 'OOV'
tokenizer = Tokenizer(num_words=num_words + 2, oov_token=oov)
tokenizer.fit_on_texts(corpus.split())
print(f'word_index: {tokenizer.word_index}')
print(f'vocabulary: {tokenizer.word_index.keys()}')
text = [key for key in tokenizer.word_index.keys()]
print(f'keys: {text}: {tokenizer.texts_to_sequences(text)}')

text = 'I like turtles'.split()
print(f'{text}: {tokenizer.texts_to_sequences(text)}')

text = 'I like marshmallows'.split() 
print(f'{text}: {tokenizer.texts_to_sequences(text)}')

Это приводит к следующему выводу:

word_index: {'OOV': 1, 'i': 2, 'like': 3, 'turtles': 4}
vocabulary: dict_keys(['OOV', 'i', 'like', 'turtles'])
keys: ['OOV', 'i', 'like', 'turtles']: [[1], [2], [3], [4]]
['I', 'like', 'turtles']: [[2], [3], [4]]
['I', 'like', 'marshmallows']: [[2], [3], [1]]

Однако, если вы укажете oov_token результат выглядит следующим образом:

{'OOV': 1, 'i': 2, 'like': 3, 'turtles': 4}

Обратите внимание, как я должен был указать num_words=num_words + 2 вместо ожидаемого «+1». Это потому, что мы явно определяем токен OOV, который добавляется в словарь, что немного глупо.

Если вы задаете токен OOV и устанавливаете num_words=num_words + 1 (как задокументировано), тогда ' Я люблю черепах »получает ту же кодировку, что и« Я люблю зефир ». Также орехи.

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

Пожалуйста, дайте нам знать, что вы найдете. :)

(Подробнее о безумии читайте это сообщение StackOverflow.)

...