【问题标题】:Tensorflow : IOU per classTensorflow:每个班级的借据
【发布时间】:2019-07-17 03:56:46
【问题描述】:

我正在尝试使用 deeplab 进行语义分割。我想计算每个班级的 IOU(仅限个人的 IOU)而不是平均 IOU。

在 L142 的 https://github.com/tensorflow/models/blob/master/research/deeplab/eval.py, 我试图通过

得到混淆矩阵而不是平均IOU
miou, cmat = tf.metrics.mean_iou(...)
metric_map['cmat'] = cmat

但它不起作用。 如果有人建议我如何出行,我将不胜感激。

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    您可以使用tensorflow.python.ops.metrics_impl 中的_streaming_confusion_matrix 来获取混淆矩阵。 本质上,它的工作方式与其他运行指标(如 mean_iou)相同。这意味着,在调用此指标时,您会得到两个操作,一个是总的混淆矩阵操作,另一个是累积更新混淆矩阵的更新操作。

    有了混淆矩阵,现在你应该能够计算类明智的 iou

    【讨论】:

      【解决方案2】:

      为此,我基于 MeanIoU 类实现了一个特定于类的 IoU 指标。

      class ClassIoU(tf.keras.metrics.MeanIoU):
      """Computes the class-specific Intersection-Over-Union metric.
      
      IOU is defined as follows:
        IOU = true_positive / (true_positive + false_positive + false_negative).
      The predictions are accumulated in a confusion matrix, weighted by
      `sample_weight` and the metric is then calculated from it.
      
      If `sample_weight` is `None`, weights default to 1.
      Use `sample_weight` of 0 to mask values.
      
      Args:
        class_idx: The index of the the class of interest
        one_hot: Indicates if the input is a one_hot vector as in CategoricalCrossentropy or if the class indices
          are used as in SparseCategoricalCrossentropy or MeanIoU
        num_classes: The possible number of labels the prediction task can have.
          This value must be provided, since a confusion matrix of dimension =
          [num_classes, num_classes] will be allocated.
        name: (Optional) string name of the metric instance.
        dtype: (Optional) data type of the metric result.
      """
      def __init__(self, class_idx, one_hot, num_classes, name=None, dtype=None):
          super().__init__(num_classes, name, dtype)
          self.one_hot = one_hot
          self.class_idx = class_idx
      
      def result(self):
          sum_over_row = tf.cast(
              tf.reduce_sum(self.total_cm, axis=0), dtype=self._dtype)
          sum_over_col = tf.cast(
              tf.reduce_sum(self.total_cm, axis=1), dtype=self._dtype)
          true_positives = tf.cast(
              tf.linalg.diag_part(self.total_cm), dtype=self._dtype)
      
          # sum_over_row + sum_over_col =
          #     2 * true_positives + false_positives + false_negatives.
          denominator = sum_over_row[self.class_idx] + sum_over_col[self.class_idx] \
              - true_positives[self.class_idx]
      
          # The mean is only computed over classes that appear in the
          # label or prediction tensor. If the denominator is 0, we need to
          # ignore the class.
          num_valid_entries = tf.reduce_sum(
              tf.cast(tf.not_equal(denominator, 0), dtype=self._dtype))
      
          iou = tf.math.divide_no_nan(true_positives[self.class_idx], denominator)
      
          return tf.math.divide_no_nan(
              tf.reduce_sum(iou, name='mean_iou'), num_valid_entries)
      
      def update_state(self, y_true, y_pred, sample_weight=None):
          if self.one_hot:
              return super().update_state(tf.argmax(y_true, axis=-1), tf.argmax(y_pred, axis=-1), sample_weight)
          else:
              return super().update_state(y_true, y_pred, sample_weight)
      

      【讨论】:

        猜你喜欢
        • 2023-03-25
        • 2020-11-04
        • 2018-06-21
        • 2012-02-09
        • 1970-01-01
        • 2019-04-26
        • 2010-10-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多