Keras Custom Metric用于单级精度

时间:2017-01-04 07:58:47

标签: python tensorflow neural-network keras

我正在构建一个自定义指标来衡量培训期间我的多类数据集中一个类的准确性。我在选择课程时遇到了麻烦。

目标是热门目标(例如: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函数来索引张量。如何为张量创建布尔蒙版?谢谢。

1 个答案:

答案 0 :(得分:17)

请注意,在谈论一个班级的准确度时,可以参考以下任一项(不等同于)两个金额:

  • 精度,对于类 C ,是标记为类 C 的示例与预计具有类 C
  • 召回,对于类 C ,它是预测为 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

如果您想要更灵活,您还可以将感兴趣的类别参数化:

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)])