web-dev-qa-db-fra.com

Expliquer avec un exemple: comment l'intégration des couches dans les kéros fonctionne

Je ne comprends pas la couche Embedding de Keras. Bien qu'il y ait beaucoup d'articles expliquant cela, je suis toujours confus. Par exemple, le code ci-dessous provient de l'analyse des sentiments imdb:

top_words = 5000
max_review_length = 500
embedding_vecor_length = 32    

model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length))
model.add(LSTM(100))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())
model.fit(X_train, y_train, nb_Epoch=3, batch_size=64)

Dans ce code, que fait exactement la couche d'intégration? Quelle serait la sortie de la couche d'intégration? Ce serait bien si quelqu'un pouvait l'expliquer avec quelques exemples peut-être!

18
user1670773

L'incorporation de la couche crée des vecteurs d'intégration à partir des mots d'entrée (je ne comprends toujours pas les mathématiques) de la même manière que le ferait Word2vec ou un gant précalculé.

Avant d'arriver à votre code, faisons un petit exemple.

texts = ['This is a text','This is not a text']

Nous transformons d'abord ces phrases en vecteur d'entiers où chaque mot est un numéro attribué au mot dans le dictionnaire et l'ordre du vecteur crée la séquence des mots.

from keras.preprocessing.text import Tokenizer
from keras.preprocessing.sequence import pad_sequences 
from keras.utils import to_categorical

max_review_length = 6 #maximum length of the sentence
embedding_vecor_length = 3
top_words = 10

#num_words is tne number of unique words in the sequence, if there's more top count words are taken
tokenizer = Tokenizer(top_words)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
Word_index = tokenizer.Word_index
input_dim = len(Word_index) + 1
print('Found %s unique tokens.' % len(Word_index))

#max_review_length is the maximum length of the input text so that we can create vector [... 0,0,1,3,50] where 1,3,50 are individual words
data = pad_sequences(sequences, max_review_length)

print('Shape of data tensor:', data.shape)
print(data)

[Out:] 
'This is a text' --> [0 0 1 2 3 4]
'This is not a text' --> [0 1 2 5 3 4]

Vous pouvez maintenant les saisir dans la couche d'intégration

from keras.models import Sequential
from keras.layers import Embedding

model = Sequential()
model.add(Embedding(top_words, embedding_vecor_length, input_length=max_review_length,mask_zero=True))
model.compile(optimizer='adam', loss='categorical_crossentropy')
output_array = model.predict(data)

output_array contient un tableau de taille (2, 6, 3): 2 commentaires ou phrases d'entrée dans mon cas, 6 est le nombre maximum de mots dans chaque revue (max_review_length) et 3 est embedding_vecor_length. Par exemple.

array([[[-0.01494285, -0.007915  ,  0.01764857],
    [-0.01494285, -0.007915  ,  0.01764857],
    [-0.03019481, -0.02910612,  0.03518577],
    [-0.0046863 ,  0.04763055, -0.02629668],
    [ 0.02297204,  0.02146662,  0.03114786],
    [ 0.01634104,  0.02296363, -0.02348827]],

   [[-0.01494285, -0.007915  ,  0.01764857],
    [-0.03019481, -0.02910612,  0.03518577],
    [-0.0046863 ,  0.04763055, -0.02629668],
    [-0.01736645, -0.03719328,  0.02757809],
    [ 0.02297204,  0.02146662,  0.03114786],
    [ 0.01634104,  0.02296363, -0.02348827]]], dtype=float32)

