jiyuhang il y a 3 mois
Parent
commit
833b55e20d
2 fichiers modifiés avec 151 ajouts et 24 suppressions
  1. 103 0
      accuracy.py
  2. 48 24
      bmodel_test.py

+ 103 - 0
accuracy.py

@@ -0,0 +1,103 @@
+import json
+import argparse
+import numpy as np
+
+def argsparser():
+    parser = argparse.ArgumentParser(prog=__file__)
+    parser.add_argument('--input', type=str, default='./prediction_result.json', help='path of prediction')
+    args = parser.parse_args()
+    return args
+
+
+def calculate_metrics(y_true, y_pred):
+    """
+    使用numpy手动计算分类评估指标 - 修正版
+    """
+    y_pred = y_pred.astype(np.int32)
+    y_true = y_true.astype(np.int32)
+
+    # 获取唯一类别并排序
+    classes = np.unique(np.concatenate([y_true, y_pred])).astype(np.int32)
+    n_classes = len(classes)
+
+    # 创建混淆矩阵
+    #  TP  FN
+    #  FP  TN
+    confusion_matrix = np.zeros((n_classes, n_classes), dtype=np.float32)
+
+    # 手动填充混淆矩阵
+    for true_val, pred_val in zip(y_true, y_pred):
+        if true_val == pred_val:  # 预测正确的样本
+            if true_val == 1:  # 真实为正例
+                confusion_matrix[0, 0] += 1
+            else:
+                confusion_matrix[1, 1] += 1
+        else:  # 预测错误的样本
+            if true_val == 0:  # 真实为负例
+                confusion_matrix[1, 0] += 1
+            else:  # 真实为正例
+                confusion_matrix[0, 1] += 1
+    tp = confusion_matrix[0, 0]
+    tn = confusion_matrix[1, 1]
+    fn = confusion_matrix[0, 1]
+    fp = confusion_matrix[1, 0]
+    # 计算精度
+    accuracy = (tp + tn) / (tp + fp + fn + tn + 1e-8)
+    # 计算准确率
+    precision = tp / (tp + fp + 1e-8)
+    # 计算召回率
+    recall = tp / (tp + fn + 1e-8)
+    # 计算F1分数
+    f1 = 2 * precision * recall / (precision + recall + 1e-8)
+    return {
+        'confusion_matrix': confusion_matrix,
+        'classes': classes,
+        'tp': tp,
+        'tn': tn,
+        'fp': fp,
+        'fn': fn,
+        'accuracy': accuracy,
+        'precision': precision,
+        'recall': recall,
+        'f1': f1
+    }
+
+def main(args):
+    # 读取json文件
+    data = None
+    with open(args.input, 'r') as f:
+        data = json.load(f)
+    if data is None:
+        return 0
+    # 开始计算精度 格式:真值,预测值
+    data = [[i['y'], i['x']] for i in data.values()]
+    data = np.array(data, dtype=np.float32)
+    # 分离真值和预测值
+    y_true = data[:, 0]  # 第一列是真值
+    y_pred = data[:, 1]  # 第二列是预测值
+    # 计算评估指标
+    metrics = calculate_metrics(y_true, y_pred)
+
+    # 打印结果
+    print("=== 分类评估结果 ===")
+    print(f"总体精度: {metrics['accuracy']:.4f}")
+    print(f"混淆矩阵:TP FN")
+    print(f"        FP TN")
+    print(f"{metrics['confusion_matrix']}")
+    print(f"查准率: {metrics['precision']:.4f}")
+    print(f"查全率: {metrics['recall']:.4f}")
+    print(f"F1分数: {metrics['f1']:.4f}")
+    from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
+    # 计算各项指标
+    report = classification_report(y_true, y_pred)
+    cm = confusion_matrix(y_true, y_pred)
+    accuracy = accuracy_score(y_true, y_pred)
+    print(f"=== sklearn 分类评估结果 ===")
+    print(f"分类报告:\n{report}")
+    print(f"混淆矩阵:\n{cm}")
+    print(f"准确率: {accuracy:.4f}")
+    return 1
+
+if __name__ == '__main__':
+    args = argsparser()
+    main(args)

