Die Keras-Dokumentation ist nicht klar, was dies tatsächlich ist. Ich verstehe, dass wir dies verwenden können, um den Eingabe-Feature-Bereich in einen kleineren zu komprimieren. Aber wie geht das aus neuronaler Sicht? Ist es ein Autoenocder, RBM?
Die Keras-Dokumentation ist nicht klar, was dies tatsächlich ist. Ich verstehe, dass wir dies verwenden können, um den Eingabe-Feature-Bereich in einen kleineren zu komprimieren. Aber wie geht das aus neuronaler Sicht? Ist es ein Autoenocder, RBM?
Antworten:
Soweit ich weiß, ist die Einbettungsschicht eine einfache Matrixmultiplikation, die Wörter in ihre entsprechenden Worteinbettungen umwandelt.
Die Gewichte der Einbettungsebene haben die Form (Vokabulargröße, Einbettungsdimension). Für jedes Trainingsmuster sind seine Eingaben Ganzzahlen, die bestimmte Wörter darstellen. Die ganzen Zahlen liegen im Bereich der Vokabulargröße. Die Einbettungsschicht transformiert jede ganze Zahl i in die i-te Zeile der Einbettungsgewichtungsmatrix.
Um dies schnell als Matrixmultiplikation zu tun, werden die Eingabe-Ganzzahlen nicht als Liste von Ganzzahlen, sondern als One-Hot-Matrix gespeichert. Daher ist die Eingabeform (nb_words, vocabulary_size) mit einem Wert ungleich Null pro Zeile. Wenn Sie dies mit den Einbettungsgewichten multiplizieren, erhalten Sie die Ausgabe in der Form
(nb_words, vocab_size) x (vocab_size, embedding_dim) = (nb_words, embedding_dim)
Mit einer einfachen Matrixmultiplikation transformieren Sie also alle Wörter in einem Beispiel in die entsprechenden Worteinbettungen.
Die Keras
Embedding
Schicht führt keine Matrixmultiplikation durch, sondern nur:
1. Erstellt eine Gewichtsmatrix mit (Vokabulargröße) x (Einbettungsdimension) Dimensionen
2. indiziert diese Gewichtsmatrix
Es ist immer nützlich, einen Blick auf den Quellcode zu werfen, um zu verstehen, was eine Klasse tut. In diesem Fall sehen wir uns die class
Einbettung an, die von der Basisschicht class
namens Layer erbt .
(1) - Erstellen einer Gewichtsmatrix mit (Vokabulargröße) x (Einbettungsdimension) Dimensionen:
Dies geschieht bei der build
Funktion des Einbetten :
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
Wenn Sie sich die Basisklasse Layer ansehen, werden Sie sehen, dass die add_weight
obige Funktion einfach eine Matrix trainierbarer Gewichte erstellt (in diesem Fall von (vocabulary_size) x (embeddedding_dimension) Dimensionen):
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) - Indizierung dieser Gewichtsmatrix
Dies geschieht bei der call
Funktion des Einbetten :
def call(self, inputs):
if K.dtype(inputs) != 'int32':
inputs = K.cast(inputs, 'int32')
out = K.gather(self.embeddings, inputs)
return out
Diese Funktion gibt die Ausgabe der Embedding
Ebene zurück, die ist K.gather(self.embeddings, inputs)
. Was tf.keras.backend.gather genau tut, ist die Indizierung der Gewichtungsmatrix self.embeddings
(siehe build
Funktion oben) gemäß der inputs
Liste der positiven ganzen Zahlen.
Diese Listen können beispielsweise abgerufen werden, wenn Sie Ihre Text- / Worteingaben an die one_hot- Funktion von Keras übergeben, die einen Text in eine Liste von Wortindizes der Größe n codiert (dies ist KEINE Hot-Codierung - siehe auch dieses Beispiel für weitere Informationen: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ ).
Das ist also alles. Es gibt keine Matrixmultiplikation.
Im Gegenteil, die Keras
Embedding
Schicht ist nur deshalb nützlich, weil sie genau die Durchführung einer Matrixmultiplikation vermeidet und daher einige Rechenressourcen spart.
Andernfalls können Sie einfach eine Keras
dichte Ebene verwenden (nachdem Sie Ihre Eingabedaten codiert haben), um eine Matrix trainierbarer Gewichte (mit (Vokabulargröße) x (Einbettungsdimension) Dimensionen zu erhalten) und dann einfach die Multiplikation durchführen, um die Ausgabe zu erhalten, die genau ist das gleiche mit der Ausgabe der Embedding
Ebene.
Um eine Funktion besser zu verstehen, ist es eine gute Angewohnheit, sich den Quellcode anzusehen. Hier ist für das Einbetten. Im Grunde ist es also ein trainierbarer Nachschlagetisch.
In Keras ist die Embedding
Ebene KEINE einfache Matrixmultiplikationsschicht, sondern eine Nachschlagetabellenebene (siehe Aufruffunktion unten oder die ursprüngliche Definition ).
def call(self, inputs):
if K.dtype(inputs) != 'int32':
inputs = K.cast(inputs, 'int32')
out = K.gather(self.embeddings, inputs)
return out
Was sie tut , ist jeweils eine bekannte ganze Zahl ist zur Karte n
in inputs
zu einem trainierbar Merkmalsvektor W[n]
, deren Dimension ist die sogenannte eingebettete Feature - Länge.
Embedding
Schicht ist also tatsächlich eine Matrixmultiplikation.
In einfachen Worten (aus Sicht der Funktionalität) handelt es sich um einen One-Hot-Encoder und eine vollständig verbundene Schicht . Die Schichtgewichte sind trainierbar.