Cette page a été traduite par l'API Cloud Translation.
Switch to English

Affichage des données d'image dans TensorBoard

Voir sur TensorFlow.org Exécuter dans Google Colab Afficher la source sur GitHub

Aperçu

À l'aide de l' API TensorFlow Image Summary, vous pouvez facilement enregistrer des tenseurs et des images arbitraires et les afficher dans TensorBoard. Cela peut être extrêmement utile pour échantillonner et examiner vos données d'entrée, ou pour visualiser les poids des couches et les tenseurs générés . Vous pouvez également enregistrer les données de diagnostic sous forme d'images qui peuvent être utiles au cours du développement de votre modèle.

Dans ce didacticiel, vous apprendrez à utiliser l'API Image Summary pour visualiser les tenseurs sous forme d'images. Vous apprendrez également à prendre une image arbitraire, à la convertir en tenseur et à la visualiser dans TensorBoard. Vous travaillerez sur un exemple simple mais réel qui utilise des résumés d'images pour vous aider à comprendre les performances de votre modèle.

Installer

 try:
  # %tensorflow_version only exists in Colab.
  %tensorflow_version 2.x
except Exception:
  pass

# Load the TensorBoard notebook extension.
%load_ext tensorboard
 
TensorFlow 2.x selected.

 from datetime import datetime
import io
import itertools
from packaging import version
from six.moves import range

import tensorflow as tf
from tensorflow import keras

import matplotlib.pyplot as plt
import numpy as np
import sklearn.metrics

print("TensorFlow version: ", tf.__version__)
assert version.parse(tf.__version__).release[0] >= 2, \
    "This notebook requires TensorFlow 2.0 or above."
 
TensorFlow version:  2.2

Téléchargez le jeu de données Fashion-MNIST

Vous allez construire un réseau de neurones simple pour classer les images dans le jeu de données Fashion-MNIST . Cet ensemble de données se compose de 70 000 images 28x28 en niveaux de gris de produits de mode de 10 catégories, avec 7 000 images par catégorie.

Tout d'abord, téléchargez les données:

 # Download the data. The data is already divided into train and test.
# The labels are integers representing classes.
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = \
    fashion_mnist.load_data()

