La Keras
Embedding
couche n'effectue aucune multiplication matricielle mais seulement:
1. crée une matrice de poids de (vocabulary_size) x (embedding_dimension) dimensions
2. indexe cette matrice de poids
Il est toujours utile de jeter un œil au code source pour comprendre ce que fait une classe. Dans ce cas, nous allons jeter un œil à l' class
incorporation qui hérite de la couche de base class
appelée Layer .
(1) - Création d'une matrice de poids de dimensions (vocabulary_size) x (embedding_dimension) :
Cela se produit au niveau de la build
fonction d' incorporation :
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 vous regardez la classe de base Layer, vous verrez que la fonction add_weight
ci-dessus crée simplement une matrice de poids entraînables (dans ce cas de dimensions (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) - Indexation de cette matrice de poids
Cela se produit au niveau de la call
fonction d' incorporation :
def call(self, inputs):
if K.dtype(inputs) != 'int32':
inputs = K.cast(inputs, 'int32')
out = K.gather(self.embeddings, inputs)
return out
Cette fonction renvoie la sortie de la Embedding
couche qui est K.gather(self.embeddings, inputs)
. Ce que fait exactement tf.keras.backend.gather est d'indexer la matrice de poids self.embeddings
(voir la build
fonction ci-dessus) en fonction de ce inputs
qui devrait être des listes d'entiers positifs.
Ces listes peuvent être récupérées par exemple si vous passez vos entrées texte / mots à la fonction one_hot de Keras qui encode un texte dans une liste d'index de mots de taille n (ce n'est PAS un encodage à chaud - voir aussi cet exemple pour plus d'informations: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ ).
Par conséquent, c'est tout. Il n'y a pas de multiplication matricielle.
Au contraire, la Keras
Embedding
couche n'est utile que parce qu'elle évite justement d'effectuer une multiplication matricielle et donc elle économise certaines ressources de calcul.
Sinon, vous pouvez simplement utiliser une couche Keras
dense (après avoir encodé vos données d'entrée) pour obtenir une matrice de poids pouvant être entraînés (de dimensions (vocabulary_size) x (embedding_dimension) ) et ensuite simplement faire la multiplication pour obtenir la sortie qui sera exactement la même chose avec la sortie de la Embedding
couche.