A_toaster
A_toaster

Reputation: 1288

Preparing data for Keras CNN training without the use of ImageDataGenerator

I am trying to figure out how to train a CNN in Keras without using ImageDataGenerator. Essentially I'm trying to figure out the magic behind the ImageDataGenerator class so that I don't have to rely on it for all my projects.

I have a dataset organized into 2 folders: training_set and test_set. Each of these folders contains 2 sub-folders: cats and dogs.

I am loading them all into memory using Keras' load_img class in a for loop as follows:

trainingImages = []
trainingLabels = []
validationImages = []
validationLabels = []

imgHeight = 32
imgWidth = 32
inputShape = (imgHeight, imgWidth, 3)

print('Loading images into RAM...')

for path in imgPaths:

    classLabel = path.split(os.path.sep)[-2]
    classes.add(classLabel)
    img = img_to_array(load_img(path, target_size=(imgHeight, imgWidth)))

    if path.split(os.path.sep)[-3] == 'training_set':
        trainingImages.append(img)
        trainingLabels.append(classLabel)
    else:
        validationImages.append(img)
        validationLabels.append(classLabel)

trainingImages = np.array(trainingImages)
trainingLabels = np.array(trainingLabels)
validationImages = np.array(validationImages)
validationLabels = np.array(validationLabels)

When I print the shape() of the trainingImages and trainingLabels I get:

Shape of trainingImages: (8000, 32, 32, 3)
Shape of trainingLabels: (8000,)

My model looks like this:

model = Sequential()
model.add(Conv2D(
        32, (3, 3), padding="same", input_shape=inputShape))
model.add(Activation("relu"))
model.add(Flatten())
model.add(Dense(len(classes)))
model.add(Activation("softmax"))

And when I compile and try to fit the data, I get: ValueError: Error when checking target: expected activation_2 to have shape (2,) but got array with shape (1,)

Which tells me my data is not input into the system correctly. How can I properly prepare my data arrays without using ImageDataGenerator?

Upvotes: 2

Views: 828

Answers (1)

Ankur Ankan
Ankur Ankan

Reputation: 3066

The error is because of your model definition instead of ImageDataGenerator (which I don't see used in the code you have posted). I am assuming that len(classes) = 2 because of the error message that you are getting. You are getting the error because the last layer of your model expects trainingLabels to have a vector of size 2 for each datapoint but your trainingLabels is a 1-D array.

For fixing this, you can either change your last layer to have just 1 unit because it's binary classification:

model.add(Dense(1))

or you can change your training and validation labels to vectors using one hot encoding:

from keras.utils import to_categorical
training_labels_one_hot = to_categorical(trainingLabels)
validation_labels_one_hot = to_categorical(validationLabels)

Upvotes: 1

Related Questions