Model calculating accurcy of only class 0 in class-wise accuracy evaluation

Viewed 35

My code is given below, I am only getting the accuracy of the class 0 instead of all the classes. The output is Epoch 1/2 58/58 [==============================] - 424s 7s/step - loss: 4.7356 - accuracy: 0.5317 - acc_1_0: 0.9655 - acc_1_1: 0.0000e+00 - acc_1_2: 0.0000e+00 - acc_1_3: 0.0000e+00 - acc_1_4: 0.0000e+00 - recall_1_0: 0.2252 - recall_1_1: 0.0000e+00 - prec_1_0: 0.9655 - prec_1_1: 0.0000e+00 - val_loss: 0.9262 - val_accuracy: 0.6447 - val_acc_1_0: 1.0000 - val_acc_1_1: 0.0000e+00 - val_acc_1_2: 0.0000e+00 - val_acc_1_3: 0.0000e+00 - val_acc_1_4: 0.0000e+00 - val_recall_1_0: 0.2062 - val_recall_1_1: 0.0000e+00 - val_prec_1_0: 1.0000 - val_prec_1_1: 0.0000e+00

The code on https://tykimos.github.io/2017/09/24/Custom_Metric/ is working perfectly find. I think the issue is with the preprocessing function used to process the data because in the given example in the URL, they are using mnist dataset. and extracting data as x_train, y_train while with tf.keras.preprocessing.image_dataset_from_directory the dataset as a whole is fed to fit. Please help to resolve this issue. Thanks

train_ds = tf.keras.preprocessing.image_dataset_from_directory(
   data_dir, labels ='inferred', label_mode='int',
   validation_split=0.2,
   subset="training",
   seed=123,
   image_size=(img_height, img_width),
   batch_size=batch_size)

val_ds = tf.keras.preprocessing.image_dataset_from_directory(
   data_dir, labels ='inferred', label_mode='int',
  validation_split=0.2,
  subset="validation",
  seed=123,
  image_size=(img_height, img_width),
  batch_size=batch_size)

resnet_model = Sequential()
pretrained_model= tf.keras.applications.VGG16(include_top=False,
               input_shape=(180,180,3),
               pooling='avg',classes=5,
               weights='imagenet',
               #classifier_activation= 'sigmoid')
              classifier_activation= 'softmax')

for layer in pretrained_model.layers: layer.trainable=False

resnet_model.add(pretrained_model)
resnet_model.add(Flatten())
resnet_model.add(Dense(512, activation='relu'))
resnet_model.add(Dense(5, activation='softmax'))
interesting_class_id = 0  # Choose the class of interest
from keras import backend as K

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_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

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







 resnet_model.compile(optimizer=Adam(lr=0.01),loss='sparse_categorical_crossentropy',
  metrics=[
                    'accuracy',
                     single_class_accuracy(0),  
                     single_class_accuracy(1),
                     single_class_accuracy(2),
                     single_class_accuracy(3),
                     single_class_accuracy(4),
                     single_class_recall(0),
                     single_class_recall(1),
                     single_class_precision(0),  
                    single_class_precision(1)
                   ])
 history = resnet_model.fit(train_ds, validation_data=val_ds, epochs=2)
1 Answers

My code is given below, I am only getting the accuracy of the class 0 instead of all the classes... probably because accuracy is meant to do exactly that... what you probably are looking for, are precision and recall

Related