I am getting the following error, I am trying to get class-wise accuracy on training data. I have installed the latest TensorFlow and Keras, could anyone please help with the error? Thanks
Error:
**raise ValueError('Found two metrics with the same name: {}'.format(
ValueError: Found two metrics with the same name: acc1**
Code:
resnet_model.summary()
from keras import backend as K
#interesting_class_id = 0 # Choose the class of interest
def single_class_accuracy(interesting_class_id):
def acc1(y_true, y_pred):
class_id_true = K.argmax(y_true)
class_id_preds = K.argmax(y_pred)
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
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
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
return prec
resnet_model.compile(optimizer=Adam(lr=0.01),loss='binary_crossentropy',metrics=[
'accuracy',
single_class_accuracy(0),
single_class_accuracy(1),
single_class_recall(0),
single_class_recall(1),
single_class_precision(0),
single_class_precision(1)
])
resnet_model.save('my_model')
history = resnet_model.fit(train_ds, validation_data=val_ds, epochs=20)
CodePudding user response:
You can't add multiple metrics in metrics
argument, changing only the parameter with which you call the metric. During the fit of your model, it will detect that you have multiple metrics with same name. The name is automatically set as the name of the inner metric function: acc1
, recall
and prec
in your case.
So when it goes through your metrics
, it will find single_class_accuracy(0)
and will call it acc1
, then will find single_class_accuracy(1)
and will try to call it acc1
too, which leads to the error.
What you can do is set different names to your metric functions, like so:
def single_class_accuracy(interesting_class_id):
def acc1(y_true, y_pred):
class_id_true = K.argmax(y_true)
class_id_preds = K.argmax(y_pred)
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
# setting a name according to your additional parameter
acc1.__name__ = 'acc_1_{}'.format(interesting_class_id)
return acc1