0
$\begingroup$

I am doing image classificaition, and to do this I have built the following neural network:

def Network(input_shape, num_classes, regl2 = 0.0001, lr=0.0001):

model = Sequential()

# C1 Convolutional Layer 
model.add(Conv2D(filters=96, input_shape=input_shape, kernel_size=(3,3),\
                 strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation before passing it to the next layer
model.add(BatchNormalization())

# C2 Convolutional Layer
model.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())

# C3 Convolutional Layer
model.add(Conv2D(filters=768, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Batch Normalisation
model.add(BatchNormalization())

# C4 Convolutional Layer
model.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Batch Normalisation
model.add(BatchNormalization())

# C5 Convolutional Layer
model.add(Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())

# C6 Convolutional Layer
model.add(Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())

# C7 Convolutional Layer
model.add(Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))
# Batch Normalisation
model.add(BatchNormalization())

# Flatten
model.add(Flatten())

flatten_shape = (input_shape[0]*input_shape[1]*input_shape[2],)

# D1 Dense Layer
model.add(Dense(4096, input_shape=flatten_shape, kernel_regularizer=regularizers.l2(regl2)))
model.add(Activation('relu'))
# Dropout
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())

# D2 Dense Layer
model.add(Dense(4096, kernel_regularizer=regularizers.l2(regl2)))
model.add(Activation('relu'))
# Dropout
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())

# D3 Dense Layer
model.add(Dense(1000,kernel_regularizer=regularizers.l2(regl2)))
model.add(Activation('relu'))
# Dropout
model.add(Dropout(0.4))
# Batch Normalisation
model.add(BatchNormalization())

# Output Layer
model.add(Dense(num_classes))
model.add(Activation('softmax'))

# Compile

adam = optimizers.Adam(lr=lr)
model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy'])

return model

  # create the model
  model = Network(input_shape,num_classes)
  model.summary()

it works good enough, but I would like to increase its performances.

How could I modify it to do so?

I was thinking about adding layers, which should give better performances, but I haven' t understand well if I should add convolutional layers or dense layers. Moreover I would like to find other ways to increase accuracy than simply adding layers.

Can somebody please help me?

Thanks in advance.

[EDIT] I am considering a training set of 1200 images, which represent 4 wheater conditions : Haze, Rainy, Snowy, Sunny.

With my model, the Test accuracy is 0.797500, and the Test loss is 1.881952.

I would like to increase more my accuracy, but I don' t have other ideas than adding convolutional layers. I could try to change the size of the kernels and other hyperparameters, but I have other ideas.

$\endgroup$
2
  • $\begingroup$ It might help if you also share some details of your dataset - number of images you are using in particular. If it is not large enough, adding more layers may not always mean better results. Also, it is not very clear what you mean by "works well enough". What is training/validation performance like? A quantitative description is always better. And finally if your sole purpose is to do image recognition, make sure you look into "transfer learning" before building a model from scratch. $\endgroup$
    – serali
    Dec 2, 2019 at 16:56
  • $\begingroup$ Thanks for answering. I have edited the question with more details. Regarding transfer learning, I would like to learn building a CNN which performs well also when created by scratch. Thanks again. $\endgroup$
    – J.D.
    Dec 2, 2019 at 17:22

2 Answers 2

0
$\begingroup$

It sounds like the model is underfit; to verify this, you would check that training and testing accuracy are similar, but, both lower than desired.

One cause is likely the very low number of training images for a model of this complexity.

You could try augmenting the training set with transformations of those images, for example by rotating the images in the training set? (This was done in the original alexnet paper: http://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf see section 4.1 on p.5).

$\endgroup$
0
$\begingroup$

Try adding more images , also make sure that your dataset is balanced ie, there arent too many images of a single kind , that would lead to your model overfitting for that particular class. I was facing a similar issue when I trained an emotion classifier , also try transfer learning based on well known CNN architectures such as the VGG16 or RESNET.

$\endgroup$

Your Answer

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

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