pew
pew

Reputation: 27

CNN layers confusion

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

Answers (1)

pew
pew

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:

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 :)

Upvotes: 1

Related Questions