Keras Custom Metric para precisión de una sola clase

Estoy creando una métrica personalizada para medir la precisión de una clase en mi conjunto de datos de varias clases durante la capacitación. Estoy teniendo problemas para seleccionar la clase.

Los objectives son uno candente (por ejemplo: la etiqueta de la clase 0 es [1 0 0 0 0]:

from keras import backend as K def single_class_accuracy(y_true, y_pred): idx = bool(y_true[:, 0]) # boolean mask for class 0 class_preds = y_pred[idx] class_true = y_true[idx] class_acc = K.mean(K.equal(K.argmax(class_true, axis=-1), K.argmax(class_preds, axis=-1))) # multi-class accuracy return class_acc 

El problema es que tenemos que usar las funciones de Keras para indexar los tensores. ¿Cómo se crea una máscara booleana para un tensor? Gracias.

Tenga en cuenta que cuando se habla de la precisión de una clase, uno puede referirse a cualquiera de las siguientes dos cantidades (no equivalentes):

  • La precisión , que, para la clase C , es la proporción de ejemplos etiquetados con la clase C que se predice que tienen la clase C.
  • El retiro , que, para la clase C , es la proporción de ejemplos que se predice que son de la clase C que de hecho están etiquetados con la clase C.

En lugar de hacer una indexación compleja, solo puede confiar en el enmascaramiento para su cálculo. Suponiendo que estamos hablando de precisión aquí (cambiar para recordar sería trivial).

 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 

Si desea ser más flexible, también puede tener la clase de interés parametrizada:

 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 

Y la usamos como:

 model.compile(..., metrics=[single_class_accuracy(INTERESTING_CLASS_ID)])