# Copyright 2022 The TensorFlow Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """IOU Metrics used for semantic segmentation models.""" import tensorflow as tf class PerClassIoU(tf.keras.metrics.MeanIoU): """Computes the per-class Intersection-Over-Union metric. This metric computes the IOU for each semantic class. 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. Example: >>> # cm = [[1, 1], >>> # [1, 1]] >>> # sum_row = [2, 2], sum_col = [2, 2], true_positives = [1, 1] >>> # iou = true_positives / (sum_row + sum_col - true_positives)) >>> # result = [(1 / (2 + 2 - 1), 1 / (2 + 2 - 1)] = 0.33 >>> m = tf.keras.metrics.MeanIoU(num_classes=2) >>> m.update_state([0, 0, 1, 1], [0, 1, 0, 1]) >>> m.result().numpy() [0.33333334, 0.33333334] """ def result(self): """Compute IoU for each class via the confusion matrix.""" 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.tensor_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 + sum_over_col - true_positives return tf.math.divide_no_nan(true_positives, denominator)