Visualizzazione dei dati immagine in TensorBoard

Visualizza su TensorFlow.org Esegui in Google Colab Visualizza la fonte su GitHub Scarica taccuino

Panoramica

Utilizzando l'API Sommario tensorflow Immagine, si può facilmente accedere tensori e immagini arbitrarie e visualizzarli in TensorBoard. Questo può essere estremamente utile per il campionamento e esaminare i dati di input, o per visualizzare i pesi strato e tensori generati . Puoi anche registrare i dati diagnostici come immagini che possono essere utili nel corso dello sviluppo del modello.

In questo tutorial imparerai come utilizzare l'API Image Summary per visualizzare i tensori come immagini. Imparerai anche come prendere un'immagine arbitraria, convertirla in un tensore e visualizzarla in TensorBoard. Lavorerai attraverso un esempio semplice ma reale che utilizza i riepiloghi di immagini per aiutarti a capire le prestazioni del tuo modello.

Impostare

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

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

Scarica il dataset Fashion-MNIST

Stai andando a costruire una semplice rete neurale per immagini classificano nella del Fashion-MNIST dataset. Questo set di dati è composto da 70.000 immagini in scala di grigi 28x28 di prodotti di moda di 10 categorie, con 7.000 immagini per categoria.

Per prima cosa, scarica i dati:

# 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

Visualizzazione di una singola immagine

Per capire come funziona l'API Image Summary, ora registrerai semplicemente la prima immagine di training nel tuo training set in TensorBoard.

Prima di farlo, esamina la forma dei tuoi dati di allenamento:

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

Notare che la forma di ogni immagine nel set di dati è un tensore di forma di rango 2 (28, 28), che rappresenta l'altezza e la larghezza.

Tuttavia, tf.summary.image() prevede un tensore di rango 4 contenente (batch_size, height, width, channels) . Pertanto, i tensori devono essere rimodellati.

Non Sei la registrazione una sola immagine, in modo da batch_size è pari a 1. Le immagini sono in scala di grigi, in modo da impostare channels a 1.

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

Ora sei pronto per registrare questa immagine e visualizzarla in 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)

Ora usa TensorBoard per esaminare l'immagine. Attendi qualche secondo che l'interfaccia utente si avvii.

%tensorboard --logdir logs/train_data

La scheda "Immagini" mostra l'immagine che hai appena registrato. È uno "stivaletto".

L'immagine viene ridimensionata a una dimensione predefinita per una visualizzazione più semplice. Se desideri visualizzare l'immagine originale non ridimensionata, seleziona "Mostra le dimensioni effettive dell'immagine" in alto a sinistra.

Gioca con i cursori di luminosità e contrasto per vedere come influenzano i pixel dell'immagine.

Visualizzazione di più immagini

La registrazione di un tensore è ottima, ma cosa succede se si desidera registrare più esempi di addestramento?

Basta specificare il numero di immagini che si desidera registrare, quando il passaggio di dati a 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

Registrazione di dati immagine arbitrari

Che cosa succede se si desidera visualizzare un'immagine che non è un tensore, ad esempio un'immagine generata da matplotlib ?

Hai bisogno di un codice standard per convertire la trama in un tensore, ma dopo, sei a posto.

Nel codice qui sotto, si accede le prime 25 immagini in una griglia bella usando di matplotlib subplot() la funzione. Vedrai quindi la griglia in 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

Costruire un classificatore di immagini

Ora metti tutto insieme con un esempio reale. Dopotutto, sei qui per fare l'apprendimento automatico e non per tracciare belle immagini!

Utilizzerai i riepiloghi delle immagini per capire quanto sta andando bene il tuo modello durante l'addestramento di un semplice classificatore per il set di dati Fashion-MNIST.

Innanzitutto, crea un modello molto semplice e compilalo, impostando l'ottimizzatore e la funzione di perdita. Il passaggio di compilazione specifica inoltre che si desidera registrare l'accuratezza del classificatore lungo il percorso.

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']
)

Quando la formazione di un classificatore, è utile per vedere la matrice di confusione . La matrice di confusione fornisce una conoscenza dettagliata delle prestazioni del tuo classificatore sui dati di test.

Definire una funzione che calcoli la matrice di confusione. Potrai utilizzare una vantaggiosa scikit-learn funzione per fare questo, e poi tracciare utilizzando 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)

  # Compute the labels from the normalized confusion matrix.
  labels = 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, labels[i, j], horizontalalignment="center", color=color)

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

Ora sei pronto per addestrare il classificatore e registrare regolarmente la matrice di confusione lungo il percorso.

Ecco cosa farai:

  1. Creare il callback Keras TensorBoard per accedere metriche di base
  2. Creare un Keras LambdaCallback per accedere alla matrice di confusione alla fine di ogni epoca
  3. Addestrare il modello utilizzando Model.fit(), assicurandosi di passare entrambi i callback

Con l'avanzare dell'addestramento, scorrere verso il basso per vedere l'avvio di 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),
)

Notare che la precisione è in aumento sia sul treno che sui set di convalida. Questo è un buon segno. Ma come si comporta il modello su specifici sottoinsiemi di dati?

Seleziona la scheda "Immagini" per visualizzare le matrici di confusione registrate. Seleziona "Mostra dimensione immagine effettiva" in alto a sinistra per vedere la matrice di confusione a grandezza naturale.

Per impostazione predefinita, la dashboard mostra il riepilogo dell'immagine per l'ultimo passaggio o epoca registrato. Utilizzare il dispositivo di scorrimento per visualizzare le matrici di confusione precedenti. Nota come la matrice cambia in modo significativo man mano che l'allenamento progredisce, con i quadrati più scuri che si uniscono lungo la diagonale e il resto della matrice che tende verso lo 0 e il bianco. Ciò significa che il tuo classificatore sta migliorando con il progredire dell'allenamento! Ottimo lavoro!

La matrice di confusione mostra che questo semplice modello presenta alcuni problemi. Nonostante i grandi progressi, Camicie, T-Shirt e Pullover si confondono tra loro. Il modello ha bisogno di più lavoro.

Se siete interessati, cercare di migliorare questo modello con una rete di convoluzionale (CNN).