web-dev-qa-db-fra.com

Comment utiliser TensorBoard avec Keras dans Python pour visualiser les plongements

Je lis le livre Deep Learning avec Python qui utilise Keras. Dans le chapitre 7, il montre comment utiliser TensorBoard pour surveiller la progression de la phase de formation avec un exemple:

import keras
from keras import layers
from keras.datasets import imdb
from keras.preprocessing import sequence

max_features = 2000
max_len = 500
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
x_train = sequence.pad_sequences(x_train, maxlen=max_len)
x_test = sequence.pad_sequences(x_test, maxlen=max_len)

model = keras.models.Sequential()
model.add(layers.Embedding(max_features, 128, input_length=max_len, name='embed'))
model.add(layers.Conv1D(32, 7, activation='relu'))
model.add(layers.MaxPooling1D(5))
model.add(layers.Conv1D(32, 7, activation='relu'))
model.add(layers.GlobalMaxPooling1D())
model.add(layers.Dense(1))
model.summary()

model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])

callbacks = [
    keras.callbacks.TensorBoard(
        log_dir='my_log_dir',
        histogram_freq=1,
        embeddings_freq=1,
    )
]
history = model.fit(x_train, y_train, epochs=20, batch_size=128, validation_split=0.2, callbacks=callbacks)

Apparemment, la bibliothèque Keras a subi quelques modifications car ce code lève une exception:

ValueError: To visualize embeddings, embeddings_data must be provided.

C'est après la première Epoch et la première fois que les rappels sont exécutés (la première fois que TensorBoard est exécuté). Je sais que ce qui manque, c'est le paramètre du TensorBoard embeddings_data. Mais je ne sais pas quoi lui assigner.

Quelqu'un at-il un exemple de travail pour cela?

Voici les versions que j'utilise:

Python: 3.6.5
Keras: 2.2.0
Tensorflow: 1.9.0

[MISE À JOUR]

Afin de tester toute solution possible, j'ai testé ceci:

import numpy as np

callbacks = [
    keras.callbacks.TensorBoard(
        log_dir='my_log_dir',
        histogram_freq = 1,
        embeddings_freq = 1,
        embeddings_data = np.arange(0, max_len).reshape((1, max_len)),
    )
]
history = model.fit(x_train, y_train, epochs=20, batch_size=128, validation_split=0.2, callbacks=callbacks)

C'est la seule façon de remplir embeddings_data ce qui ne conduira pas à une erreur. Mais même si cela n'aide pas non plus. L'onglet PROJECTOR du TensorBoard est toujours vide:

enter image description here

Toute aide est appréciée.

15
Mehran

Je lis également le livre "Deep Learning with Python" qui utilise Keras. Voici ma solution à cette question. D'abord, j'essaie ce code:

callbacks = [keras.callbacks.TensorBoard(
    log_dir = 'my_log_dir',
    histogram_freq = 1,
    embeddings_freq = 1,
    embeddings_data = x_train,
)]
history = model.fit(x_train, y_train, epochs=2, batch_size=128, validation_split=0.2, callbacks=callbacks)

Mais il y a une erreur: ResourceExhaustedError .

Parce qu'il y a 25 000 échantillons dans "x_train", il est difficile de les intégrer tous sur mon ancien cahier. Alors j'essaye ensuite d'incorporer les 100 premiers échantillons de "x_train", et c'est logique.

Le code et le résultat sont affichés ici.

callbacks = [keras.callbacks.TensorBoard(
    log_dir = 'my_log_dir',
    histogram_freq = 1,
    embeddings_freq = 1,
    embeddings_data = x_train[:100],
)]
history = model.fit(x_train, y_train, epochs=2, batch_size=128, validation_split=0.2, callbacks=callbacks)

Projecteur de 100 échantillons

Notez que dans le projecteur, "Points: 100" signifie qu'il y a 100 échantillons et "Dimension: 64000" signifie que la longueur du vecteur d'intégration pour un échantillon est 64000. Il y a 500 mots dans un échantillon, comme "max_len = 500", et il y a un vecteur 128_dim pour chaque mot, donc 500 * 128 = 64000.

3
ttigong

Oui c'est correct, vous devez fournir quoi à intégrer pour la visualisation en utilisant le embeddings_data argument:

callbacks = [
    keras.callbacks.TensorBoard(
        log_dir='my_log_dir',
        histogram_freq=1,
        embeddings_freq=1,
        embeddings_data=np.array([3,4,2,5,2,...]),
    )
]

embeddings_data : données à incorporer aux couches spécifiées dans embeddings_layer_names. Tableau Numpy (si le modèle a une seule entrée) ou liste de tableaux Numpy (si le modèle a plusieurs entrées).

Jetez un oeil à la documentation pour des informations mises à jour sur ce que sont ces arguments.

1
nuric

Je me suis juste posé la même question. D'après la documentation, il n'était pas si clair ce que "embeddings_data" était censé être. Mais il est logique que ce soit une liste de mots à intégrer, ou plutôt leurs indices.

