Отображение данных изображения в TensorBoard

Посмотреть на TensorFlow.org Запускаем в Google Colab Посмотреть исходный код на GitHub Скачать блокнот

Обзор

Использование TensorFlow изображения Краткое описание API, вы можете легко войти тензоры и произвольные изображения и просматривать их в TensorBoard. Это может быть очень полезно для выборки и изучить ваши входные данные или визуализировать вес слоя и сгенерированные тензоры . Вы также можете записывать диагностические данные в виде изображений, которые могут быть полезны в процессе разработки вашей модели.

В этом руководстве вы узнаете, как использовать API сводки изображений для визуализации тензоров в виде изображений. Вы также узнаете, как взять произвольное изображение, преобразовать его в тензор и визуализировать в TensorBoard. Вы проработаете простой, но реальный пример, в котором используются сводки изображений, которые помогут вам понять, как работает ваша модель.

Настраивать

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

Загрузите набор данных Fashion-MNIST

Вы собираетесь построить простую нейронную сеть для классификации изображений в в Fashion-MNIST наборе данных. Этот набор данных состоит из 70 000 изображений модной одежды 28 x 28 в оттенках серого из 10 категорий, по 7 000 изображений в каждой категории.

Сначала загрузите данные:

# 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

Визуализация одного изображения

Чтобы понять, как работает API сводки изображений, теперь вы собираетесь просто зарегистрировать первое обучающее изображение в своем обучающем наборе в TensorBoard.

Перед тем, как сделать это, изучите форму ваших тренировочных данных:

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

Обратите внимание, что форма каждого изображения в наборе данных - это тензор второго ранга формы (28, 28), представляющий высоту и ширину.

Тем не менее, tf.summary.image() ожидает тензор ранга 4 , содержащий (batch_size, height, width, channels) . Следовательно, необходимо изменить форму тензоров.

Ты протоколирование только один образ, так batch_size равно 1. Изображения в оттенках серого, поэтому установите channels 1.

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

Теперь вы готовы зарегистрировать это изображение и просмотреть его на 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)

Теперь используйте TensorBoard, чтобы изучить изображение. Подождите несколько секунд, пока пользовательский интерфейс не раскрутится.

%tensorboard --logdir logs/train_data

На вкладке «Изображения» отображается только что зарегистрированное изображение. Это «ботинок по щиколотку».

Изображение масштабируется до размера по умолчанию для облегчения просмотра. Если вы хотите просмотреть немасштабированное исходное изображение, установите флажок «Показать реальный размер изображения» в верхнем левом углу.

Поиграйте с ползунками яркости и контрастности, чтобы увидеть, как они влияют на пиксели изображения.

Визуализация нескольких изображений

Запись одного тензора - это здорово, но что, если вы хотите записать несколько обучающих примеров?

Просто укажите количество изображений , которые вы хотите , чтобы войти при передаче данных в 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

Запись произвольных данных изображения

Что делать , если вы хотите визуализировать изображение , которое не является тензором, такие как изображение , сформированное Matplotlib ?

Вам понадобится шаблонный код для преобразования графика в тензор, но после этого все готово.

В приведенном ниже кода, вы будете регистрировать первые 25 изображений в качестве хорошей сетки с использованием Matplotlib в subplot() функции. Затем вы просмотрите сетку в 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

Создание классификатора изображений

Теперь соедините все это с реальным примером. В конце концов, вы здесь для того, чтобы заниматься машинным обучением, а не рисовать красивые картинки!

Вы собираетесь использовать сводки изображений, чтобы понять, насколько хорошо работает ваша модель, при обучении простого классификатора для набора данных Fashion-MNIST.

Сначала создайте очень простую модель и скомпилируйте ее, настроив оптимизатор и функцию потерь. На этапе компиляции также указывается, что вы хотите регистрировать точность классификатора на этом пути.

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

При обучении классификатора, это полезно , чтобы увидеть матрицу путаницы . Матрица неточностей дает вам подробные сведения о том, как ваш классификатор работает с тестовыми данными.

Определите функцию, которая вычисляет матрицу неточностей. Вы будете использовать удобный Scikit учиться функцию , чтобы сделать это, а затем построить его с помощью 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

Теперь вы готовы обучать классификатор и регулярно регистрировать матрицу неточностей.

Вот что ты будешь делать:

  1. Создание обратного вызова Keras TensorBoard для входа основных показателей
  2. Создать Keras LambdaCallback войти в матрицу путаницы в конце каждой эпохи
  3. Обучите модель с помощью Model.fit (), убедившись, что переданы оба обратных вызова

По мере обучения прокрутите вниз, чтобы увидеть запуск 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),
)

Обратите внимание, что точность растет как на обучающих, так и на проверочных наборах. Это хороший знак. Но как модель работает с конкретными подмножествами данных?

Выберите вкладку «Изображения», чтобы визуализировать ваши зарегистрированные матрицы путаницы. Установите флажок «Показать реальный размер изображения» в левом верхнем углу, чтобы увидеть матрицу неадекватности в полном размере.

По умолчанию на панели управления отображается сводка изображений для последнего зарегистрированного шага или эпохи. Используйте ползунок, чтобы просмотреть более ранние матрицы путаницы. Обратите внимание, как матрица значительно меняется по мере обучения: более темные квадраты сливаются по диагонали, а остальная часть матрицы стремится к 0 и белому. Это означает, что ваш классификатор улучшается по мере обучения! Отличная работа!

Матрица неточностей показывает, что у этой простой модели есть некоторые проблемы. Несмотря на большой прогресс, рубашки, футболки и пуловеры путают друг с другом. Модель требует доработки.

Если вы заинтересованы, попробуйте улучшить эту модель с сверточными сетями (CNN).