3
$\begingroup$

I am a beginner in Deep Learning and working on Road Crack detection using transfer learning. I am working on binary classification with two classes , crack and no crack.

My distribution of two classes is as follows:

Cracks - 600 images

No cracks - 480 images

I have used data augmentation also :

 train_generator = train_datagen.flow(trainX, trainY, batch_size=16)

 val_generator = test_datagen.flow(testX, testY, batch_size= 16)

I am using VGG16 and I have frozen the lower 4 layers like this :

vgg = vgg16.VGG16(include_top=False, weights='imagenet', 
                                 input_shape=input_shape)

output = vgg.layers[-1].output

output = keras.layers.Flatten()(output)

vgg_model = Model(vgg.input, output)

for layer in vgg_model.layers[:4]:

     layer.trainable = False

After that, I added two hidden layers :

model = Sequential()
model.add(vgg_model)
model.add(Dense(256, activation='relu', input_dim=input_shape))
model.add(Dense(256, activation='relu'))
model.add(Dense(2, activation='softmax')) 
model.compile(loss='binary_crossentropy',
          optimizer=Adam(lr = 1e-6),
          metrics=['accuracy'])

But after 1-2 epochs nothing seems to change, neither validation accuracy nor loss. I tried using SGD optimizer also but that also didn't help. I added more layers also but didn't have any effect on accuracy and loss.The maximum validation accuracy achieved is 62%.

I tried testing an image from my dataset, for that also model gives wrong prediction. For every test image it predicts as crack, i.e label 1.

Could someone suggest how i can improve this? Thanks!

$\endgroup$
2
$\begingroup$

Transfer learning is done by chopping off the last layer in the pre-trained network (in your case it is VGG16) and add a dense layer depending on the number of classes you need and then train the new model.

The reason why your model is not working is that you are taking the output from the last layer of the vgg16, which is activated by a softmax layer. And one cannot learn something from a softmax layer especially for transfer learning.

Rewrite your code as

from keras.models import Model
from keras.layers import Dense

X = vgg_model.layers[-1].output #will give 4096 feature vector as an output
X = Dense(256, activation ='relu')(X)
X = Dense(256, activation ='relu')(X)
X = Dense(2, activation ='softmax')(X)
newmodel = Model(vgg_model.layers[0].output,X)
newmodel.compile(loss='binary_crossentropy',
          optimizer=Adam(lr = 1e-6),
          metrics=['accuracy'])
$\endgroup$
  • $\begingroup$ I have already done this.Forgot to add in my code snippet here. Will edit it $\endgroup$ – Shreya Apr 6 '19 at 4:47
1
$\begingroup$

Just take 2 images from your training data. One from class 'crack', another one from class 'not crack'. Now, check if your model can get a training accuracy of 100% which means it can overfit on the training dataset or not. If it is not able to do that, something is extremely wrong about the model.

$\endgroup$
  • $\begingroup$ Yes i tried with two images, training accuracy is 100% only $\endgroup$ – Shreya Apr 4 '19 at 9:24
  • $\begingroup$ Try freezing some more lower layers(the ones closer to the input). Start with freezing all the conv layers. Your dataset seems to be too small for learning that many parameters without overfitting. For checking whether the model overfits, track the training accuracies along with validation accuracies throughout the training epochs. Also, consider lowering the learning rate when you unfreeze some conv layers starting from the top(closer to the output node) so that the previously learned parameters are not completely morphed. $\endgroup$ – Sajid Ahmed Apr 4 '19 at 9:35
  • $\begingroup$ Actually my model is underfitting because the training loss is always higher than validation loss and training accuracy lower than validation accuracy $\endgroup$ – Shreya Apr 4 '19 at 10:06
  • $\begingroup$ Use 'categorical_crossentropy' as loss function instead of 'binary_crossentropy' since you are using 'softmax' as activation function in your output layer. I hope you have already encoded your classes in one-hot format before applying softmax....................................................... for binary_crossentropy: sigmoid activation, scalar target for categorical_crossentropy: softmax activation, one-hot encoded target $\endgroup$ – Sajid Ahmed Apr 4 '19 at 11:23
  • $\begingroup$ Yes i one-hot encoded before using binary_cross entropy. I changed to categorical_cross entropy as well but there is no change in accuracy, its constant 57% $\endgroup$ – Shreya Apr 4 '19 at 13:02
1
$\begingroup$

The problem with your code is inconsistency of the goal you are willing to operate upon. Softmax calculates the probability of individual neuron and a binary classifier contains single neuron to operate. Hence softmax is never used in binary classification and we rather use sigmoid.

So simply change the following

model = Sequential()
model.add(vgg_model)
model.add(Dense(256, activation='relu', input_dim=input_shape))
model.add(Dense(256, activation='relu'))
model.add(Dense(1, activation='sigmoid')) 
model.compile(loss='binary_crossentropy',
          optimizer=Adam(lr = 1e-6),
          metrics=['accuracy'])

Talking about this model, I should say that the lower layers you have unfrozen are the layers that learn low level features like edges, so even though you have trained the lower layers it still might not have been able to detect the cracks from a higher level. As a recommendation, I would suggest you to make the higher layers of the model trainable and reduce the complexity of your model. This would improve your model.

$\endgroup$
  • $\begingroup$ But I have frozen the lower layers not the higher layers. $\endgroup$ – Shreya Apr 10 '19 at 11:24
  • $\begingroup$ I tried to run your model and somehow it didn't threw the same problem as you are facing. In my case, the model was learning (accuracy was improving). Can you share your notebook for better understanding? $\endgroup$ – thanatoz Apr 10 '19 at 12:04
  • $\begingroup$ Yes sure! How can I share? $\endgroup$ – Shreya Apr 10 '19 at 14:58
  • $\begingroup$ Upload it somewhere and add the link in the comment. $\endgroup$ – thanatoz Apr 11 '19 at 4:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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