Mais je suis un peu confus quant au format. De ma tokenisation avec le tokenizer keras, j'ai un "Word_index" avec un numéro pour tous les mots de mon vocabulaire à partir desquels les entrées les plus fréquentes maxwords sont utilisées. Le tokenizer me donne des listes d'entiers de 0 à maxwords ou un sac de mots codés à chaud. Je remplis ensuite ces séquences à maxlen.

max_words = 1000

tokenizer = Tokenizer(num_words=max_words)
tokenizer.fit_on_texts(X_train)

X_train_sequences = tokenizer.texts_to_sequences(X_train)
X_train_one_hot_results = tokenizer.texts_to_matrix(X_train, mode='binary')

X_test_sequences = tokenizer.texts_to_sequences(X_test)
X_test_one_hot_results = tokenizer.texts_to_matrix(X_test, mode='binary')

#####

maxlen = 100
X_train_pad = pad_sequences(X_train_sequences, maxlen=maxlen)
X_test_pad = pad_sequences(X_test_sequences, maxlen=maxlen)

Je crée ensuite un modèle qui commence par une couche d'intégration en tant que telle:

embedding_dim = 300

model = Sequential()
model.add(Embedding(max_words,embedding_dim,input_length=maxlen, name='embed'))
model.add(Flatten())
...

Donc max_words est la taille de mon vocabulaire, la taille d'un mot/texte encodé à chaud, embedding_dim est la taille de la sortie de la couche et maxlen = est la longueur de la séquence, c'est-à-dire le nombre de mots dans une phrase, qui est maintenu constant par un remplissage. Les nombres de Word_index sont-ils ceux que "embeddings_data" devrait obtenir d'une manière ou d'une autre?

Lorsque j'entre "uniquement" un tableau numpy qui répertorie un nombre arbitraire d'index Word

...
tensorboard = TensorBoard(log_dir='log_dir', histogram_freq=1, embeddings_freq=1, embeddings_data=np.array([1,2,3]))
...

Je reçois cette erreur:

ValueError: impossible de fournir la valeur de la forme (3, 1) pour le tenseur 'embed_input_2: 0', qui a la forme '(?, 100)'

Dans mon exemple, 100 correspond à la longueur de la séquence. C'est déroutant. Parce que je veux visualiser des mots simples, pas des phrases ou des textes, n'est-ce pas? Apparemment, le rappel veut alimenter la couche une ou plusieurs séquences.

Alors, comment suis-je censé encoder mes jetons "Reine", "Roi", "femme", "homme" pour que je puisse voir les relations sémantiques (avec un peu de chance)? Ou plus généralement: comment obtenir un aperçu de tous les éléments de vocabulaire pour repérer les tendances générales des intégrations formées individuellement?

1
Philipp Schäfer

Voici un exemple utilisant des plongements pour un classificateur NN convolutionnel de base. Le embedding_data se trouve être les données d'entrée dans ce scénario, et je pense que ce seront généralement toutes les données qui seront transmises via le réseau.

Voici le script lié avec quelques commentaires. Tout d'abord, ils commencent par la configuration de base du MNIST.

'''Trains a simple convnet on the MNIST dataset and embeds test data.
The test data is embedded using the weights of the final dense layer, just
before the classification head. This embedding can then be visualized using
TensorBoard's Embedding Projector.
'''

from __future__ import print_function

from os import makedirs
from os.path import exists, join

import keras
from keras.callbacks import TensorBoard
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K

import numpy as np

batch_size = 128
num_classes = 10
epochs = 12
log_dir = './logs'

if not exists(log_dir):
    makedirs(log_dir)

# input image dimensions
img_rows, img_cols = 28, 28

# the data, split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

if K.image_data_format() == 'channels_first':
    x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)
    x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)
    input_shape = (1, img_rows, img_cols)
else:
    x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
    x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
    input_shape = (img_rows, img_cols, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

Maintenant, les métadonnées sont créées pour tensorboard. Pour cette tâche de classification, le embedding_data est l'ensemble de test. Ensuite, les métadonnées doivent inclure les étiquettes de chiffres correspondantes.

# save class labels to disk to color data points in TensorBoard accordingly
with open(join(log_dir, 'metadata.tsv'), 'w') as f:
    np.savetxt(f, y_test)

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)

Définissez maintenant le rappel du tensorboard. Notez que les "fonctions" feront référence à l'incorporation de couche d'intérêt, qui est nommée lors de la construction du modèle. Le embedding_data est simplement l'ensemble de test ici.

tensorboard = TensorBoard(batch_size=batch_size,
                          embeddings_freq=1,
                          embeddings_layer_names=['features'],
                          embeddings_metadata='metadata.tsv',
                          embeddings_data=x_test)

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3),
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())

La couche suivante est nommée "entités".

model.add(Dense(128, activation='relu', name='features'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.losses.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

model.fit(x_train, y_train,
          batch_size=batch_size,
          callbacks=[tensorboard],
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

# You can now launch tensorboard with `tensorboard --logdir=./logs` on your
# command line and then go to http://localhost:6006/#projector to view the
# embeddings
0
zahbaz