-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetrics.py
89 lines (70 loc) · 2.52 KB
/
metrics.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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# Retrieved from https://github.com/DrSleep/DenseTorch/blob/master/densetorch/engine/metrics.py
import numpy as np
from miou import compute_iu, fast_cm
class MeanIoU:
"""Mean-IoU computational block for semantic segmentation.
Args:
num_classes (int): number of classes to evaluate.
Attributes:
name (str): descriptor of the estimator.
"""
def __init__(self, num_classes):
if isinstance(num_classes, (list, tuple)):
num_classes = num_classes[0]
assert isinstance(
num_classes, int
), f"Number of classes must be int, got {num_classes}"
self.num_classes = num_classes
self.name = "meaniou"
self.reset()
def reset(self):
self.cm = np.zeros((self.num_classes, self.num_classes), dtype=int)
def update(self, pred, gt):
idx = gt < self.num_classes
pred_dims = len(pred.shape)
assert (pred_dims - 1) == len(
gt.shape
), "Prediction tensor must have 1 more dimension that ground truth"
if pred_dims == 3:
class_axis = 0
elif pred_dims == 4:
class_axis = 1
else:
raise ValueError("{}-dimensional input is not supported".format(pred_dims))
assert (
pred.shape[class_axis] == self.num_classes
), "Dimension {} of prediction tensor must be equal to the number of classes".format(
class_axis
)
pred = pred.argmax(axis=class_axis)
self.cm += fast_cm(
pred[idx].astype(np.uint8), gt[idx].astype(np.uint8), self.num_classes
)
def val(self):
return np.mean([iu for iu in compute_iu(self.cm) if iu <= 1.0])
class RMSE:
"""Root Mean Squared Error computational block for depth estimation.
Args:
ignore_val (float): value to ignore in the target
when computing the metric.
Attributes:
name (str): descriptor of the estimator.
"""
def __init__(self, ignore_val=0):
self.ignore_val = ignore_val
self.name = "rmse"
self.reset()
def reset(self):
self.num = 0.0
self.den = 0.0
def update(self, pred, gt):
assert (
pred.shape == gt.shape
), "Prediction tensor must have the same shape as ground truth"
pred = np.abs(pred)
idx = gt != self.ignore_val
diff = (pred - gt)[idx]
self.num += np.sum(diff ** 2)
self.den += np.sum(idx)
def val(self):
return np.sqrt(self.num / self.den)