Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you create a boolean mask for a tensor in Keras?

I am building a custom metric to measure the accuracy of one class in my multi-class dataset during training. I am having trouble selecting the class.

The targets are one hot (e.g: the class 0 label is [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

The trouble is, we have to use Keras functions to index tensors. How do you create a boolean mask for a tensor?

like image 702
Chris Parry Avatar asked Jan 04 '17 07:01

Chris Parry


People also ask

How do you make a boolean mask?

To create a boolean mask from an array, use the ma. make_mask() method in Python Numpy. The function can accept any sequence that is convertible to integers, or nomask. Does not require that contents must be 0s and 1s, values of 0 are interpreted as False, everything else as True.

What is TF Boolean_mask?

boolean_mask , which can be applied to both dense and ragged tensors, and can be used if you need to preserve the masked dimensions of tensor (rather than flattening them, as tf. boolean_mask does).

What is masking in keras?

Masking is a way to tell sequence-processing layers that certain timesteps in an input are missing, and thus should be skipped when processing the data. Padding is a special form of masking where the masked steps are at the start or the end of a sequence.

What is boolean masking?

Boolean masking is typically the most efficient way to quantify a sub-collection in a collection. Masking in python and data science is when you want manipulated data in a collection based on some criteria. The criteria you use is typically of a true or false nature, hence the boolean part.


1 Answers

Note that when talking about the accuracy of one class one may refer to either of the following (not equivalent) two amounts:

  • The recall, which, for class C, is the ratio of examples labelled with class C that are predicted to have class C.
  • The precision, which, for class C, is the ratio of examples predicted to be of class C that are in fact labelled with class C.

Instead of doing complex indexing, you can just rely on masking for you computation. Assuming we are talking about precision here (changing to recall would be 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

If you want to be more flexible, you can also have the class of interest parametrised:

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

And the use it as:

model.compile(..., metrics=[single_class_accuracy(INTERESTING_CLASS_ID)])
like image 131
jdehesa Avatar answered Oct 25 '22 02:10

jdehesa