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 Embeddinglayer 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 classchiamato Layer .
(1) - Creazione di una matrice di peso di (vocabulary_size) x (embedding_dimension) dimensioni:
Ciò si verifica nella buildfunzione 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 callfunzione 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 Embeddinglivello che è K.gather(self.embeddings, inputs). Quello che tf.keras.backend.gather fa esattamente è indicizzare la matrice dei pesiself.embeddings (vedere la buildfunzione sopra) in base alle inputsliste 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 Embeddinglayer è 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 Embeddinglivello.
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 Embeddinglivello 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 nin inputsun vettore di feature addestrabile W[n], la cui dimensione è la cosiddetta lunghezza di feature incorporata.
Embeddingstrato è 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.