Les documents pour un Embedding Layer dans Keras disent:
Transforme les entiers positifs (indices) en vecteurs denses de taille fixe. par exemple.
[[4], [20]]
->[[0.25, 0.1], [0.6, -0.2]]
Je crois que cela pourrait également être réalisé en codant les entrées en tant que vecteurs un-chaud de longueur vocabulary_size
, et en les introduisant dans un Dense Layer .
Un calque d'intégration est-il simplement une commodité pour ce processus en deux étapes, ou quelque chose de plus sophistiqué se passe-t-il sous le capot?
Mathématiquement, la différence est la suivante:
Une couche d'intégration exécute l'opération select. En keras, cette couche équivaut à:
K.gather(self.embeddings, inputs) # just one matrix
Une couche dense effectue produit scalaire opération, plus une activation facultative:
outputs = matmul(inputs, self.kernel) # a kernel matrix
outputs = bias_add(outputs, self.bias) # a bias vector
return self.activation(outputs) # an activation function
Vous pouvez émuler une couche d'intégration avec une couche entièrement connectée via un codage à chaud, mais tout le point de l'intégration dense est de éviter une représentation à chaud. En PNL, la taille du vocabulaire Word peut être de l'ordre de 100k (parfois même un million). En plus de cela, il est souvent nécessaire de traiter les séquences de mots dans un lot. Le traitement du lot de séquences d'indices Word serait beaucoup plus efficace que le lot de séquences de vecteurs à un seul point. De plus, l'opération gather
elle-même est plus rapide que le produit scalaire matriciel, à la fois en avant et en arrière.
ne couche d'intégration est plus rapide, car c'est essentiellement l'équivalent d'une couche dense qui fait des hypothèses simplificatrices.
Imaginez une couche Word-to-embedding avec ces poids:
w = [[0.1, 0.2, 0.3, 0.4],
[0.5, 0.6, 0.7, 0.8],
[0.9, 0.0, 0.1, 0.2]]
Une couche Dense
les traitera comme poids réels avec lesquels effectuer la multiplication matricielle. Une couche d'intégration traitera simplement ces poids comme ne liste de vecteurs, chaque vecteur représentant un mot; le 0ème mot du vocabulaire est w[0]
, 1er est w[1]
, etc.
Pour un exemple, utilisez les poids ci-dessus et cette phrase:
[0, 2, 1, 2]
Un réseau naïf basé sur Dense
doit convertir cette phrase en un codage à chaud
[[1, 0, 0],
[0, 0, 1],
[0, 1, 0],
[0, 0, 1]]
puis faites une multiplication matricielle
[[1 * 0.1 + 0 * 0.5 + 0 * 0.9, 1 * 0.2 + 0 * 0.6 + 0 * 0.0, 1 * 0.3 + 0 * 0.7 + 0 * 0.1, 1 * 0.4 + 0 * 0.8 + 0 * 0.2],
[0 * 0.1 + 0 * 0.5 + 1 * 0.9, 0 * 0.2 + 0 * 0.6 + 1 * 0.0, 0 * 0.3 + 0 * 0.7 + 1 * 0.1, 0 * 0.4 + 0 * 0.8 + 1 * 0.2],
[0 * 0.1 + 1 * 0.5 + 0 * 0.9, 0 * 0.2 + 1 * 0.6 + 0 * 0.0, 0 * 0.3 + 1 * 0.7 + 0 * 0.1, 0 * 0.4 + 1 * 0.8 + 0 * 0.2],
[0 * 0.1 + 0 * 0.5 + 1 * 0.9, 0 * 0.2 + 0 * 0.6 + 1 * 0.0, 0 * 0.3 + 0 * 0.7 + 1 * 0.1, 0 * 0.4 + 0 * 0.8 + 1 * 0.2]]
=
[[0.1, 0.2, 0.3, 0.4],
[0.9, 0.0, 0.1, 0.2],
[0.5, 0.6, 0.7, 0.8],
[0.9, 0.0, 0.1, 0.2]]
Cependant, un calque Embedding
regarde simplement [0, 2, 1, 2]
et prend les poids de la couche aux indices zéro, deux, un et deux pour obtenir immédiatement
[w[0],
w[2],
w[1],
w[2]]
=
[[0.1, 0.2, 0.3, 0.4],
[0.9, 0.0, 0.1, 0.2],
[0.5, 0.6, 0.7, 0.8],
[0.9, 0.0, 0.1, 0.2]]
C'est donc le même résultat, qui vient d'être obtenu de manière plus rapide, espérons-le.
La couche Embedding
a des limitations:
Cependant, aucune de ces limitations ne devrait avoir d'importance si vous voulez simplement convertir un Word encodé en entier en une intégration.