3

I'm building a simple CNN Model for multi class classification. The training and test data is in data_path according to the classes sub directories as required by the flow_from_directory function of ImageDataGenerator.

Here's my code to build and train the model on the data:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dropout, Flatten, Dense, Conv2D, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# Build Model

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(40, 24, 1)))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(12, activation='softmax'))

model.compile('binary_crossentropy', 'SGD', ['accuracy'])

# Init Generators

generator = ImageDataGenerator(rescale=1./255,
                               horizontal_flip=True,
                               fill_mode='nearest',
                               validation_split=0.2)

def get_train_images():
    train_images = generator.flow_from_directory(os.path.join(data_path, 'train'),
                                                 target_size=(40, 24, 1),
                                                 batch_size=32,
                                                 color_mode='grayscale',
                                                 class_mode='categorical',
                                                 subset='training',
                                                 shuffle=True)

def get_validation_images():
    validation_images = generator.flow_from_directory(os.path.join(data_path, 'train'),
                                                      target_size=(40, 24, 1),
                                                      batch_size=32,
                                                      color_mode='grayscale',
                                                    class_mode='categorical',
                                                      subset='validation',
                                                      shuffle=True)

# Train Model

model.fit(get_train_images, validation_data=get_validation_images, epochs=20)

The fit function gives the following error:

File "C:\Python38\lib\site-packages\tensorflow\python\keras\engine\training.py", line 108, in _method_wrapper
    return method(self, *args, **kwargs)
  File "C:\Python38\lib\site-packages\tensorflow\python\keras\engine\training.py", line 1049, in fit
    data_handler = data_adapter.DataHandler(
  File "C:\Python38\lib\site-packages\tensorflow\python\keras\engine\data_adapter.py", line 1104, in __init__
    adapter_cls = select_data_adapter(x, y)
  File "C:\Python38\lib\site-packages\tensorflow\python\keras\engine\data_adapter.py", line 968, in select_data_adapter
    raise ValueError(
ValueError: Failed to find data adapter that can handle input: <class 'method'>, <class 'NoneType'>

It looks to be some sort of compatability issues. I'm using tensorflow version 2.3.1. Can someone point out what I'm doing wrong and help me solve this issue?

Thanks!

1
  • 1
    I believe, one of the argument provided to fit() is None. Commented Dec 8, 2020 at 22:13

2 Answers 2

4

There are 2 things I had to change to fix the issue:

  • The target size to flow_from_directory should be (40, 24) and not (40, 24, 1)
  • I had function wrappers to get the flow_from_directory generators and I was passing these functions to the fit function as parameters. Instead, I had to pass the return value of these wrappers to the fit function

The correct way should be:

model.fit(get_train_images(), validation_data=get_validation_images(), epochs=20)
Sign up to request clarification or add additional context in comments.

Comments

1

did you execute

model=model.compile(tf.keras.optimizers.Adam(), loss='categorical_crossentropy', metrics=['accuracy']) 

For the validation_images in flow_from_directory set shuffle=False that way the validation data is presented in the same order to the model for each epoch.

2 Comments

Yes, I forgot to mention. I did compile the model using model.compile('binary_crossentropy', 'SGD', ['accuracy'])
you should use categorical_crossentropy in model.compile as that is used by the generators and you have 12 neurons in your classification layer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.