Skip to content
Advertisement

How do I fit tensorflow ImageDataGenerator

I’ve build my model, but do not know how to fit it. Could anyone give me some tip so I can use ImageDataGenerator in my models while working with images, or it is better to use other ways like using Dataset?

import tensorflow as tf
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
import numpy as np
import matplotlib.pyplot as plt
import cv2
import os

# const
IMG_HEIGHT = 150
IMG_WIDTH  = 150
BATCH = 32
EPOCHS = 5
train_dir = "data/images/train"
val_dir = "data/images/val"


# train image data generator
train_generator = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1./255,
    horizontal_flip=True,
    dtype=tf.float32
)
train_generator.flow_from_directory(
    directory=train_dir,
    target_size=(IMG_WIDTH, IMG_HEIGHT)
)

# validation image data generator
val_generator = tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1./255,
    horizontal_flip=False
)
val_generator.flow_from_directory(
    directory = val_dir,
    target_size=(IMG_WIDTH, IMG_HEIGHT)
)

# count train cats & dogs
train_cats_len = len(os.listdir(os.path.join(train_dir, "cats")))
train_dogs_len = len(os.listdir(os.path.join(train_dir, "dogs")))
train_len = train_cats_len + train_dogs_len

# count validation cats & dogs
val_cats_len = len(os.listdir(os.path.join(val_dir, "cats")))
val_dogs_len = len(os.listdir(os.path.join(val_dir, "dogs")))
val_len = val_cats_len + val_dogs_len

# build a model
model = tf.keras.Sequential([
    Conv2D(16, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH , 3)),
    MaxPooling2D(),
    Dropout(0.2),
    Flatten(),
    Dense(128, activation='relu'),
    Dense(64, activation='relu'),
    Dense(2, activation='sigmoid')
])

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

# fit?

# history = model.fit_generator(
#     train_generator,
#     steps_per_epoch=train_len // BATCH,
#     epochs=EPOCHS,
#     validation_data=val_generator,
#     validation_steps=val_len // BATCH,
#     verbose=True
# )

# raises error:
# ValueError: Failed to find data adapter that can handle input: <class 'tensorflow.python.keras.preprocessing.image.ImageDataGenerator'>, <class 'NoneType'>

My directory architecture:

data-
    |-images-
            |-train-
                   |-cats
                   |-dogs
            |-val-
                  |-cats
                  |-dogs

PS:

I found article where same method used and everything seems to work, but not in my case

Advertisement

Answer

your problem is you have the code

train_generator.flow_from_directory(
    directory=train_dir,
    target_size=(IMG_WIDTH, IMG_HEIGHT)

You need to change that to

train_generator=train_generator.flow_from_directory( directory=train_dir,
    target_size=(IMG_WIDTH, IMG_HEIGHT)

do the same for the val_generator. In addition the default class_mode for the ImageDataGenerator is “categorical”. Therefore in model.compile you should specify the loss as ‘categorical_crossentropy’. In your model layer with the 2 nodes the activation function should be ‘softmax’. As an aside I think your model may not perform very well as it may be a bit to simple to process the features of the data. I suggest adding several more convolutional layers with more filters. An example for a more complex model is shown below

model = tf.keras.Sequential([
    Conv2D(16, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH , 3)),
    MaxPooling2D(),
    Conv2D(32, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH , 3)),
    MaxPooling2D(),
    Conv2D(64, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH , 3)),
    MaxPooling2D(),
    Conv2D(128, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH , 3)),
    MaxPooling2D(),
    Flatten(),
    Dense(128, activation='relu'),
    Dropout(.3),
    Dense(64, activation='relu'),
    Dropout(.3),
    Dense(2, activation='softmax')
])

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement