There is no method that lets you do this automatically like image_dataset_from_directory (that I know of at least). However creating the dataset on your own is pretty easy.
You first have to iterate through your directory searching for the images. You save the path of each image you encounter in a list paths. For each image you check the class, either dog or cat in this case, and you create a dictionary where you map each class name to a different int, the label of that class. For each image you save aside the label of it in a list labels.
import glob
paths = []
labels = []
labels_dict = {}
index = 0
for filepath in glob.iglob('train/*/*.jpg'):
paths.append(filepath)
class_name = filepath.split('_')[1].split("/")[-1]
if class_name not in labels_dict:
labels_dict[class_name] = index
index += 1
labels.append(labels_dict[class_name])
print(labels)
print(paths)
print(labels_dict)
Outputs:
# labels:
[0, 1, 1, 1, 1, 0]
# paths
['train/dir_1/dog_1.jpg', 'train/dir_1/cat_2.jpg', 'train/dir_1/cat_1.jpg', 'train/dir_2/cat_1.jpg', 'train/dir_2/cat_2.jpg', 'train/dir_2/dog_1.jpg']
# labels_dict
{'dog': 0, 'cat': 1}
Now that you have prepared your paths and labels, you can proceed as from this answer:
import tensorflow as tf
paths = tf.constant(paths)
labels = tf.constant(labels)
# create a dataset returning slices of `paths`
dataset = tf.data.Dataset.from_tensor_slices((paths, labels))
# parse every image in the dataset using `map`
def _parse_function(filename, label):
image_string = tf.io.read_file(filename)
image_decoded = tf.image.decode_jpeg(image_string, channels=3)
image = tf.cast(image_decoded, tf.float32)
return image, label
dataset = dataset.map(_parse_function)