CNN layers confusion

Question:

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!

Asked By: pew

||

Answers:

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:

enter image description here

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 🙂

Answered By: pew
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.