Hi I am new in Keras with back-end tensorflow. I have build my training and validation set of images of two possible classes; my network has to end with two classes yes or not. I have used ImageDatagenerator to read the images from the folders and prepare the training and the validation set. At the end I get the issue described in the Title. My guess is that the ImageDatagenerator is not preparing the data as I would like; Any body can explain to me how to solve it, here is the code (THANKS):
# Data Preparation
# dimensions of our images.
img_width, img_height = 256, 256
#top_model_weights_path = 'bottleneck_fc_model.h5'
train_data_dir = 'data/train'
validation_data_dir = 'data/validation'
nb_train_samples = 2
nb_validation_samples = 2
epochs = 50
batch_size = 1
num_classes = 2
# prepare data augmentation configuration
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
data_format=K.image_data_format(),
horizontal_flip=True)
test_datagen = ImageDataGenerator(
rescale=1. / 255,
data_format=K.image_data_format())
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='binary')
# create the CNN model
model = Sequential()
model.add(Conv2D(24, kernel_size=(20, 20), strides=(2,2), padding='valid', activation='relu', input_shape=(256,256,3)))
model.add(MaxPooling2D(pool_size=(7, 7), strides=(2,2), padding='valid'))
# Avoiding overfitting
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(64, activation='relu'))
# Avoiding overfitting
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
print(model.summary())
# Compile model
sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mean_squared_error', optimizer='sgd', metrics=['accuracy'])
# Fit the model
model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size,
verbose=0)
# Save the weights
model.save_weights('first_try.h5')
Specifically for "two classes", there are two ways of doing it:
Each one requires a different model output:
Dense(1,....)
Dense(2,....)
You seem to be in the first case, so, change your last layer.
What does that error mean?
Your model outputs things with shape (BatchSize, 2), but your class labels have shape (BatchSize,1).
If you need a single output that predicts either 0 or 1 then just change your last layer to
model.add(Dense(1, activation='softmax'))
However, if you need two outputs per each of your classes then use categorical class mode for your train and validation generators, namely,
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
<...>
model.add(Dense(2, activation='softmax'))
To summarize:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With