200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 「解析」语义分割性能指标 附代码

「解析」语义分割性能指标 附代码

时间:2019-01-02 21:13:07

相关推荐

「解析」语义分割性能指标 附代码

图像分割与其他任务不同,其性能指标采用的混淆矩阵,然后在混淆矩阵的基础上再计算各项性能指标,其比直接计算 像素级的IoU要方便且更加高效,完整版的代码在博客结尾

⚠️注意:

此文章的性能指标 一般适用于 语义分割,对于实例分割不太适用

语义分割不区别个体,因此可以统计类的准确率,但是实例分割区别个体,因此两者有区别

实例分割性能指标后期加上

1、混淆矩阵

def _fast_hist(self, label_true, label_pred):mask = (label_true >= 0) & (label_true < self.n_classes)b = label_true[mask]b = b.astype(int)a = self.n_classes * b + label_pred[mask]hist = np.bincount(a, minlength=self.n_classes ** 2).reshape(self.n_classes, self.n_classes)return hist

添加 掩码mask 的目的是为了保证 标签都为非负数 且 在类别之内,预防其他情况,如果有个例不在此范围,则输出False;则在label_true[mask]时将对应位置 置0⃣️,label_pred[mask]同理;astype(int) 将label_true 转换成整数,则小数部分将会被截断。注意小数点不是四舍五入,而是直接干掉;np.bincount用来统计不同数值的数量

⚠️注意:self.n_classes * b + label_pred[mask]b 的范围为 [0, self.n_classes-1] 因此self.n_classes * b + label_pred[mask]的范围就变成了 [0,self.n_classes2][0, \quad self.n\_classes^2][0,self.n_classes2]

混淆矩阵可视化

confusion = histplt.figure()plt.grid(False)plt.imshow(confusion, camp='confusion')plt.colorbar()plt.show()

2、语义分割常用指标

假设:共有 kkk 个类, pijp_{ij}pij​ 表示本属于类 iii 但被预测为类 jjj 的像素数量。即,pijp_{ij}pij​ 表示真正的数量,而 pijp_{ij}pij​ 和 pjip_{ji}pji​ 则分别被解释为假正 或 假负。

Pixel Accuracy (PA 像素精度):标记正确的像素占总像素的比例

PA=∑i=0k−1pii∑i=0k−1∑j=0k−1pijPA = \frac{\sum^{k-1}_{i=0} p_{ii} }{\sum^{k-1}_{i=0}\sum^{k-1}_{j=0}p_{ij}}PA=∑i=0k−1​∑j=0k−1​pij​∑i=0k−1​pii​​

acc = np.diag(hist).sum() / hist.sum()

Mean Pixel Accuracy (MPA 平均类像素精度):计算每个类内被正确分类像素数的比例,再求所有类的平均

即: MPA = np.nanmean(对角线值 / 行和)

MPA=1k∑i=0k−1pii∑j=0k−1pijMPA = \frac1 k \sum^{k-1}_{i=0} \frac{p_{ii}}{\sum^{k-1}_{j=0}{p_{ij}}}MPA=k1​i=0∑k−1​∑j=0k−1​pij​pii​​

acc_cls = np.diag(hist) / hist.sum(axis=1)

acc_cls = np.nanmean(acc_cls)

Mean Intersection over Union (MIou 平均交并比):计算真实值和预测值的交集 与 并集的比

即:IoU = 对角线 / (行和 - 对角线)

IoU = / 行和 + 列和 - 对角线

MIoU = 真实 和 预测的交集 / 真实 和预测的并集

IoU=Apred⋂AtrueApred⋃AtrueMIoU=1k∑i=0k−1pii∑j=0k−1pij+∑j=0k−1(pji−pii)IoU = \frac{A_{pred} \bigcap A_{true}}{A_{pred} \bigcup A_{true}} \\ \quad \\ MIoU = \frac1k\sum^{k-1}_{i=0}\frac{p_{ii}}{\sum^{k-1}_{j=0}p_{ij} + \sum^{k-1}_{j=0} \big( p_{ji}-p_{ii} \big)}IoU=Apred​⋃Atrue​Apred​⋂Atrue​​MIoU=k1​i=0∑k−1​∑j=0k−1​pij​+∑j=0k−1​(pji​−pii​)pii​​

3、完整代码

class StreamSegMetrics():""" Stream Metrics for Semantic Segmentation Task """def __init__(self, n_classes):self.n_classes = n_classesself.confusion_matrix = np.zeros((n_classes, n_classes))def update(self, label_trues, label_preds):for lt, lp in zip(label_trues, label_preds):self.confusion_matrix += self._fast_hist(lt.flatten(), lp.flatten())@staticmethoddef to_str(results):string = "\n"for k, v in results.items():if k != "Class IoU":string += "%s: %f\n" % (k, v)# string+='Class IoU:\n'# for k, v in results['Class IoU'].items():# string += "\tclass %d: %f\n"%(k, v)return stringdef _fast_hist(self, label_true, label_pred):mask = (label_true >= 0) & (label_true < self.n_classes)b = label_true[mask]b = b.astype(int)a = self.n_classes * b + label_pred[mask]hist = np.bincount(a, minlength = self.n_classes ** 2).reshape(self.n_classes, self.n_classes)return histdef get_results(self):hist = self.confusion_matrix acc= np.diag(hist).sum() / hist.sum()acc_cls = np.diag(hist) / hist.sum(axis=1)acc_cls = np.nanmean(acc_cls)iu= np.diag(hist) / (hist.sum(axis=1) + hist.sum(axis=0) - np.diag(hist))mean_iu = np.nanmean(iu)freq = hist.sum(axis=1) / hist.sum()fwavacc = (freq[freq > 0] * iu[freq > 0]).sum()cls_iu = dict(zip(range(self.n_classes), iu))return {"Overall Acc": acc,"Mean Acc" : acc_cls,"FreqW Acc" : fwavacc,"Mean IoU" : mean_iu,"Class IoU" : cls_iu, }def reset(self):self.confusion_matrix = np.zeros((self.n_classes, self.n_classes))

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。