Reputation: 27
I have this model which is attempting to classify cats and dogs:
model = Sequential([Conv2D(128, kernel_size=(3,3), activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
MaxPooling2D(pool_size=(2,2)),
Conv2D(64, kernel_size=(3,3), activation='relu'),
MaxPooling2D(pool_size=(2,2)),
Flatten(),
Dense(32, activation='relu'),
Dense(2, activation='softmax')]) # pick between 2 different possible outputs
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
and then attempting to run the model like so:
history = model.fit(x=train_data_gen, steps_per_epoch=total_train//batch_size,
epochs=epochs, batch_size=batch_size,
validation_data=val_data_gen,
validation_steps=total_val//batch_size)
however, I get this ValueError:
ValueError: `logits` and `labels` must have the same shape, received ((None, 2) vs (None, 1)).
If I change the last dense layer to have a dimensionality of 1, then this runs, but I want a binary classification with 2 output layers to which I softmax between them to analyze the testing data.
How do I fix my train_data_gen
in order to match the dimensionality, as it is a keras.preprocessing.image.DirectoryIterator
object defined like so:
train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size,
directory=train_dir,
target_size=(IMG_HEIGHT, IMG_WIDTH),
class_mode='binary')
Is there a way I can reshape this object so my model runs correctly, because I can't seem to find it with regards to this object, or if I need to convert this into a numpy array or tensor first. Also, how do I classify dimensionality/filter arguments in these models? I went with 128, 64, 32, and cutting by 2 because this is what I saw online, but if an explanation could be provided as to why these values are picked that would greatly help me out. Thank you in advance for the help!
Upvotes: 0
Views: 52
Reputation: 27
Thanks Jay Mody for your response. I was away on holiday and taking a break from this project, but yes what you suggested was correct and useful to actually understand what I was doing. I also wanted to mention a few other errors I had which led to a worse/useless model performance.
The steps_per_epoch
and validation_steps
arguments were not totally incorrect, but produced weird graphs that I didn't see in other online examples
I learned how they are implemented through this website, in my case substituting the training images and validation images counts as the corresponding sizes. Now my graph looks like so:
Also I played around with my filter(s) arguments for my model, and found this resource helpful. My model now looks like so, and works well:
model = Sequential([Conv2D(32, kernel_size=(3,3), activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH, 3)),
MaxPooling2D(pool_size=(2,2)),
Conv2D(32, kernel_size=(3,3), activation='relu'),
MaxPooling2D(pool_size=(2,2)),
Flatten(),
Dense(128, activation='relu'),
Dense(1, activation='sigmoid')]) # pick between 2 different possible outputs
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
Hope this helps others, this whole field still confuses me but we go on :)
Upvotes: 1