Что такое встраивание в Керас?


97

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

keras 

7
Это таблица поиска, которую можно обучить
— gokul_uf

1
Он просто создает и индексирует весовую матрицу; см. мой подробный ответ ниже ( stackoverflow.com/a/53101566/9024698 ).
— Outcast

3
Хотя в ответах, получивших наибольшее количество голосов, говорится, что это умножение матриц, исходный код и другие ответы показывают, что на самом деле это просто обучаемая матрица. Входные слова просто выбирают соответствующую строку в этой матрице.
— Daniel Möller

Ответы:


67

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

Веса слоя Embedding имеют форму (vocabulary_size, embedding_dimension). Для каждой обучающей выборки входными данными являются целые числа, которые представляют определенные слова. Целые числа находятся в диапазоне размера словаря. Слой внедрения преобразует каждое целое число i в i-ю строку матрицы весов внедрения.

Чтобы быстро сделать это как матричное умножение, входные целые числа сохраняются не как список целых чисел, а как горячая матрица. Следовательно, входная форма (nb_words, dictionary_size) с одним ненулевым значением в строке. Если вы умножите это на веса вложения, вы получите результат в форме

(nb_words, vocab_size) x (vocab_size, embedding_dim) = (nb_words, embedding_dim)

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


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

3
Вот хороший пост о встраивании слов и их преимуществах.
— sietschie

3
В случае, который я представил, каждый обучающий ввод представляет собой набор слов (может быть предложением). Каждое слово представлено как горячий вектор и вложено в плотный вектор. Недостатком этого подхода является то, что, поскольку ввод должен быть постоянной длины, все ваши предложения должны содержать одинаковое количество слов. Альтернативой могут быть векторы абзацев , которые могут встраивать предложения, абзацы или даже документы в векторы.
— Лоррит 02

4
Слой встраивания просто оптимизирует свои веса, чтобы минимизировать потери. Может быть, это означает, что он будет учитывать семантическое сходство, а может, и нет. Мало ли с нейронными сетями. Если вы хотите быть уверенным, что встраивание следует определенной формуле (например, w2v), используйте эту формулу. Если у вас достаточно данных, вы можете использовать слой «Встраивание» и обучить вложения. Просто попробуйте и проверьте, нравятся ли вам результаты.
— Lorrit 08

2
Я согласен с user36624 (ответ ниже). Это НЕ простое матричное умножение.
— Даниэль Мёллер

21

Keras EmbeddingСлой не выполняет никакого умножения матриц , но это только:

1. создает весовую матрицу размеров (Dictionary_size) x (embedding_dimension)

2. индексирует эту весовую матрицу


Всегда полезно взглянуть на исходный код, чтобы понять, что делает класс. В этом случае мы рассмотрим class встраивание, которое наследуется от базового слоя, classназываемого Layer .

(1) - Создание весовой матрицы размеров (Dictionary_size) x (embedding_dimension) :

Это происходит при buildфункции встраивания :

def build(self, input_shape):
    self.embeddings = self.add_weight(
        shape=(self.input_dim, self.output_dim),
        initializer=self.embeddings_initializer,
        name='embeddings',
        regularizer=self.embeddings_regularizer,
        constraint=self.embeddings_constraint,
        dtype=self.dtype)
    self.built = True

Если вы посмотрите на базовый класс Layer, вы увидите, что приведенная add_weightвыше функция просто создает матрицу обучаемых весов (в данном случае размерности (vocabulary_size) x (embedding_dimension) ):

def add_weight(self,
               name,
               shape,
               dtype=None,
               initializer=None,
               regularizer=None,
               trainable=True,
               constraint=None):
    """Adds a weight variable to the layer.
    # Arguments
        name: String, the name for the weight variable.
        shape: The shape tuple of the weight.
        dtype: The dtype of the weight.
        initializer: An Initializer instance (callable).
        regularizer: An optional Regularizer instance.
        trainable: A boolean, whether the weight should
            be trained via backprop or not (assuming
            that the layer itself is also trainable).
        constraint: An optional Constraint instance.
    # Returns
        The created weight variable.
    """
    initializer = initializers.get(initializer)
    if dtype is None:
        dtype = K.floatx()
    weight = K.variable(initializer(shape),
                        dtype=dtype,
                        name=name,
                        constraint=constraint)
    if regularizer is not None:
        with K.name_scope('weight_regularizer'):
            self.add_loss(regularizer(weight))
    if trainable:
        self._trainable_weights.append(weight)
    else:
        self._non_trainable_weights.append(weight)
    return weight

(2) - Индексирование этой весовой матрицы

Это происходит при callфункции встраивания :

def call(self, inputs):
    if K.dtype(inputs) != 'int32':
        inputs = K.cast(inputs, 'int32')
    out = K.gather(self.embeddings, inputs)
    return out

Эта функция возвращает результат Embeddingслоя, который есть K.gather(self.embeddings, inputs). Что именно делает tf.keras.backend.gather, так это индексирует матрицу весов self.embeddings(см. buildФункцию выше) в соответствии со inputsсписками положительных целых чисел.

Эти списки можно получить, например, если вы передадите свои текстовые / словесные входные данные в функцию one_hot Keras, которая кодирует текст в список индексов слов размера n (это НЕ одна горячая кодировка - см. Также этот пример для получения дополнительной информации: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ ).


Поэтому все. Умножения матриц нет.

Напротив, этот Keras Embeddingслой полезен только потому, что именно он позволяет избежать умножения матриц и, следовательно, экономить некоторые вычислительные ресурсы.

В противном случае вы могли бы просто использовать Keras плотный слой (после того, как вы закодировали свои входные данные), чтобы получить матрицу обучаемых весов ( размеров (Dictionary_size) x (embedding_dimension) ), а затем просто выполнить умножение, чтобы получить результат, который будет точно то же самое с выводом Embeddingслоя.



4

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

def call(self, inputs):
    if K.dtype(inputs) != 'int32':
        inputs = K.cast(inputs, 'int32')
    out = K.gather(self.embeddings, inputs)
    return out

Он отображает каждое известное целое число nв inputsобучаемый вектор признаков W[n], размерность которого является так называемой длиной встроенного признака.


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

За исключением того, что нигде keras не выполняет это умножение. Он просто определяет «вложения = обучаемую матрицу» и использует входные индексы для сбора слов из матрицы.
— Даниэль Мёллер

Таким образом, это встраивание экономит много памяти, просто не создавая ни одной горячей версии входных данных.
— Даниэль Мёллер

1

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.