如何在 Keras 中为张量创建布尔掩码?
How do you create a boolean mask for a tensor in Keras?
我正在构建一个自定义指标来衡量训练期间我的多 class 数据集中一个 class 的准确性。我在选择 class 时遇到问题。
目标是一个热点(例如:class 0
标签是 [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
麻烦的是,我们必须使用 Keras 函数来索引张量。如何为张量创建布尔掩码?
请注意,在谈论一个 class 的 准确度 时,可能指的是以下两个量之一(不等价):
- recall,对于classC,是标有class的样本比例C 预测有 class C.
- 精度,其中,对于class C,是预测为[=45的示例的比率=] C 实际上标有 class 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
如果你想更灵活,你也可以将class感兴趣的参数化:
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)])
我正在构建一个自定义指标来衡量训练期间我的多 class 数据集中一个 class 的准确性。我在选择 class 时遇到问题。
目标是一个热点(例如:class 0
标签是 [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
麻烦的是,我们必须使用 Keras 函数来索引张量。如何为张量创建布尔掩码?
请注意,在谈论一个 class 的 准确度 时,可能指的是以下两个量之一(不等价):
- recall,对于classC,是标有class的样本比例C 预测有 class C.
- 精度,其中,对于class C,是预测为[=45的示例的比率=] C 实际上标有 class 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
如果你想更灵活,你也可以将class感兴趣的参数化:
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)])