0
$\begingroup$

Well, I need to do a CNN to classify if a Image is from one or another class. But my model return high losses (6.~8.) and low accuracies (0.50 on max). I tried to include more layers, change my activation functions, and nothing works. My database is 142 .jpg imgs (71 for each class)

This is my code: OLD CODE

def ReadImages(Path):
    LabelList = list()
    ImageCV = list()
    classes = ["nonPdr", "pdr"]

    # Get all subdirectories
    FolderList = [f for f in os.listdir(Path) if not f.startswith('.')]
    print(FolderList)

    # Loop over each directory
    for File in FolderList:
        for index, Image in enumerate(os.listdir(os.path.join(Path, File))):
            # Convert the path into a file
            ImageCV.append(cv2.resize(cv2.imread(os.path.join(Path, File) + os.path.sep + Image), (600,700)))
            LabelList.append(classes.index(os.path.splitext(File)[0])) 

    return ImageCV, LabelList

model = Sequential()
model.add(Conv2D(64, kernel_size=(3,3), padding="same",activation="relu", input_shape=(700,600,3)))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128,  kernel_size=(4,4), padding="same",activation="relu"))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='RMSprop', loss='binary_crossentropy', metrics=['accuracy'])

data, labels = ReadImages(TRAIN_DIR)

model.fit(np.array(data), np.array(labels), epochs=10, batch_size=20)

model.save('model.h5')

What can I do to improve my model? I appreciate your help!

UPDATE I tried to do what Shubham Panchal said but isn't resolve the problem:

THINGS THAT I TRIED - Reduce Img size
- lr=0.0001
- optimizers: adam, sgd, rmsprop
- put more layers
- put dropout layer
- normalize the data with np.array(data) / 255.0
- Increase the data (1400 total, 700 each class)

My code:

model = Sequential()
model.add(Conv2D(64, kernel_size=(3,3), padding="same",activation="relu", input_shape=(150,150,3)))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(64, kernel_size=(3,3), padding="same",activation="relu"))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128,  kernel_size=(3,3), padding="same",activation="relu"))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128,  kernel_size=(3,3), padding="same",activation="relu"))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(1, activation='softmax'))
opt = SGD(lr=0.0001, momentum=0.9)
model.compile(optimizer = opt, loss="binary_crossentropy", metrics=['accuracy'])
#model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

data, labels = ReadImages(TRAIN_DIR)

model.fit(np.array(data) / 255.0, np.array(labels), epochs=10, batch_size=16)

My console:

Epoch 1/10
1400/1400 [==============================] - 58s 42ms/step - loss: 7.9712 - acc: 0.5000
Epoch 2/10
1400/1400 [==============================] - 59s 42ms/step - loss: 7.9712 - acc: 0.5000
Epoch 3/10
1400/1400 [==============================] - 59s 42ms/step - loss: 7.9712 - acc: 0.5000
...

Anyone have any ideia what can I do??

$\endgroup$

1 Answer 1

1
$\begingroup$

Here are some hacks which you can use to improve then model.

The dataset seems to be inadequate. Try image augmentation.

Image augmentation basically applies to different transformations to your images. Like the rotation, scale, color, whitening etc. are changed. It helps the model to generalise better on the image. See here.

Use softmax classification function.

Instead of sigmoid, try softmax activation function since you are working on a classification task. Sigmoid is mostly reserved for binary classification tasks.

model.add(Dense(1, activation='softmax'))

Add more convolution layers.

Consider adding more Conv2D layers to the model because the image size is quite large. More the number of layers, the better feature extraction will take place. Due to less layers, your model is not able to extract smaller features which may be required for proper classification.

Tips:

  1. Try adam optimizer instead of rmsprop.
  2. Restrict the kernel size to ( 3 , 3 ).
  3. Use a smaller batch size. Your batch size is 20 for 142 images. That makes only ~7 batches. Lower it to a number like 6 or 10.
  4. Use Dropout layers in between the Dense layers.
  5. The smaller learning rate always helps like 0.001 or 0.0001.
$\endgroup$
9
  • $\begingroup$ Thanks for your answer, please see my update $\endgroup$
    – 0nroth1
    Sep 4, 2019 at 12:21
  • $\begingroup$ Also, try adding more Conv2D layers as mentioned. $\endgroup$ Sep 4, 2019 at 14:18
  • $\begingroup$ I'd introduced 6 layers (32,32,64,64,128,128) and it still doens't working $\endgroup$
    – 0nroth1
    Sep 4, 2019 at 19:00
  • $\begingroup$ Maybe you can Dropout layers or Adam optimizer. $\endgroup$ Sep 5, 2019 at 0:20
  • $\begingroup$ I try to put Adam(lr=0,0001) and the dropout, but the problem persists loss '4~9' and acc '0.2~0.5' $\endgroup$
    – 0nroth1
    Sep 5, 2019 at 0:57

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.