Ответ 1
Обратите внимание, что, говоря о точности одного класса, можно обратиться к одному из следующих (не эквивалентных) двух значений:
- точность, которая для класса C является отношением примеров, помеченных классом C, которые, как прогнозируется, имеют класс C.
- отзыв, который для класса C представляет собой отношение примеров, которые, как предполагается, относятся к классу C, которые на самом деле помечены классом C.
Вместо выполнения сложной индексации вы можете просто полагаться на маскировку для вас вычислений. Предполагая, что мы говорим о точности здесь (изменение на вызов было бы тривиальным).
from keras import backend as K
INTERESTING_CLASS_ID = 0 # Choose the class of interest
def single_class_accuracy(y_true, y_pred):
class_id_true = K.argmax(y_true, axis=-1)
class_id_preds = K.argmax(y_pred, axis=-1)
# Replace class_id_preds with class_id_true for recall here
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.sum(class_acc_tensor) / K.maximum(K.sum(accuracy_mask), 1)
return class_acc
Если вы хотите быть более гибким, вы также можете присвоить класс интереса:
from keras import backend as K
def single_class_accuracy(interesting_class_id):
def fn(y_true, y_pred):
class_id_true = K.argmax(y_true, axis=-1)
class_id_preds = K.argmax(y_pred, axis=-1)
# Replace class_id_preds with class_id_true for recall here
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.sum(class_acc_tensor) / K.maximum(K.sum(accuracy_mask), 1)
return class_acc
return fn
И используйте его как:
model.compile(..., metrics=[single_class_accuracy(INTERESTING_CLASS_ID)])