如何在PyTorch中计算语义分割模型的类别准确率?
基于sklearn的语义分割类别级像素准确率计算方法
你已经在用sklearn.metrics计算MIoU的话,完全可以直接复用计算MIoU时生成的混淆矩阵来统计类别级像素准确率,不需要重复遍历像素做统计,效率更高。
核心计算逻辑
类别级像素准确率(Class-wise Pixel Accuracy, cPA)的定义为:单个类别预测正确的像素数 / 该类别在真实标注中的总像素数,对应混淆矩阵的统计逻辑为:
- 单个类别预测正确的像素数 = 混淆矩阵对角线对应位置的值(真阳性TP)
- 单个类别的真实总像素数 = 混淆矩阵对应行的求和值(真阳性TP + 假阴性FN,即所有标注为该类的像素总数)
具体实现步骤
1. 对齐MIoU计算的前置混淆矩阵生成逻辑
你当前计算MIoU时,必然已经生成了全局混淆矩阵,标准的生成代码和你现有逻辑是对齐的:
import numpy as np from sklearn import metrics # 参数说明: # num_classes: 待评估的类别总数,不包含需要忽略的无效类 # ignore_index: 需要跳过的无效标签值,比如常用的255(边界、未标注区域) # gt: 真实分割标注图,shape为(H,W)的numpy数组 # pred: 模型输出的分割预测图,shape和gt一致 # 先过滤无效像素 valid_mask = (gt != ignore_index) gt_flatten = gt[valid_mask].flatten() pred_flatten = pred[valid_mask].flatten() # 生成混淆矩阵:行索引对应真实类别,列索引对应预测类别 conf_mat = metrics.confusion_matrix( gt_flatten, pred_flatten, labels=list(range(num_classes)) )
你现有计算MIoU的逻辑就是基于这个混淆矩阵:单类IoU = 对角线值 / (对应行和 + 对应列和 - 对角线值),所有类IoU取均值就是MIoU,这一步的混淆矩阵可以直接复用,不需要重复计算。
2. 计算类别级像素准确率
直接基于混淆矩阵做矩阵运算即可,不需要额外依赖其他库:
# 取每个类的TP值(预测正确的像素数) tp_per_class = np.diag(conf_mat) # 取每个类的真实标注总像素数 gt_sum_per_class = conf_mat.sum(axis=1) # 计算单类像素准确率,自动处理某类在当前评估数据中不存在(分母为0)的异常情况 class_pixel_acc = np.divide( tp_per_class, gt_sum_per_class, out=np.zeros_like(tp_per_class, dtype=np.float32), where=gt_sum_per_class != 0 )
最终得到的class_pixel_acc是长度为num_classes的数组,数组索引对应类别id,值就是对应类别的像素准确率。如果需要直观输出结果,可以搭配类别名列表打印:
# class_names为存储类别名的列表,顺序和类别id一一对应,比如['道路','人行道','建筑'...] for cls_id, acc in enumerate(class_pixel_acc): print(f"类别 {class_names[cls_id]} 像素准确率: {round(acc, 4)}")
补充:全局像素准确率计算
如果需要同时统计所有类别的全局像素准确率(所有预测正确的像素占总有效像素的比例),可以直接用以下代码计算:
global_pixel_acc = tp_per_class.sum() / conf_mat.sum()
内容的提问来源于stack exchange,提问作者Muhammad Butt
相关产品推荐
相关产品推荐

