La documentazione di Keras non è chiara su cosa sia effettivamente. Capisco che possiamo usarlo per comprimere lo spazio della funzione di input in uno più piccolo. Ma come si fa da una prospettiva di progettazione neurale? È un autoenocder, RBM?
La documentazione di Keras non è chiara su cosa sia effettivamente. Capisco che possiamo usarlo per comprimere lo spazio della funzione di input in uno più piccolo. Ma come si fa da una prospettiva di progettazione neurale? È un autoenocder, RBM?
Risposte:
Per quanto ne so, il livello Embedding è una semplice moltiplicazione di matrici che trasforma le parole nei loro corrispondenti word embedding.
I pesi del livello Embedding sono della forma (vocabulary_size, embedding_dimension). Per ogni campione di addestramento, i suoi input sono numeri interi, che rappresentano determinate parole. I numeri interi rientrano nella gamma della dimensione del vocabolario. Il livello Embedding trasforma ogni numero intero i nella iesima riga della matrice dei pesi di incorporamento.
Per fare ciò rapidamente come una moltiplicazione di matrici, gli interi di input non vengono memorizzati come un elenco di numeri interi ma come una matrice a caldo. Pertanto la forma di input è (nb_words, vocabulary_size) con un valore diverso da zero per riga. Se lo moltiplichi per i pesi di incorporamento, ottieni l'output nella forma
(nb_words, vocab_size) x (vocab_size, embedding_dim) = (nb_words, embedding_dim)
Quindi, con una semplice moltiplicazione di matrici, trasformi tutte le parole di un campione nelle corrispondenti parole incorporate.
Il Keras
Embedding
layer non esegue alcuna moltiplicazione di matrici ma si limita a:
1. crea una matrice di peso x (vocabulary_size) (embedding_dimension) dimensioni
2. indicizza questa matrice di peso
È sempre utile dare un'occhiata al codice sorgente per capire cosa fa una classe. In questo caso, daremo uno sguardo class
all'incorporamento che eredita dal livello di base class
chiamato Layer .
(1) - Creazione di una matrice di peso di (vocabulary_size) x (embedding_dimension) dimensioni:
Ciò si verifica nella build
funzione di incorporamento :
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
Se si dispone di uno sguardo alla classe di base di livello si vedrà che la funzioneadd_weight
di cui sopra crea semplicemente una matrice di pesi addestrabili (in questo caso di (vocabulary_size) x (embedding_dimension) le dimensioni):
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) - Indicizzazione di questa matrice di peso
Ciò avviene nella call
funzione di incorporamento :
def call(self, inputs):
if K.dtype(inputs) != 'int32':
inputs = K.cast(inputs, 'int32')
out = K.gather(self.embeddings, inputs)
return out
Questa funzione restituisce l'output del Embedding
livello che è K.gather(self.embeddings, inputs)
. Quello che tf.keras.backend.gather fa esattamente è indicizzare la matrice dei pesiself.embeddings
(vedere la build
funzione sopra) in base alle inputs
liste di numeri interi positivi.
Questi elenchi possono essere recuperati, ad esempio, se passi i tuoi input di testo / parole alla funzione one_hot di Keras che codifica un testo in un elenco di indici di parole di dimensione n (questa NON è una codifica a caldo - vedi anche questo esempio per maggiori informazioni: https://machinelearningmastery.com/use-word-embedding-layers-deep-learning-keras/ ).
Quindi è tutto. Non c'è moltiplicazione di matrici.
Al contrario, il Keras
Embedding
layer è utile solo perché esattamente evita di eseguire una moltiplicazione di matrici e quindi risparmia su alcune risorse computazionali.
Altrimenti, potresti semplicemente usare un livello Keras
Denso (dopo aver codificato i tuoi dati di input) per ottenere una matrice di pesi addestrabili (di dimensioni (vocabulary_size) x (embedding_dimension) ) e poi semplicemente fare la moltiplicazione per ottenere l'output che sarà esattamente lo stesso con l'output del Embedding
livello.
Per comprendere meglio qualsiasi funzione è una buona abitudine guardare il codice sorgente. Qui è per l' incorporamento Quindi, in pratica, è una tabella di ricerca addestrabile.
In Keras, il Embedding
livello NON è un semplice livello di moltiplicazione di matrici, ma un livello di tabella di ricerca (vedere la funzione di chiamata di seguito o la definizione originale ).
def call(self, inputs):
if K.dtype(inputs) != 'int32':
inputs = K.cast(inputs, 'int32')
out = K.gather(self.embeddings, inputs)
return out
Quello che fa è mappare ciascuno un intero noto n
in inputs
un vettore di feature addestrabile W[n]
, la cui dimensione è la cosiddetta lunghezza di feature incorporata.
Embedding
strato è davvero una moltiplicazione di matrici.
In parole semplici (dal punto di vista della funzionalità), è un encoder one-hot e uno strato completamente connesso . I pesi degli strati possono essere allenati.