Cos'è l'incorporamento in Keras?


97

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?

keras 

7
È una tabella di ricerca che può essere addestrata
gokul_uf

1
Crea e indicizza semplicemente una matrice di peso; vedere la mia risposta dettagliata di seguito ( stackoverflow.com/a/53101566/9024698 ).
Emarginato

3
Anche se la risposta più votata dice che è una moltiplicazione di matrici, il codice sorgente e altre risposte mostrano che in realtà sono solo una matrice addestrabile. Le parole di input selezionano semplicemente la rispettiva riga in questa matrice.
Daniel Möller

Risposte:


66

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.


3
Sicuramente un approccio valido (vedi Apprendimento sequenziale semi-supervisionato ). Puoi anche imparare gli incorporamenti con un autoencoder e quindi usarli come inizializzazione del livello di incorporamento per ridurre la complessità della tua rete neurale (presumo che tu faccia qualcos'altro dopo il livello di incorporamento).
Lorrit

3
Ecco un bel post sul blog sugli incorporamenti di parole e sui loro vantaggi.
sietschie

3
Nel caso che ho presentato, ogni input di formazione è un insieme di parole (può essere una frase). Ogni parola è rappresentata come un vettore caldo e incorporata in un vettore denso. Lo svantaggio di questo approccio è che, poiché l'input deve essere di lunghezza costante, tutte le frasi devono avere lo stesso numero di parole. Un'alternativa sarebbe i vettori di paragrafo , che possono incorporare frasi, paragrafi o persino documenti in vettori.
Lorrit

4
Il livello di incorporamento ottimizzerà solo i suoi pesi per ridurre al minimo la perdita. Forse questo significa che prenderà in considerazione la somiglianza semantica, forse no. Non si sa mai con le reti neurali. Se vuoi essere sicuro che l'incorporamento segua una certa formula (es. W2v), usa la formula. Se disponi di dati sufficienti, potresti voler utilizzare il livello di incorporamento e addestrare gli incorporamenti. Provalo e controlla se ti piacciono i risultati.
Lorrit

2
Sono d'accordo con user36624 (risposta sotto). La sua non una semplice moltiplicazione matrice.
Daniel Möller

21

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.


5

Per comprendere meglio qualsiasi funzione è una buona abitudine guardare il codice sorgente. Qui è per l' incorporamento Quindi, in pratica, è una tabella di ricerca addestrabile.


4

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.


Ebbene, quando si moltiplica un insieme di vettori rappresentati con una matrice, il prodotto diventa una ricerca. Quindi lo Embeddingstrato è davvero una moltiplicazione di matrici.
yannis

Tranne che da nessuna parte Keras esegue questa moltiplicazione. Definisce semplicemente "embeddings = una matrice addestrabile" e utilizza gli indici di input per raccogliere parole dalla matrice.
Daniel Möller

Pertanto, questo incorporamento risparmia molta memoria semplicemente non creando alcuna versione degli input.
Daniel Möller

1

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.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.