文章目录
- 前言
- 一、F1 Score 定义
- 二、代码实现
- 三、为什么用F1 Score
- 总结
- 参考文献
前言
刚开始做两个类别语义分割项目时,发现分割的评价指标高,但是实际效果可能完全错误的现象。当时使用的指标是Pixel Accuracy,因为前景像素占总像素的5%以内,所以如果预测结果都是背景的话识别也过也非常高。目前分割论文中普遍使用的评价标准是mIOU,单一类别和多类别都可以使用该标准,另外还有一个较好的评价指标F1 Score。
即使是F1 Score还不能完全表示所有分割任务的评价标准,具体人物可以参考这篇文章(R. Haralick, L. Shapiro, Survey: image segmentation techniques,Computer Vision, Graphics and Image Processing 29 (1985) 100–132.)
Haralick 和Shapiro 建立了四个标准:
- 对于某些特征(如灰度、纹理),同一个区域的图像应该一致和均匀
- 区域内部应该简单,没有很多空洞
- 相邻的区域在满足区域内部一致性的特征上应该有显著的区别
- 每个区域的边界应该简单而不粗糙,并且空间位置准确
一、F1 Score 定义
该定义在之前文章Dice Loss中已经提到,F1 score等同于Dice coefficient
二、代码实现
博客有很多代码供参考,不细讨论
#二值分割图是一个波段的黑白图,正样本值为1,负样本值为0
#通过矩阵的逻辑运算分别计算出tp,tn,fp,fn
seg_inv, gt_inv = np.logical_not(premask), np.logical_not(groundtruth)
true_pos = float(np.logical_and(premask, groundtruth).sum()) # float for division
true_neg = np.logical_and(seg_inv, gt_inv).sum()
false_pos = np.logical_and(premask, gt_inv).sum()
false_neg = np.logical_and(seg_inv, groundtruth).sum()
#然后根据公式分别计算出这几种指标
prec = true_pos / (true_pos + false_pos + 1e-6)
rec = true_pos / (true_pos + false_neg + 1e-6)
accuracy = (true_pos + true_neg) / (true_pos + true_neg + false_pos + false_neg + 1e-6)
F1 = 2 * true_pos / (2 * true_pos + false_pos + false_neg + 1e-6)
IoU = true_pos / (true_pos + false_neg + false_pos + 1e-6)
三、为什么用F1 Score
F1 Score定义来源于调和平均,可以通过导数来考虑不同 mean 函数的性质[^4]。显然,三个函数关于其中一个变量 x 的一阶导数都大于0,即 x 越大 mean 越大。二阶导 harmonic mean 和 geometric mean 都是负的,也就是说 x 越大 mean 越大,且大得更慢。反之,x 越小 mean 越小,且小得越快。也就是说,一个数想变大来拉高 调和/几何 平均会越来越难,而一个数变小容易拉低 调和/几何 平均,这相当于就是对小数字的「惩罚」了。
相当于短板理论,不接受偏科,待平均各项中,短板相对长板,对整体平均值影响更大,综合召回率和准确率评判模型效果,另外还可以对召回率或者准确率增加权重,调和两者的影响占比。
总结
实际应用的评价标准可以在F1/mIOU基础上,根据应用需求增加边缘精准度、空洞等测量评价方式。