# Names of the integer classes, i.e., 0 -> T-short/top, 1 -> Trouser, etc.
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 
    'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
 
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-labels-idx1-ubyte.gz
32768/29515 [=================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/train-images-idx3-ubyte.gz
26427392/26421880 [==============================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-labels-idx1-ubyte.gz
8192/5148 [===============================================] - 0s 0us/step
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/t10k-images-idx3-ubyte.gz
4423680/4422102 [==============================] - 0s 0us/step

Visualiser une seule image

Pour comprendre le fonctionnement de l'API Image Summary, vous allez maintenant simplement enregistrer la première image d'entraînement dans votre ensemble d'entraînement dans TensorBoard.

Avant de faire cela, examinez la forme de vos données d'entraînement:

 print("Shape: ", train_images[0].shape)
print("Label: ", train_labels[0], "->", class_names[train_labels[0]])
 
Shape:  (28, 28)
Label:  9 -> Ankle boot

Notez que la forme de chaque image de l'ensemble de données est un tenseur de forme de rang 2 (28, 28), représentant la hauteur et la largeur.

Cependant, tf.summary.image() attend un tenseur de rang 4 contenant (batch_size, height, width, channels) . Par conséquent, les tenseurs doivent être remodelés.

Vous batch_size qu'une seule image, donc batch_size vaut 1. Les images sont en niveaux de gris, alors définissez les channels sur 1.

 # Reshape the image for the Summary API.
img = np.reshape(train_images[0], (-1, 28, 28, 1))
 

Vous êtes maintenant prêt à enregistrer cette image et à l'afficher dans TensorBoard.

 # Clear out any prior log data.
!rm -rf logs

# Sets up a timestamped log directory.
logdir = "logs/train_data/" + datetime.now().strftime("%Y%m%d-%H%M%S")
# Creates a file writer for the log directory.
file_writer = tf.summary.create_file_writer(logdir)

# Using the file writer, log the reshaped image.
with file_writer.as_default():
  tf.summary.image("Training data", img, step=0)
 

Maintenant, utilisez TensorBoard pour examiner l'image. Attendez quelques secondes que l'interface utilisateur démarre.

 %tensorboard --logdir logs/train_data
 

L'onglet "Images" affiche l'image que vous venez de connecter. C'est une "bottine".

L'image est mise à l'échelle à une taille par défaut pour une visualisation plus facile. Si vous souhaitez afficher l'image originale non mise à l'échelle, cochez "Afficher la taille réelle de l'image" en haut à gauche.

Jouez avec les curseurs de luminosité et de contraste pour voir comment ils affectent les pixels de l'image.

Visualiser plusieurs images

Enregistrer un tenseur est génial, mais que faire si vous souhaitez enregistrer plusieurs exemples d'entraînement?

Spécifiez simplement le nombre d'images que vous souhaitez enregistrer lorsque vous tf.summary.image() données à tf.summary.image() .

 with file_writer.as_default():
  # Don't forget to reshape.
  images = np.reshape(train_images[0:25], (-1, 28, 28, 1))
  tf.summary.image("25 training data examples", images, max_outputs=25, step=0)

%tensorboard --logdir logs/train_data
 

Enregistrement de données d'image arbitraires

Que faire si vous souhaitez visualiser une image qui n'est pas un tenseur, comme une image générée par matplotlib ?

Vous avez besoin d'un code standard pour convertir l'intrigue en tenseur, mais après cela, vous êtes prêt à partir.

Dans le code ci-dessous, vous enregistrerez les 25 premières images comme une belle grille en utilisant la fonction subplot subplot() de matplotlib. Vous verrez ensuite la grille dans TensorBoard:

 # Clear out prior logging data.
!rm -rf logs/plots

logdir = "logs/plots/" + datetime.now().strftime("%Y%m%d-%H%M%S")
file_writer = tf.summary.create_file_writer(logdir)

def plot_to_image(figure):
  """Converts the matplotlib plot specified by 'figure' to a PNG image and
  returns it. The supplied figure is closed and inaccessible after this call."""
  # Save the plot to a PNG in memory.
  buf = io.BytesIO()
  plt.savefig(buf, format='png')
  # Closing the figure prevents it from being displayed directly inside
  # the notebook.
  plt.close(figure)
  buf.seek(0)
  # Convert PNG buffer to TF image
  image = tf.image.decode_png(buf.getvalue(), channels=4)
  # Add the batch dimension
  image = tf.expand_dims(image, 0)
  return image

def image_grid():
  """Return a 5x5 grid of the MNIST images as a matplotlib figure."""
  # Create a figure to contain the plot.
  figure = plt.figure(figsize=(10,10))
  for i in range(25):
    # Start next subplot.
    plt.subplot(5, 5, i + 1, title=class_names[train_labels[i]])
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
  
  return figure

# Prepare the plot
figure = image_grid()
# Convert to image and log
with file_writer.as_default():
  tf.summary.image("Training data", plot_to_image(figure), step=0)

%tensorboard --logdir logs/plots
 

Construire un classificateur d'images

Maintenant, mettez tout cela ensemble avec un exemple réel. Après tout, vous êtes ici pour faire du machine learning et non pour tracer de jolies images!

Vous allez utiliser des résumés d'images pour comprendre les performances de votre modèle tout en entraînant un classificateur simple pour l'ensemble de données Fashion-MNIST.

Tout d'abord, créez un modèle très simple et compilez-le, en configurant l'optimiseur et la fonction de perte. L'étape de compilation spécifie également que vous souhaitez enregistrer la précision du classificateur en cours de route.

 model = keras.models.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(32, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

model.compile(
    optimizer='adam', 
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)
 

Lors de la formation d'un classificateur, il est utile de voir la matrice de confusion . La matrice de confusion vous donne une connaissance détaillée des performances de votre classificateur sur les données de test.

Définissez une fonction qui calcule la matrice de confusion. Vous utiliserez une fonction pratique Scikit-learn pour ce faire, puis vous le tracerez à l'aide de matplotlib.

 def plot_confusion_matrix(cm, class_names):
  """
  Returns a matplotlib figure containing the plotted confusion matrix.

  Args:
    cm (array, shape = [n, n]): a confusion matrix of integer classes
    class_names (array, shape = [n]): String names of the integer classes
  """
  figure = plt.figure(figsize=(8, 8))
  plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
  plt.title("Confusion matrix")
  plt.colorbar()
  tick_marks = np.arange(len(class_names))
  plt.xticks(tick_marks, class_names, rotation=45)
  plt.yticks(tick_marks, class_names)

  # Normalize the confusion matrix.
  cm = np.around(cm.astype('float') / cm.sum(axis=1)[:, np.newaxis], decimals=2)

  # Use white text if squares are dark; otherwise black.
  threshold = cm.max() / 2.
  for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
    color = "white" if cm[i, j] > threshold else "black"
    plt.text(j, i, cm[i, j], horizontalalignment="center", color=color)

  plt.tight_layout()
  plt.ylabel('True label')
  plt.xlabel('Predicted label')
  return figure
 

Vous êtes maintenant prêt à entraîner le classificateur et à consigner régulièrement la matrice de confusion en cours de route.

Voici ce que vous ferez:

  1. Créer le rappel Keras TensorBoard pour consigner les métriques de base
  2. Créez un Keras LambdaCallback pour consigner la matrice de confusion à la fin de chaque époque
  3. Entraînez le modèle à l'aide de Model.fit (), en vous assurant de passer les deux rappels

À mesure que la formation progresse, faites défiler vers le bas pour voir le démarrage de TensorBoard.

 # Clear out prior logging data.
!rm -rf logs/image

logdir = "logs/image/" + datetime.now().strftime("%Y%m%d-%H%M%S")
# Define the basic TensorBoard callback.
tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir)
file_writer_cm = tf.summary.create_file_writer(logdir + '/cm')
 
 def log_confusion_matrix(epoch, logs):
  # Use the model to predict the values from the validation dataset.
  test_pred_raw = model.predict(test_images)
  test_pred = np.argmax(test_pred_raw, axis=1)

  # Calculate the confusion matrix.
  cm = sklearn.metrics.confusion_matrix(test_labels, test_pred)
  # Log the confusion matrix as an image summary.
  figure = plot_confusion_matrix(cm, class_names=class_names)
  cm_image = plot_to_image(figure)

  # Log the confusion matrix as an image summary.
  with file_writer_cm.as_default():
    tf.summary.image("Confusion Matrix", cm_image, step=epoch)

# Define the per-epoch callback.
cm_callback = keras.callbacks.LambdaCallback(on_epoch_end=log_confusion_matrix)
 
 # Start TensorBoard.
%tensorboard --logdir logs/image

# Train the classifier.
model.fit(
    train_images,
    train_labels,
    epochs=5,
    verbose=0, # Suppress chatty output
    callbacks=[tensorboard_callback, cm_callback],
    validation_data=(test_images, test_labels),
)
 

Notez que la précision augmente à la fois sur le train et les ensembles de validation. C'est bon signe. Mais comment le modèle fonctionne-t-il sur des sous-ensembles spécifiques de données?

Sélectionnez l'onglet "Images" pour visualiser vos matrices de confusion enregistrées. Cochez "Afficher la taille réelle de l'image" en haut à gauche pour voir la matrice de confusion en taille réelle.

Par défaut, le tableau de bord affiche le résumé de l'image de la dernière étape ou époque enregistrée. Utilisez le curseur pour afficher les matrices de confusion antérieures. Remarquez comment la matrice change de manière significative au fur et à mesure que l'entraînement progresse, avec des carrés plus sombres fusionnant le long de la diagonale et le reste de la matrice tendant vers 0 et le blanc. Cela signifie que votre classificateur s'améliore au fur et à mesure que l'entraînement progresse! Bon travail!

La matrice de confusion montre que ce modèle simple présente certains problèmes. Malgré les grands progrès, les chemises, les t-shirts et les pulls se confondent. Le modèle a besoin de plus de travail.

Si vous êtes intéressé, essayez d'améliorer ce modèle avec un réseau convolutif (CNN).