| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- # copytrue (c) 2020 PaddlePaddle Authors. All Rights Reserve.
- #
- # 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.
- import json
- import yaml
- import os.path as osp
- import numpy as np
- from paddlex_restful.restful.dataset.utils import get_encoding
- class Evaluator(object):
- def __init__(self, model_path):
- model_yml = osp.join(model_path, "model.yml")
- with open(model_yml, encoding=get_encoding(model_yml)) as f:
- model_info = yaml.load(f.read(), Loader=yaml.Loader)
- self.labels = model_info['_Attributes']['labels']
- eval_details_file = osp.join(model_path, 'eval_details.json')
- with open(
- eval_details_file, 'r',
- encoding=get_encoding(eval_details_file)) as f:
- eval_details = json.load(f)
- self.confusion_matrix = np.array(eval_details['confusion_matrix'])
- self.num_classes = len(self.confusion_matrix)
- def cal_iou(self):
- '''计算IoU。
- '''
- category_iou = []
- mean_iou = 0
- vji = np.sum(self.confusion_matrix, axis=1)
- vij = np.sum(self.confusion_matrix, axis=0)
- for c in range(self.num_classes):
- total = vji[c] + vij[c] - self.confusion_matrix[c][c]
- if total == 0:
- iou = 0
- else:
- iou = float(self.confusion_matrix[c][c]) / total
- mean_iou += iou
- category_iou.append(iou)
- mean_iou = float(mean_iou) / float(self.num_classes)
- return np.array(category_iou), mean_iou
- def cal_acc(self):
- '''计算Acc。
- '''
- total = self.confusion_matrix.sum()
- total_tp = 0
- for c in range(self.num_classes):
- total_tp += self.confusion_matrix[c][c]
- if total == 0:
- mean_acc = 0
- else:
- mean_acc = float(total_tp) / total
- vij = np.sum(self.confusion_matrix, axis=0)
- category_acc = []
- for c in range(self.num_classes):
- if vij[c] == 0:
- acc = 0
- else:
- acc = self.confusion_matrix[c][c] / float(vij[c])
- category_acc.append(acc)
- return np.array(category_acc), mean_acc
- def cal_confusion_matrix(self):
- '''计算混淆矩阵。
- '''
- return self.confusion_matrix
- def cal_precision_recall(self):
- '''计算precision、recall.
- '''
- self.precision_recall = dict()
- for i in range(len(self.labels)):
- label_name = self.labels[i]
- if np.isclose(np.sum(self.confusion_matrix[i, :]), 0, atol=1e-6):
- recall = -1
- else:
- total_gt = np.sum(self.confusion_matrix[i, :]) + 1e-06
- recall = self.confusion_matrix[i, i] / total_gt
- if np.isclose(np.sum(self.confusion_matrix[:, i]), 0, atol=1e-6):
- precision = -1
- else:
- total_pred = np.sum(self.confusion_matrix[:, i]) + 1e-06
- precision = self.confusion_matrix[i, i] / total_pred
- self.precision_recall[label_name] = {
- 'precision': precision,
- 'recall': recall
- }
- return self.precision_recall
- def generate_report(self):
- '''生成评估报告。
- '''
- category_iou, mean_iou = self.cal_iou()
- category_acc, mean_acc = self.cal_acc()
- category_iou_dict = {}
- for i in range(len(category_iou)):
- category_iou_dict[self.labels[i]] = category_iou[i]
- report = dict()
- report['Confusion_Matrix'] = self.cal_confusion_matrix()
- report['Mean_IoU'] = mean_iou
- report['Mean_Acc'] = mean_acc
- report['PRIoU'] = self.cal_precision_recall()
- for key in report['PRIoU']:
- report['PRIoU'][key]["iou"] = category_iou_dict[key]
- report['label_list'] = self.labels
- return report
|