什么是Keras中的嵌入?


97

Keras文档尚不清楚这到底是什么。我知道我们可以使用它来将输入要素空间压缩为较小的空间。但是,从神经设计的角度来看,这是怎么做的呢?它是自动编码器吗,RBM?

keras 

7
这是一个可以训练的查询表
gokul_uf

1
它只是创建和索引一个权重矩阵。请参阅下面的详细答案(stackoverflow.com/a/53101566/9024698)。
弃儿

3
尽管投票得最多的答案是矩阵乘法,但是源代码和其他答案表明,它们实际上只是可训练的矩阵。输入的单词只是在此矩阵中选择相应的行。
DanielMöller18年

Answers:


67

据我所知,Embedding层是一个简单的矩阵乘法,可将单词转换为相应的单词嵌入。

嵌入层的权重的形状为(vocabulary_size,embedding_dimension)。对于每个训练样本,其输入都是整数,表示某些单词。整数在词汇量范围内。嵌入层将每个整数i转换为嵌入权重矩阵的第i行。

为了快速地将其作为矩阵乘法,输入整数不存储为整数列表,而是存储为单热矩阵。因此,输入形状为(nb_words,vocabulary_size),每行一个非零值。如果将其乘以嵌入权重,则会得到形状为

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

因此,通过简单的矩阵乘法,您可以将样本中的所有单词转换为相应的单词嵌入。


3
绝对有效(请参阅半监督序列学习)。您还可以使用自动编码器学习嵌入,然后将其用作嵌入层的初始化,以降低神经网络的复杂性(我假设您在嵌入层之后进行其他操作)。
罗里特'16

3
是一个关于单词嵌入及其优点的不错的博客文章。
sietschie

3
在我介绍的情况下,每个训练输入都是一组单词(可以是一个句子)。每个单词都表示为一个热向量,并嵌入到一个密集向量中。这种方法的缺点是,由于输入的长度必须恒定,因此所有句子的单词数必须相同。另一种选择是段落向量,它可以将句子,段落甚至文档嵌入向量中。
罗里特

4
嵌入层将仅优化其权重以最小化损失。也许这意味着它将考虑语义相似性,也许不会。您永远不会知道神经网络。如果要确保嵌入遵循某个公式(例如w2v),请使用该公式。如果您有足够的数据,则可能要使用“嵌入”层并训练嵌入。只需尝试一下,然后检查您是否喜欢结果。
罗里特

2
我同意user36624(以下答案)。它不是简单的矩阵乘法。
丹尼尔·莫勒(DanielMöller)'18年

21

Keras Embedding层不执行任何矩阵乘法,而仅执行以下操作:

1.创建一个(vocabulary_size)x(embedding_dimension)维度的权重矩阵

2.索引此权重矩阵


查看源代码以了解类的作用总是很有用的。在这种情况下,我们将看看class Embedding,它继承class自称为Layer的基础层。

(1)-创建一个(vocabulary_size)x(embedding_dimension)维度的权重矩阵:

这是在Embeddingbuild函数中发生的:

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)-索引此权重矩阵

这是在Embeddingcall函数中发生的:

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

此函数返回的输出EmbeddingK.gather(self.embeddings, inputs)。什么tf.keras.backend.gather究竟是指数权重矩阵self.embeddings(参见build根据上述功能),inputs这应该是正整数的列表。

例如,如果将文本/单词输入传递给Keras的one_hot函数,则该列表可以被检索,该函数将文本编码为大小为n的单词索引列表(这不是一种热编码-有关更多信息,请参见此示例:https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/)。


因此,仅此而已。没有矩阵乘法。

相反,Keras Embedding层仅是有用的,因为它恰好避免执行矩阵乘法,因此节省了一些计算资源。

否则,您可以仅使用Keras Dense层(在对输入数据进行编码之后)来获得可训练权重矩阵((vocabulary_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

它的作用是将每个已知整数映射ninputs向可训练特征向量W[n],其尺寸是所谓的嵌入式特征长度。


好吧,当您将一个单幅表示的向量集与一个矩阵相乘时,乘积将成为查找对象。所以Embedding确实是一个矩阵乘法。
yannis '18

除非喀拉拉邦无处执行此乘法。它仅定义“嵌入=可训练的矩阵”,并使用输入索引从矩阵中收集单词。
丹尼尔·莫勒(DanielMöller)'18年

因此,通过简单地不创建任何热输入版本,此嵌入可节省大量内存。
丹尼尔·莫勒(DanielMöller)'18年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.