Keras文档尚不清楚这到底是什么。我知道我们可以使用它来将输入要素空间压缩为较小的空间。但是,从神经设计的角度来看,这是怎么做的呢?它是自动编码器吗,RBM?
Keras文档尚不清楚这到底是什么。我知道我们可以使用它来将输入要素空间压缩为较小的空间。但是,从神经设计的角度来看,这是怎么做的呢?它是自动编码器吗,RBM?
Answers:
据我所知,Embedding层是一个简单的矩阵乘法,可将单词转换为相应的单词嵌入。
嵌入层的权重的形状为(vocabulary_size,embedding_dimension)。对于每个训练样本,其输入都是整数,表示某些单词。整数在词汇量范围内。嵌入层将每个整数i转换为嵌入权重矩阵的第i行。
为了快速地将其作为矩阵乘法,输入整数不存储为整数列表,而是存储为单热矩阵。因此,输入形状为(nb_words,vocabulary_size),每行一个非零值。如果将其乘以嵌入权重,则会得到形状为
(nb_words, vocab_size) x (vocab_size, embedding_dim) = (nb_words, embedding_dim)
因此,通过简单的矩阵乘法,您可以将样本中的所有单词转换为相应的单词嵌入。
该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
此函数返回的输出Embedding
层K.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
图层的输出相同。
为了更好地理解任何功能,有一个很好的习惯来查看源代码。这是用于嵌入的, 因此基本上是一个可训练的查找表。
在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
层是确实是一个矩阵乘法。
用简单的话说(从功能的角度看),它是一个单编码器和完全连接的层。图层权重是可训练的。