-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMeanIoU.py
49 lines (36 loc) · 1.89 KB
/
MeanIoU.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import tensorflow as tf
import numpy as np
from sklearn.metrics import confusion_matrix
class MeanIoU(object):
def __init__(self, num_classes):
super().__init__()
self.num_classes = num_classes
def mean_iou(self, y_true, y_pred):
# Wraps np_mean_iou method and uses it as a TensorFlow op.
# Takes numpy arrays as its arguments and returns numpy arrays as
# its outputs.
return tf.py_func(self.np_mean_iou, [y_true, y_pred], tf.float32)
#mean_iou, update_op = tf.metrics.mean_iou(y_true, y_pred, self.num_classes)
#return mean_iou
def np_mean_iou(self, y_true, y_pred):
# Compute the confusion matrix to get the number of true positives,
# false positives, and false negatives
# Convert predictions and target from categorical to integer format
target = np.argmax(y_true, axis=-1).ravel()
predicted = np.argmax(y_pred, axis=-1).ravel()
#self.num_classes = len(np.unique([target, predicted]))
#print(self.num_classes)
# Trick from torchnet for bincounting 2 arrays together
x = predicted + self.num_classes * target
bincount_2d = np.bincount(x.astype(np.int32), minlength=self.num_classes**2)
assert bincount_2d.size == self.num_classes**2
conf = bincount_2d.reshape((self.num_classes, self.num_classes))
# Compute the IoU and mean IoU from the confusion matrix
true_positive = np.diag(conf)
false_positive = np.sum(conf, 0) - true_positive
false_negative = np.sum(conf, 1) - true_positive
# Just in case we get a division by 0, ignore/hide the error and set the value to 0
with np.errstate(divide='ignore', invalid='ignore'):
iou = true_positive / (true_positive + false_positive + false_negative)
iou[np.isnan(iou)] = 0
return np.mean(iou).astype(np.float32)