In class-wise accurcy calcualtion model predicing for one class only in case of binary

Viewed 26

In the case of class-wise prediction, the model is predicting for one class 0 only and not for class 1 in the case of binary classification, but in the case of multiclass classification, the same model with modifications in code is working fine. Could it be related to the loss function or activation function used as sigmoid?

The output is as:
Epoch 5/5
19/19 [==============================] - 144s 8s/step - loss: 0.0232 - accuracy: 0.9884 
- acc_1_0: 1.0000 - acc_1_1: 0.0000e+00 - prec_1_0: 1.0000 - recall_1_0: 1.0000 - 
prec_1_1: 0.0000e+00 - recall_1_1: 0.0000e+00 - val_loss: 0.0057 - val_accuracy: 1.0000 
- val_acc_1_0: 1.0000 - val_acc_1_1: 0.0000e+00 - val_prec_1_0: 1.0000 - val_recall_1_0: 
1.0000 - val_prec_1_1: 0.0000e+00 - val_recall_1_1: 0.0000e+00


code:
 from keras.preprocessing.image import ImageDataGenerator
 train_datagen=ImageDataGenerator(rescale=1./255)
 test_datagen = ImageDataGenerator(rescale=1./255)
data_dir1='Flower2'
data_dir2='Flower'

train_generator = train_datagen.flow_from_directory( data_dir1, target_size=(180, 180), 
batch_size=32, shuffle=True, class_mode='binary')

val_generator = test_datagen.flow_from_directory( data_dir2, target_size=(180, 180), 
batch_size=32, shuffle=True, class_mode='binary')

x_test, y_test=next(val_generator)

interesting_class_id=0

def single_class_accuracy(interesting_class_id):
    def acc1(y_true, y_pred):
        class_id_true = K.argmax(y_true, axis=-1)
        class_id_preds = K.argmax(y_pred, axis=-1)
        accuracy_mask = K.cast(K.equal(class_id_preds, interesting_class_id), 'int32')
        class_acc_tensor = K.cast(K.equal(class_id_true, class_id_preds), 'int32') * 
        accuracy_mask
        class_acc = K.cast(K.sum(class_acc_tensor), 'float32') / 
  K.cast(K.maximum(K.sum(accuracy_mask), 1), 'float32')
        return class_acc
acc1.__name__ = 'acc_1_{}'.format(interesting_class_id)
return acc1

def single_class_precision(interesting_class_id):
    def prec(y_true, y_pred):
        class_id_true = K.argmax(y_true, axis=-1)
        class_id_pred = K.argmax(y_pred, axis=-1)
        precision_mask = K.cast(K.equal(class_id_pred, interesting_class_id), 'int32')
        class_prec_tensor = K.cast(K.equal(class_id_true, class_id_pred), 'int32') * 
    precision_mask
        class_prec = K.cast(K.sum(class_prec_tensor), 'float32') / 
K.cast(K.maximum(K.sum(precision_mask), 1), 'float32')
    return class_prec
 prec.__name__ = 'prec_1_{}'.format(interesting_class_id)

return prec

def single_class_recall(interesting_class_id):
    def recall(y_true, y_pred):
        class_id_true = K.argmax(y_true, axis=-1)
        class_id_pred = K.argmax(y_pred, axis=-1)
        recall_mask = K.cast(K.equal(class_id_true, interesting_class_id), 'int32')
        class_recall_tensor = K.cast(K.equal(class_id_true, class_id_pred), 'int32') * 
recall_mask
     class_recall = K.cast(K.sum(class_recall_tensor), 'float32') / 
K.cast(K.maximum(K.sum(recall_mask), 1), 'float32')
    return class_recall
recall.__name__ = 'recall_1_{}'.format(interesting_class_id)

return recall

model = Sequential()

pretrained_model= tf.keras.applications.VGG16(include_top=False,
               input_shape=(180,180,3),
               pooling='avg',classes=2,
               weights='imagenet',
               classifier_activation= 'sigmoid'
               )
             
for layer in pretrained_model.layers:
    layer.trainable=False

model.add(pretrained_model)



model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.summary()

model.compile(loss='binary_crossentropy', optimizer=Adam(lr=0.01), 
          metrics=['accuracy',
                   single_class_accuracy(0), single_class_accuracy(1),
                  
                   single_class_precision(0), single_class_recall(0),
                   single_class_precision(1), single_class_recall(1),
                                       ])

hist = model.fit(train_generator, validation_data=val_generator, epochs=5, 
batch_size=32)
1 Answers

The issue was with the activation function, I changed the code to use softmax instead of sigmoid, may it was getting metrics values for one class only in the case of binary.

Related