1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- import torch
-
- """
- The evaluation implementation refers to the following paper:
- "Selective Feature Aggregation Network with Area-Boundary Constraints for Polyp Segmentation"
- https://github.com/Yuqi-cuhk/Polyp-Seg
- """
- def evaluate(pred, gt, th):
- if isinstance(pred, (list, tuple)):
- pred = pred[0]
-
- pred_binary = (pred >= th).float()
- pred_binary_inverse = (pred_binary == 0).float()
-
- gt_binary = (gt >= th).float()
- gt_binary_inverse = (gt_binary == 0).float()
-
- TP = pred_binary.mul(gt_binary).sum()
- FP = pred_binary.mul(gt_binary_inverse).sum()
- TN = pred_binary_inverse.mul(gt_binary_inverse).sum()
- FN = pred_binary_inverse.mul(gt_binary).sum()
-
- if TP.item() == 0:
- # print('TP=0 now!')
- # print('Epoch: {}'.format(epoch))
- # print('i_batch: {}'.format(i_batch))
- TP = torch.Tensor([1]).cuda()
-
- # recall
- Recall = TP / (TP + FN)
-
- # Specificity or true negative rate
- Specificity = TN / (TN + FP)
-
- # Precision or positive predictive value
- Precision = TP / (TP + FP)
-
- # F1 score = Dice
- F1 = 2 * Precision * Recall / (Precision + Recall)
-
- # F2 score
- F2 = 5 * Precision * Recall / (4 * Precision + Recall)
-
- # Overall accuracy
- ACC_overall = (TP + TN) / (TP + FP + FN + TN)
-
- # IoU for poly
- IoU_poly = TP / (TP + FP + FN)
-
- # IoU for background
- IoU_bg = TN / (TN + FP + FN)
-
- # mean IoU
- IoU_mean = (IoU_poly + IoU_bg) / 2.0
-
- #Dice
- Dice = (2 * TP)/(2*TP + FN + FP)
-
- return Recall, Specificity, Precision, F1, F2, ACC_overall, IoU_poly, IoU_bg, IoU_mean, Dice
-
-
- class Metrics(object):
- def __init__(self, metrics_list):
- self.metrics = {}
- for metric in metrics_list:
- self.metrics[metric] = 0
-
- def update(self, **kwargs):
- for k, v in kwargs.items():
- assert (k in self.metrics.keys()), "The k {} is not in metrics".format(k)
- if isinstance(v, torch.Tensor):
- v = v.item()
-
- self.metrics[k] += v
-
- def mean(self, total):
- mean_metrics = {}
- for k, v in self.metrics.items():
- mean_metrics[k] = v / total
- return mean_metrics
|