Dans votre cas, vous avez une liste de 5000 mots, qui peut créer un examen de 500 mots maximum (d'autres seront rognés) et transformer chacun de ces 500 mots en vecteur de taille 32.

Vous pouvez obtenir le mappage entre les index Word et les vecteurs d'intégration en exécutant:

model.layers[0].get_weights()

Dans le cas ci-dessous, top_words était de 10, nous avons donc un mappage de 10 mots et vous pouvez voir que le mappage pour 0, 1, 2, 3, 4 et 5 est égal à output_array ci-dessus.

[array([[-0.01494285, -0.007915  ,  0.01764857],
    [-0.03019481, -0.02910612,  0.03518577],
    [-0.0046863 ,  0.04763055, -0.02629668],
    [ 0.02297204,  0.02146662,  0.03114786],
    [ 0.01634104,  0.02296363, -0.02348827],
    [-0.01736645, -0.03719328,  0.02757809],
    [ 0.0100757 , -0.03956784,  0.03794377],
    [-0.02672029, -0.00879055, -0.039394  ],
    [-0.00949502, -0.02805768, -0.04179233],
    [ 0.0180716 ,  0.03622523,  0.02232374]], dtype=float32)]

Comme mentionné dans https://stats.stackexchange.com/questions/270546/how-does-keras-embedding-layer-work ces vecteurs sont lancés comme aléatoires et optimisés par les optimiseurs de mots clés comme n'importe quel autre paramètre du réseau.

9
Vaasha

Je suis d'accord avec la réponse détaillée précédente, mais je voudrais essayer de donner une explication plus intuitive.

Pour comprendre le fonctionnement de la couche d'intégration, il est préférable de prendre un peu de recul et de comprendre pourquoi nous avons besoin de l'intégration en premier lieu.

Habituellement, les modèles ML prennent des vecteurs (tableau de nombres) en entrée et, lorsque nous traitons du texte, nous convertissons les chaînes en nombres. L'un des moyens les plus simples de le faire est le codage à chaud où vous traitez chaque chaîne comme une variable catégorielle. Mais le premier problème est que si vous utilisez un dictionnaire (vocabulaire) de 10000 mots, alors l'encodage à chaud est à peu près une perte d'espace (mémoire).

De plus, comme les entités discrètes sont mappées à 0 ou 1 signalant une catégorie spécifique, le codage à chaud ne peut capturer aucune relation entre les mots. Ainsi, si vous connaissez ensemble de données de film IMDB , l'encodage à chaud n'est rien mais inutile pour l'analyse des sentiments. Parce que, si vous mesurez la similitude en utilisant la distance cosinus, la similitude est toujours nulle pour chaque comparaison entre différents indices.

Cela devrait nous guider pour trouver une méthode où -

  • Des mots similaires peuvent avoir un codage similaire,
  • Pour représenter les variables catégorielles, nous aurons moins de nombres que le nombre de catégories uniques.

Entre dans l'incorporation ..

L'incorporation est un vecteur dense de valeurs à virgule flottante et, ces nombres sont générés de manière aléatoire et pendant la formation, ces valeurs sont mises à jour via backprop tout comme les poids dans une couche dense sont mis à jour pendant la formation.
Comme défini dans TensorFlow docs

La couche d'incorporation peut être comprise comme une table de recherche qui mappe des indices entiers (qui représentent des mots spécifiques) à des vecteurs denses (leurs incorporations).

Avant de construire le modèle avec séquentiel, vous avez déjà utilisé Keras Tokenizer API et les données d'entrée sont déjà codées en entier. Maintenant, une fois que vous avez mentionné le nombre de dimensions d'intégration (par exemple 16, 32, 64, etc.), le nombre de colonnes de la table de recherche sera déterminé par cela.

La sortie de la couche d'intégration est toujours un tableau 2D, c'est pourquoi elle est généralement aplatie avant de se connecter à une couche dense. Dans la réponse précédente également, vous pouvez voir un tableau 2D de poids pour la 0ème couche et le nombre de colonnes = longueur du vecteur d'intégration.

Voilà comment je pense à la couche Embedding dans Keras. J'espère que cela éclairera un peu plus et j'ai pensé que cela pourrait être un bon accompagnement de la réponse postée par @ Vaasha .

Référence: TensorFlow Word Embedding Tutorial .

0
Suvo