KerasEmbedding 层不执行任何矩阵乘法,而只是:
1.创建一个 (vocabulary_size)x(embedding_dimension) 维度的权重矩阵
2。索引这个权重矩阵
查看源代码以了解类的作用总是很有用的。在这种情况下,我们将看一下class Embedding,它继承自名为Layer 的基础层class。
(1) - 创建一个 (vocabulary_size)x(embedding_dimension) 维度的权重矩阵:
这发生在Embedding 的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) - 索引这个权重矩阵
这发生在Embedding 的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 的确切作用是根据应该是正整数列表的 inputs 索引权重矩阵 self.embeddings(参见上面的 build 函数)。
可以检索这些列表,例如,如果您将文本/单词输入传递给 Keras 的 one_hot 函数,该函数将文本编码为大小为 n 的单词索引列表(这不是一种热编码 - 另请参阅更多信息示例:https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/)。
因此,仅此而已。没有矩阵乘法。
相反,KerasEmbedding 层之所以有用,只是因为它避免了执行矩阵乘法,因此它节省了一些计算资源。
否则,您可以只使用Keras Dense 层(在对输入数据进行编码之后)来获得可训练权重矩阵((vocabulary_size)x(embedding_dimension) 维度) 然后简单地做乘法得到与Embedding层的输出完全相同的输出。