multi-class 语义分割任务的联合交集 (IOU) 度量

Intersection over union (IOU) metric for multi-class semantic segmentation task

我有一个语义分割任务来使用 UNET 预测 5 通道掩码,例如掩码形状是 (224,244,5)。

我正在使用这个功能来欠条:

    def mean_iou(y_true, y_pred):
        y_pred = tf.round(tf.cast(y_pred, tf.int32))
        intersect = tf.reduce_sum(tf.cast(y_true, tf.float32) * tf.cast(y_pred, tf.float32), axis=[1])
        union = tf.reduce_sum(tf.cast(y_true, tf.float32),axis=[1]) + tf.reduce_sum(tf.cast(y_pred, tf.float32),axis=[1])
        smooth = tf.ones(tf.shape(intersect))
        return tf.reduce_mean((intersect + smooth) / (union - intersect + smooth))

 def iou_loss(y_true, y_pred):
      y_true = tf.reshape(y_true, [-1])
      y_pred = tf.reshape(y_pred, [-1])
      intersection = tf.reduce_sum(tf.cast(y_true, tf.float32) * tf.cast(y_pred, tf.float32))
      score = (intersection + 1.) / (tf.reduce_sum(tf.cast(y_true, tf.float32)) + 
      tf.reduce_sum(tf.cast(y_pred, tf.float32)) - intersection + 1.)
      return 1 - score`

和UNET模型的输出层:

  outputs = tf.keras.layers.Conv2D(5, (1, 1), activation='softmax')(c9)
   model = tf.keras.Model(inputs=[input_img], outputs=[outputs])
   opti =  tf.keras.optimizers.Adam(lr=0.003, clipvalue=0.7)
   model.compile(optimizer=opti, loss=iou_loss, metrics=['accuracy',mean_iou])

但我不确定 IOU 函数是否正确实现,

你能澄清一下吗?

让我们把它分成更小的部分来了解发生了什么:

  1. tf.reshape(y_true, [-1]),y_pred = tf.reshape(y_pred, [-1]); 预测和基本事实被转换成一维数组。之所以会发生这种情况,是因为从本质上讲,尽管您有多个地面实况掩码,但它们都仅由 1s0s.

    组成
  2. intersection = tf.reduce_sum(tf.cast(y_true, tf.float32) * tf.cast(y_pred, tf.float32))。我们在这里乘法,因为只有当预测和真实值在某个位置上都为 1 时,乘法才会产生 1...0x11x00x0 当然不属于交集.

  3. tf.reduce_sum()。我们只是对交集的 1 求和。

  4. score = (intersection + 1.) / (tf.reduce_sum(tf.cast(y_true, tf.float32)) + tf.reduce_sum(tf.cast(y_pred, tf.float32)) - intersection + 1.)。这就是 IoU 的定义。注意分子和分母都加上1,避免被0除。在分母层面,由于Union运算本身已经包含了交集,为了正确计算IoU,我们需要记得减去交集,从而产生正确的 IoU 值。

  5. 1 - score。我们return1-score,因为如果IoU是0.75,例如loss​​是0.25(完美IoU == 1