La Keras
Embedding
capa no está realizando ninguna multiplicación de matrices, pero solo:
1. crea una matriz de peso de (vocabulary_size) x (embedding_dimension) dimensiones
2. indexa esta matriz de ponderaciones
Siempre es útil echar un vistazo al código fuente para comprender lo que hace una clase. En este caso, veremos la class
incrustación que hereda de la capa base class
llamada Capa .
(1) - Creando una matriz de peso de (vocabulary_size) x (embedding_dimension) dimensiones:
Esto ocurre en la build
función de incrustación :
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
Si echa un vistazo a la capa de clase base , verá que la función add_weight
anterior simplemente crea una matriz de pesos entrenables (en este caso de (vocabulary_size) x (embedding_dimension) dimensiones):
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) - Indexación de esta matriz de ponderaciones
Esto ocurre en la call
función de incrustación :
def call(self, inputs):
if K.dtype(inputs) != 'int32':
inputs = K.cast(inputs, 'int32')
out = K.gather(self.embeddings, inputs)
return out
Esta función devuelve la salida de la Embedding
capa que es K.gather(self.embeddings, inputs)
. Lo que tf.keras.backend.gather hace exactamente es indexar la matriz de ponderaciones self.embeddings
(ver la build
función anterior) de acuerdo con las inputs
que deberían ser listas de enteros positivos.
Estas listas se pueden recuperar, por ejemplo, si pasa sus entradas de texto / palabras a la función one_hot de Keras, que codifica un texto en una lista de índices de palabras de tamaño n (esta NO es una codificación activa; consulte también este ejemplo para obtener más información: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ ).
Por tanto, eso es todo. No hay multiplicación de matrices.
Por el contrario, la Keras
Embedding
capa solo es útil porque evita exactamente realizar una multiplicación de matrices y, por lo tanto, economiza algunos recursos computacionales.
De lo contrario, podría usar una capa Keras
Densa (después de haber codificado sus datos de entrada) para obtener una matriz de pesos entrenables (de (vocabulary_size) x (embedding_dimension) dimensiones) y luego simplemente hacer la multiplicación para obtener el resultado que será exactamente lo mismo con la salida de la Embedding
capa.