Как работает слой «Встраивание» Keras?

70

Необходимо понимать работу слоя «Встраивание» в библиотеке Keras. Я выполняю следующий код в Python

import numpy as np
from keras.models import Sequential
from keras.layers import Embedding

model = Sequential()
model.add(Embedding(5, 2, input_length=5))

input_array = np.random.randint(5, size=(1, 5))

model.compile('rmsprop', 'mse')
output_array = model.predict(input_array)

который дает следующий вывод

input_array = [[4 1 3 3 3]]
output_array = 
[[[ 0.03126476  0.00527241]
  [-0.02369716 -0.02856163]
  [ 0.0055749   0.01492429]
  [ 0.0055749   0.01492429]
  [ 0.0055749   0.01492429]]]

Я понимаю, что каждое значение в input_array отображается в 2 элемента вектора в output_array, поэтому вектор 1 X 4 дает 1 X 4 X 2 вектора. Но как рассчитываются сопоставленные значения?

Prashanth
источник
1
Может быть, хорошее начало: github.com/fchollet/keras/issues/3110 ?
фн
В этом блоге слово «вложение» с использованием слоя « Keras
Фаиль Гафаров

Ответы:

87

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

Наиболее распространенное применение этого слоя для обработки текста. Давайте посмотрим на простой пример. Наш тренировочный набор состоит только из двух фраз:

Надеюсь увидеть вас в ближайшее время

Рад видеть тебя снова

Таким образом, мы можем кодировать эти фразы, присваивая каждому слову уникальное целое число (например, по порядку появления в нашем учебном наборе данных). Тогда наши фразы можно переписать так:

[0, 1, 2, 3, 4]

[5, 1, 2, 3, 6]

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

Embedding(7, 2, input_length=5)

Первый аргумент (7) - это количество отдельных слов в обучающем наборе. Второй аргумент (2) указывает размер векторов вложения. Input_length argumet, конечно, определяет размер каждой входной последовательности.

После того, как сеть обучена, мы можем получить веса слоя внедрения, который в этом случае будет иметь размер (7, 2) и может рассматриваться как таблица, используемая для отображения целых чисел в векторы внедрения:

+------------+------------+
|   index    |  Embedding |
+------------+------------+
|     0      | [1.2, 3.1] |
|     1      | [0.1, 4.2] |
|     2      | [1.0, 3.1] |
|     3      | [0.3, 2.1] |
|     4      | [2.2, 1.4] |
|     5      | [0.7, 1.7] |
|     6      | [4.1, 2.0] |
+------------+------------+

Таким образом, согласно этим вложениям, наша вторая обучающая фраза будет представлена ​​как:

[[0.7, 1.7], [0.1, 4.2], [1.0, 3.1], [0.3, 2.1], [4.1, 2.0]]

Поначалу это может показаться нелогичным, но базовым механизмам автоматического дифференцирования (например, Tensorflow или Theano) удается оптимизировать эти векторы, связанные с каждым входным целым числом, точно так же, как и любой другой параметр вашей модели. Также интересно использовать вложения, изученные другими методами / людьми в разных доменах (см. Https://blog.keras.io/using-pre-trained-word-embeddings-in-a-keras-model.html ) как сделано в [1].

[1] Лопес-Санчес, Д., Эрреро, Дж. Р., Арриета, А.Г. и Корчадо, Дж.М. Прикладная разведка, 1-16.

Даниэль Лопес
источник
4
Спасибо за ответ. Только один запрос, как узнать вес слоя вложения. Как и для индекса 0, как получается [1.2, 3.1].
Prashanth
5
Содержимое таблицы, которая связывает индексы с векторами внедрения (то есть весами уровня внедрения), инициализируется случайным образом, а затем оптимизируется алгоритмом обучения (например, градиентным спуском).
Даниэль Лопес
3
Благодарю. Мне все еще немного неясно, против чего оптимизатор будет оптимизатором? Мол, что такое «правильный ответ», который позволяет ему вычислить функцию потерь? Или сказал по-другому, что это делает для прямого и обратного прохода?
bwest87
2
так что ... встраивание - это всего лишь подсеть общей архитектуры, которая сокращает любые закодированные входы в горячем виде до меньшего количества входов, ага ..
Майк Кэмпбелл
1
Поскольку слой встраивания является обучаемым, насколько он чувствителен к значениям, отсутствующим в обучающем наборе? Допустим, у меня есть десять слов в тренировочном наборе и еще пять в тестовом наборе - длина моего словаря составляет 15 ... но слой фактически никогда не активируется этими пятью "тестовыми" словами во время обучения. Не могли бы вы объяснить эту ситуацию?
Микалай
6

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

Я думаю, что этот пост также полезен для понимания, однако я действительно считаю, что ответ Даниэля удобен для восприятия. Но у меня также есть идея, лежащая в основе этого, в основном, путем понимания встраивания слов .

Я полагаю, что неточно сказать, что встраиваемые слои сокращают входные данные для горячего кодирования до меньшего количества входных данных. Ведь один горячий вектор - это одномерные данные, и он действительно превращается в 2 измерения в нашем случае. Лучше сказать, что

слой встраивания приходит с отношением входов в другом измерении

Будь то в 2-х измерениях или даже выше.

Я также обнаружил очень интересное сходство между встраиванием слов в анализ основных компонентов. Хотя название может показаться сложным, концепция проста. Что делает PCA, так это определяет набор данных на основе некоторых общих правил (так называемых основных компонентов). Так что это похоже на наличие данных, и вы хотите их описать, но используя только 2 компонента. Что в этом смысле очень похоже на вложение слов. Они оба выполняют одинаковую работу в разных контекстах. Вы можете узнать больше здесь . Я надеюсь, что понимание PCA поможет понять встраивание слоев по аналогии.

Чтобы подвести итог, ответ на оригинальный вопрос поста, который « как он вычисляет значение? » Будет:

  • По сути, наша нейронная сеть фиксирует основную структуру входных данных (наших предложений) и переводит связь между словами в нашем словаре в более высокое измерение (скажем, 2) путем оптимизации.
  • Более глубокое понимание скажет, что частота каждого слова появляется вместе с другим словом из наших словарных влияний (при очень наивном подходе мы можем вычислить его вручную)
  • Вышеупомянутая частота может быть одной из многих базовых структур, которые NN может захватывать
  • Вы можете найти интуицию на ссылке на YouTube, объясняющей вложение слова
Новин Шахруди
источник
7
Хорошая точка зрения. Тем не менее, я думаю, что стоит отметить, что хотя методы встраивания слов, такие как word2vec, пытаются уловить полное значение слов в результирующем встраивании, уровень встраивания в контролируемой сети может не учиться такому семантически богатому и общему представлению. Например, если ваша сеть обучена выполнять классификацию настроений, она, вероятно, будет просто группировать / кластеризовывать слова во вложении в соответствии с их «эмоциональной» нагрузкой. Тем не менее, основываясь на моем опыте, часто полезно инициализировать слой внедрения с весами, изученными word2vec на большом корпусе.
Даниэль Лопес
2
Один горячий вектор - это не одномерные данные. Его размер - это размер словаря.
Бину Ясим
2
@BinuJasim ты прав. В одной горячие векторы , представляющие словарный запас не является одномерным данных. Но информация, которую она представляет, действительно является одномерной, и каждый объект в словаре является одномерными данными. Это правда, что у нас есть n * w (n = размер словаря, w = количество битов) элементов, но каждое двоичное значение представляет вектор, который снова является одномерным входом.
Новин Шахруди
@NovinShahroudi Бриллиант, спасибо за объяснение.
Беньямин Джафари