+ 48 - 24
bmodel_test.py

@@ -1,7 +1,9 @@
 import argparse
 import sophon.sail as sail
 import cv2
+import os
 import logging
+import json
 import numpy as np
 
 class Predictor:
@@ -52,8 +54,8 @@ class Predictor:
     def predict(self, input_img):
         input_data = {self.input_name: input_img}
         outputs = self.net.process(self.graph_name, input_data)
-        print('predict fun:', outputs)
-        print('predict fun return:', list(outputs.values())[0])
+        # print('predict fun:', outputs)
+        # print('predict fun return:', list(outputs.values())[0])
         return list(outputs.values())[0]
 
     def preprocess(self, img):
@@ -68,39 +70,61 @@ class Predictor:
         return img
 
     def postprocess(self, outputs):
-
         outputs_exp = np.exp(outputs)
-        print('exp res:', outputs_exp)
+        # print('exp res:', outputs_exp)
         outputs = outputs_exp / np.sum(outputs_exp, axis=1)[:, None]
-        print('softmax res:', outputs)
-        predictions = np.argmax(outputs, axis=1)
-        print('预测结果:', predictions)
-        return outputs
-
-def main(args):
-    predictor = Predictor()
-    filename = args.input
-    src_img = cv2.imread(filename, cv2.IMREAD_COLOR)
-    src_img = predictor.preprocess(src_img)
-    src_img = np.stack([src_img])
-    print('图像输入shape:',src_img.shape)
-    if src_img is None:
-        logging.error("{} imread is None.".format(filename))
-        return
-    res = predictor(src_img)
-    print('预测结果res:', res)
-    predictor.postprocess(res)
-
+        # print('softmax res:', outputs)
+        predictions = np.argmax(outputs, axis=1)  # 返回最大概率的类别
+        # print('预测结果:', predictions)
+        return predictions
 
 def argsparser():
     parser = argparse.ArgumentParser(prog=__file__)
-    parser.add_argument('--input', type=str, default='./000000_256_512_1.jpg', help='path of input, must be image directory')
+    parser.add_argument('--input', type=str, default='./test', help='path of input, must be image directory')
     parser.add_argument('--bmodel', type=str, default='./shufflenet_f32.bmodel', help='path of bmodel')
     parser.add_argument('--dev_id', type=int, default=0, help='tpu id')
     args = parser.parse_args()
 
     return args
 
+def main(args):
+    # 加载推理引擎
+    predictor = Predictor()
+    # 获取图片
+    cls = os.listdir(args.input)
+    # cls = os.listdir('./label_data/test')
+    filename = {}
+    for c in cls:
+        # filename[c] = [os.path.join('./label_data/test', p) for p in os.listdir(os.path.join('./label_data/test', c))]
+        filename[c] = [os.path.join(args.input,c, p) for p in os.listdir(os.path.join(args.input, c))]
+    print('find data:')
+    for k, v in filename.items():
+        print(f'{k}: {len(v)}')
+    print('开始推理...')
+    res_list=[]
+    for k, v in filename.items():
+        for i in v:
+            src_img = cv2.imread(i, cv2.IMREAD_COLOR)
+            src_img = predictor.preprocess(src_img)
+            res = [-1]
+            if src_img is not None:
+                src_img = np.stack([src_img])
+                res = predictor(src_img)
+                res =  predictor.postprocess(res)
+            print(f'{k}: {res[0]}')
+            res_list.append([i, k, res[0]])
+    # 保存结果为 json
+    res_dict = {}
+    for path, real_value, pred_value in res_list:
+        res_dict[path] = {'y':int(real_value), 'x':int(pred_value)}
+    res_save_path = f'{predictor.graph_name}_prediction_result.json'
+    with open(res_save_path, 'w') as f:
+        json.dump(res_dict, f)
+        print(f'保存结果为 {res_save_path} 成功!')
+
+
+
+
 if __name__ == '__main__':
     args = argsparser()
     main(args)