tf.keras.metrics.MeanIoU 有 sigmoid 层

tf.keras.metrics.MeanIoU with sigmoid layer

我有一个用于语义分割的网络,我模型的最后一层应用了 S 形激活,因此所有预测都在 0-1 之间缩放。有一个验证指标 tf.keras.metrics.MeanIoU(num_classes),它将分类预测(0 或 1)与验证(0 或 1)进行比较。因此,如果我进行预测并应用此指标,它会自动将连续预测映射到阈值为 0.5 的二进制吗?是否有可能手动定义阈值?

试试这个(记得用制表符替换 space):

def mean_iou(y_true, y_pred):
    th = 0.5
    y_pred_ = tf.to_int32(y_pred > th)
    score, up_opt = tf.metrics.mean_iou(y_true, y_pred_, 2)
    K.get_session().run(tf.local_variables_initializer())
    with tf.control_dependencies([up_opt]):
        score = tf.identity(score)
    return score

不,tf.keras.metrics.MeanIoU 不会自动将连续预测映射到阈值 = 0.5 的二进制。

它将连续预测转换为二进制,通过将小数点前的二进制数字作为预测,如 0.9900.5000.01 作为 01.99 作为 11.01 作为 1num_classes=2所以基本上,如果您的预测值介于 01num_classes=2 之间,那么一切都被视为 0,除非预测是 1

以下是证明 tensorflow version 2.2.0 行为合理的实验:

所有二进制结果:

import tensorflow as tf

m = tf.keras.metrics.MeanIoU(num_classes=2)
_ = m.update_state([0, 0, 1, 1], [0, 0, 1, 1])
m.result().numpy()

输出-

1.0

将一个预测改成连续0.99 -这里把0.99当成0.

import tensorflow as tf

m = tf.keras.metrics.MeanIoU(num_classes=2)
_ = m.update_state([0, 0, 1, 1], [0, 0, 1, 0.99])
m.result().numpy()

输出-

0.5833334

将一个预测改成连续0.01 -这里把0.01当成0.

import tensorflow as tf

m = tf.keras.metrics.MeanIoU(num_classes=2)
_ = m.update_state([0, 0, 1, 1], [0, 0.01, 1, 1])
m.result().numpy()

输出-

1.0

将一个预测改成连续的1.99 -这里把1.99当成1.

%tensorflow_version 2.x
import tensorflow as tf

m = tf.keras.metrics.MeanIoU(num_classes=2)
_ = m.update_state([0, 0, 1, 1], [0, 0, 1, 1.99])
m.result().numpy()

输出-

1.0

所以理想的方法是在计算MeanIoU.

之前定义一个函数将连续值转换为二进制值

希望这能回答您的问题。快乐学习。