如何在 TF2 中构建具有公差的自定义精度指标?

How to build a custom accuracy metric with tolerance in TF2?

我想构建一个具有容差的自定义准确度指标。而不是在 y_truey_pred 中计算完全相等的元素,如果它们的差异在给定的公差值内,则此精度认为这两个元素是一致的。例如,如果预测度数与真实度数的差异小于5度,我们就可以认为结果是正确的,并根据这个规则计算准确率。我想在 model.compile 中使用这个指标,所以它应该是一个可调用函数。

我写了一个函数如下

def accuracy_with_tolerence(y_true,y_pred):
    """
    y_true/y_pred: batch of samples; (BatchSize, 1)
    """
    threshold = 5
    differnece = tf.abs(tf.subtract(y_true,y_pred)) - threshold
    boolean_results = [True if i < 0 else False for i in differnece]
    return K.mean(math_ops.cast(boolean_results, K.floatx()))

它可以return正确的精度值。

x = tf.constant([1, 2, 3], dtype=tf.float32)
y = tf.constant([5, 8, 10], dtype=tf.float32)
acc = accuracy_with_tolerence(x,y)
print(acc)
tf.Tensor(0.33333334, shape=(), dtype=float32)

但是我想在编译中使用的时候出现错误:

# Initialize ResNet50
model = resnet50()
model.compile(optimizer='adam',loss='mse',metrics=[accuracy_with_tolerence])
model.load_weights(checkpoint_filepath_0)
model.evaluate(x_test,y_test)
OperatorNotAllowedInGraphError: iterating over `tf.Tensor` is not allowed: AutoGraph did convert this function. This might indicate you are trying to use an unsupported feature.

看来我无法迭代张量。那么如何在度量函数中得到逐元素的布尔比较结果呢?如何实现这个精度函数?

提前致谢。

你不能用张量进行列表推导。您要查找的操作是tf.where,您可以按如下方式使用它:

def accuracy_with_tolerence(y_true, y_pred):
    threshold = 5
    differnece = tf.abs(tf.subtract(y_true, y_pred)) - threshold
    boolean_results = tf.where(differnece>0, True, False)
    return K.mean(math_ops.cast(boolean_results, K.floatx()))

请注意,您可以进一步简化代码:

    ...
    boolean_results = tf.where(tf.abs(tf.subtract(y_true, y_pred)) - threshold>0, 1., 0.)
    return K.mean(boolean_results)