| 812 | |
| 813 | |
| 814 | class SegmentationRunningMetrics(object): |
| 815 | |
| 816 | def __init__(self, num_classes=None, ignore_index=None): |
| 817 | |
| 818 | self.n_classes = num_classes |
| 819 | self.ignore_index = ignore_index |
| 820 | self.confusion_matrix = np.zeros((self.n_classes, self.n_classes)) |
| 821 | self.reduced_confusion_matrix = None |
| 822 | |
| 823 | def get_F1_score(self): |
| 824 | assert self.n_classes == 2 |
| 825 | TN, FN, FP, TP = self.confusion_matrix.flatten() |
| 826 | precision = TP / (TP + FP) |
| 827 | recall = TP / (TP + FN) |
| 828 | return 2 / (1 / precision + 1 / recall), precision, recall |
| 829 | |
| 830 | def _fast_hist(self, label_true, label_pred, n_class): |
| 831 | mask = (label_true >= 0) & (label_true < n_class) |
| 832 | mask &= (label_pred >= 0) & (label_pred < n_class) |
| 833 | |
| 834 | if self.ignore_index is not None: |
| 835 | mask = mask & (label_true != self.ignore_index) |
| 836 | |
| 837 | hist = np.bincount( |
| 838 | n_class * label_true[mask].astype(int) + |
| 839 | label_pred[mask], minlength=n_class**2) |
| 840 | |
| 841 | # print(np.unique(label_true)) |
| 842 | # print(np.unique(label_pred)) |
| 843 | hist = hist.reshape(n_class, n_class) |
| 844 | |
| 845 | return hist |
| 846 | |
| 847 | def update(self, label_preds, label_trues): |
| 848 | self.reduced_confusion_matrix = None |
| 849 | for lt, lp in zip(label_trues, label_preds): |
| 850 | self.confusion_matrix += self._fast_hist(lt.flatten(), lp.flatten(), self.n_classes) |
| 851 | |
| 852 | def reduce_scores(self): |
| 853 | hist = self.confusion_matrix |
| 854 | self.reduced_confusion_matrix = hist |
| 855 | |
| 856 | def _get_scores(self): |
| 857 | """Returns accuracy score evaluation result. |
| 858 | - overall accuracy |
| 859 | - mean accuracy |
| 860 | - mean IU |
| 861 | - fwavacc |
| 862 | """ |
| 863 | if self.reduced_confusion_matrix is None: |
| 864 | self.reduce_scores() |
| 865 | hist = self.reduced_confusion_matrix |
| 866 | |
| 867 | acc = np.diag(hist).sum() / hist.sum() |
| 868 | acc_cls_list = acc_cls = np.diag(hist) / hist.sum(axis=1) |
| 869 | |
| 870 | acc_cls = np.nanmean(acc_cls) |
| 871 | iu = np.diag(hist) / (hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist)) |