Объясните на примере: как работает встраивание слоев в keras

Я не понимаю слой встраивания Keras. Хотя есть много статей, объясняющих это, я все еще в замешательстве. Например, приведенный ниже код взят из анализа тональности imdb:

top_words = 5000
max_review_length = 500
embedding_vecor_length = 32    

model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(LSTM(100))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
model.fit(X_train, y_train, nb_epoch=3, batch_size=64)

В этом коде, что именно делает слой внедрения? Каким будет результат встраивания слоя? Было бы неплохо, если бы кто-нибудь мог объяснить это на некоторых примерах!


person user1670773    schedule 12.08.2017    source источник
comment
Возможный дубликат Что такое встраивание в Keras?   -  person DJK    schedule 13.08.2017
comment
Это объясняется с помощью theano, но было бы легче понять пример в keras.   -  person user1670773    schedule 14.08.2017
comment
Математика для слоев следует тем же принципам.   -  person DJK    schedule 14.08.2017
comment
Вы можете взглянуть на мой ответ: stackoverflow.com/a/53101566/9024698.   -  person Outcast    schedule 30.11.2018


Ответы (2)


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

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

texts = ['This is a text','This is not a text']

Сначала мы превращаем эти предложения в вектор целых чисел, где каждое слово — это число, присвоенное слову в словаре, а порядок вектора создает последовательность слов.

from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences 
from keras.utils import to_categorical

max_review_length = 6 #maximum length of the sentence
embedding_vecor_length = 3
top_words = 10

#num_words is tne number of unique words in the sequence, if there's more top count words are taken
tokenizer = Tokenizer(top_words)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
word_index = tokenizer.word_index
input_dim = len(word_index) + 1
print('Found %s unique tokens.' % len(word_index))

#max_review_length is the maximum length of the input text so that we can create vector [... 0,0,1,3,50] where 1,3,50 are individual words
data = pad_sequences(sequences, max_review_length)

print('Shape of data tensor:', data.shape)
print(data)

[Out:] 
'This is a text' --> [0 0 1 2 3 4]
'This is not a text' --> [0 1 2 5 3 4]

Теперь вы можете ввести их в слой внедрения

from keras.models import Sequential
from keras.layers import Embedding

model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length,mask_zero=True))
model.compile(optimizer='adam', loss='categorical_crossentropy')
output_array = model.predict(data)

output_array содержит массив размера (2, 6, 3): 2 входных отзыва или предложения в моем случае, 6 — максимальное количество слов в каждом отзыве (max_review_length) и 3 — embedding_vecor_length. Например.

array([[[-0.01494285, -0.007915  ,  0.01764857],
    [-0.01494285, -0.007915  ,  0.01764857],
    [-0.03019481, -0.02910612,  0.03518577],
    [-0.0046863 ,  0.04763055, -0.02629668],
    [ 0.02297204,  0.02146662,  0.03114786],
    [ 0.01634104,  0.02296363, -0.02348827]],

   [[-0.01494285, -0.007915  ,  0.01764857],
    [-0.03019481, -0.02910612,  0.03518577],
    [-0.0046863 ,  0.04763055, -0.02629668],
    [-0.01736645, -0.03719328,  0.02757809],
    [ 0.02297204,  0.02146662,  0.03114786],
    [ 0.01634104,  0.02296363, -0.02348827]]], dtype=float32)

В вашем случае у вас есть список из 5000 слов, который может создать обзор максимум 500 слов (больше будет обрезано) и превратить каждое из этих 500 слов в вектор размера 32.

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

model.layers[0].get_weights()

В приведенном ниже случае top_words было 10, поэтому у нас есть сопоставление 10 слов, и вы можете видеть, что сопоставление для 0, 1, 2, 3, 4 и 5 равно выходному_массиву выше.

[array([[-0.01494285, -0.007915  ,  0.01764857],
    [-0.03019481, -0.02910612,  0.03518577],
    [-0.0046863 ,  0.04763055, -0.02629668],
    [ 0.02297204,  0.02146662,  0.03114786],
    [ 0.01634104,  0.02296363, -0.02348827],
    [-0.01736645, -0.03719328,  0.02757809],
    [ 0.0100757 , -0.03956784,  0.03794377],
    [-0.02672029, -0.00879055, -0.039394  ],
    [-0.00949502, -0.02805768, -0.04179233],
    [ 0.0180716 ,  0.03622523,  0.02232374]], dtype=float32)]

Как указано в https://stats.stackexchange.com/questions/270546/how-does-keras-embedding-layer-work эти векторы инициируются как случайные и оптимизируются оптимизаторами сетевого слова, как и любой другой параметр сети.

person Vaasha    schedule 23.10.2017

Я согласен с предыдущим подробным ответом, но я хотел бы попытаться дать более интуитивное объяснение.

Чтобы понять, как работает слой Embedding, лучше просто сделать шаг назад и понять, зачем нам вообще нужен Embedding.

Обычно модели машинного обучения принимают в качестве входных данных векторы (массив чисел), а при работе с текстом мы преобразуем строки в числа. Одним из самых простых способов сделать это является горячее кодирование, при котором вы обрабатываете каждую строку как категориальную переменную. Но первая проблема заключается в том, что если вы используете словарь (словарь) из 10000 слов, то однократное кодирование — это пустая трата места (памяти).

Кроме того, поскольку дискретные объекты сопоставляются либо с 0, либо с 1, сигнализирующими об определенной категории, горячее кодирование не может фиксировать какую-либо связь между словами. Таким образом, если вы знакомы с набором данных фильмов IMDB, однократное кодирование ничего, кроме бесполезного для анализа настроений. Потому что, если вы измеряете сходство с помощью косинусного расстояния, то сходство всегда равно нулю для каждого сравнения между разными индексами.

Это должно помочь нам найти метод, где --

  • Подобные слова могут иметь аналогичную кодировку,
  • Для представления категориальных переменных у нас будет меньше чисел, чем количество уникальных категорий.

Входит во встраивание..

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

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

Прежде чем строить модель с последовательностью, вы уже использовали Keras Tokenizer API, а входные данные уже закодированы целым числом. Теперь, как только вы укажете количество измерений встраивания (например, 16, 32, 64 и т. д.), количество столбцов таблицы поиска будет определяться этим.

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

Вот как я думаю о встраивании слоя в Keras. Надеюсь, это пролило немного больше света, и я подумал, что это может быть хорошим дополнением к ответу, опубликованному @Vaasha.

Ссылка: учебник по внедрению TensorFlow Word.

person Suvo    schedule 30.10.2019