Get a sample of one image per class with image_dataset_from_directory

Viewed 2017

I am trying to visualize Skin Cancer Images using Keras. I have imported the images in my notebook and have created batch datasets using Keras.image_dataset_from_directory. The code is as follows:

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
data_dir,
validation_split=0.2,
subset="training",
seed=1337,
image_size=image_size,
batch_size=batch_size)

Now, I have been trying to visualize the images. However, I want one image from each class (there are 9 classes in the dataset). I have used the below code:

plt.figure(figsize = (10,10))
for images, labels in train_ds.take(1):
    for i in range(9):
        ax = plt.subplot(3,3,i+1)
        plt.imshow(images[i].numpy().astype("uint8"))
        plt.title(class_names[labels[i]])
        plt.axis("off")

This code gets me a lot of duplicate classes. How do I get one value for each class (in this case I have 9 classes. I want one plot for each of those 9 classes). I am not sure how to fetch unique images and their labels from a BatchDataset!

3 Answers
for i in range(len(class_names)):
    filtered_ds = train_ds.filter(lambda x, l: tf.math.equal(l[0], i))
    for image, label in filtered_ds.take(1):
        ax = plt.subplot(3, 3, i+1)
        plt.imshow(image[0].numpy().astype('uint8'))
        plt.title(class_names[label.numpy()[0]])
        plt.axis('off')

You could loop through and filter on each label.

Example:

import tensorflow as tf

# fake images
imgs = tf.random.normal([100, 64, 64, 3])

# fake labels
labels = tf.random.uniform([100], minval=0, maxval=10, dtype=tf.int32)

# make dataset
ds = tf.data.Dataset.from_tensor_slices((imgs, labels))

for i in range(9):
    filtered = ds.filter(lambda _, l: tf.math.equal(l, i))
    for img, label in filtered.take(1):
        assert label.numpy() == i
        # plot image

Try Following Code - This works perfectly to display one image from each of the 10 categories of cifar10:

import numpy as np
import matplotlib.pyplot as plt
from tensorflow import keras

(x_train, y_train), (x_test, y_test)= keras.datasets.cifar10.load_data()

fig, ax= plt.subplots(nrows= 2, ncols= 5, figsize= (18,5))
plt.suptitle('displaying one image of each category in train set'.upper(), 
             y= 1.05, fontsize= 16)

i= 0
for j in range(2):
  for k in range(5):
    ax[j,k].imshow(x_train[list(y_train).index(i)])
    ax[j,k].axis('off')
    ax[j,k].set_title(i)
    i+=1

plt.tight_layout()
plt.show()
Related