赞
踩
二分类和多分类的评价指标的选择
首先,对于像素点,我们要知道,当预测的像素点类别和其真实类别不同或者相同时,我们可以用混淆矩阵来表示,如下图:
首先,dice和IOU都是衡量两个集合之间相似性的度量,在图像分割领域用来衡量网络分割结果与金标准mask(标签)之间的相似性。
(分割网络评价指标)dice系数和IOU之间的区别和联系
IOU指标可以使用几何办法给出直观的解释,我们假设红色代表图片中的标签,黄色是分割的结果,那么他们重叠的蓝色部分就是TP(true Positive)真正例,也就是正样本被正确分类。
那么对应的红色就是预测为负但实际为正,因此是FN。
下面黄色部分,就是预测为正,但实际为负,因此是FP(false Positive)。
结合上述图片,我们可以给出IOU的公式(结合几何意义)
I
O
U
=
T
P
F
N
+
T
P
+
F
P
IOU = \frac{TP}{FN+TP+FP}
IOU=FN+TP+FPTP
I
O
U
=
预测正确:蓝色
(
红色
+
蓝色
+
黄色
)
IOU=\frac{预测正确:蓝色}{(红色+蓝色+黄色)}
IOU=(红色+蓝色+黄色)预测正确:蓝色
这位是对于一个类别来说的IOU公式,而mIOU公式是对所有类别求交并比的平均值。
m
I
O
U
=
1
k
∑
i
=
1
k
T
P
F
N
+
T
P
+
F
P
mIOU = \frac{1}{k}\sum_{i=1}^{k}\frac{TP}{FN+TP+FP}
mIOU=k1i=1∑kFN+TP+FPTP
mIOU的计算过程中首先需要计算混淆矩阵。
Dice系数、mIOU与Dice LOss
Dice系数是一种集合的相似度度量函数,通常用于计算两个样本的相似度,取值范围在[0,1]之间。
我们同样根据上图,可以得出Dice系数的公式为:
Dice系数的计算公式如下:
D i c e = 2 × T P ( T P + F N ) + ( T P + F P ) = 2 × 预测正确:蓝色 ( 真实结果:红色 + 蓝色 ) + ( 预测结果:黄色 + 蓝色 ) Dice=\frac{2\times TP}{(TP+FN)+(TP+FP)} =\frac{2\times 预测正确:蓝色}{(真实结果:红色+蓝色)+(预测结果:黄色+蓝色)} Dice=(TP+FN)+(TP+FP)2×TP=(真实结果:红色+蓝色)+(预测结果:黄色+蓝色)2×预测正确:蓝色
Dice和IOU关系分析
集合交并比:
m
I
O
U
=
T
P
F
N
+
T
P
+
F
P
集合交并比:mIOU = \frac{TP}{FN+TP+FP}
集合交并比:mIOU=FN+TP+FPTP
集合相似度:
D
i
c
e
=
2
×
T
P
(
T
P
+
F
N
)
+
(
T
P
+
F
P
)
集合相似度:Dice=\frac{2\times TP}{(TP+FN)+(TP+FP)}
集合相似度:Dice=(TP+FN)+(TP+FP)2×TP
集合交并比:
I
O
U
=
T
P
F
N
+
T
P
+
F
P
=
T
P
F
N
+
T
P
+
F
P
+
T
P
−
T
P
=
2
T
P
2
(
F
N
+
T
P
+
F
P
+
T
P
)
−
2
T
P
=
D
i
c
e
2
−
D
i
c
e
集合交并比:IOU = \frac{TP}{FN+TP+FP}\\ = \frac{TP}{FN+TP+FP+TP-TP}\\ =\frac{2TP}{2(FN+TP+FP+TP)-2TP}\\ =\frac{Dice}{2-Dice}
集合交并比:IOU=FN+TP+FPTP=FN+TP+FP+TP−TPTP=2(FN+TP+FP+TP)−2TP2TP=2−DiceDice
由公式可知,Dice一般情况下>IOU。
曲线如下:
由于网上给的Dice系数的求解代码基本上都是batch_size=1的,当batch_size>1的时候,就没法用了,因此在这里对网上流行的代码和自己改的代码分别进行总结。
def dice_coef(output, target): # batch_size=1
smooth = 1e-5
#output = torch.sigmoid(output).view(-1).data.cpu().numpy()
output=torch.sigmoid(output)
output[output > 0.5] = 1 #将概率输出变为于标签相匹配的矩阵
output[output <= 0.5] = 0
#target = target.view(-1).data.cpu().numpy()
intersection = (output * target).sum() = TP
# \符号有换行的作用
return (2. * intersection + smooth) / \
(output.sum() + target.sum() + smooth)
# dice=2*TP/(TP+FN)+(TP+FP) def dice_coef(output, target): # Batch_size>1时 smooth = 1e-5 #output = torch.sigmoid(output).view(-1).data.cpu().numpy() output=torch.sigmoid(output).data.cpu().numpy() output[output > 0.5] = 1 #将概率输出变为于标签相匹配的矩阵 output[output <= 0.5] = 0 # target = target.view(-1).data.cpu().numpy() target = target.data.cpu().numpy() dice=0. # ipdb.set_trace() # 用于断掉调试 if len(output)>1:# 如果样本量>1,则逐样本累加 for i in range(len(output)): intersection = (output[i] * target[i]).sum() dice += (2. * intersection + smooth)/(output[i].sum() + target[i].sum() + smooth) else: intersection = (output * target).sum() # 一个数字,=TP dice = (2. * intersection + smooth) /(output.sum() + target.sum() + smooth) return dice
IOU的计算公式如下:
D
i
c
e
=
T
P
T
P
+
F
N
+
F
P
Dice=\frac{TP}{TP+FN+FP}
Dice=TP+FN+FPTP
# batch_size = 1
def iou_score(output, target):
smooth = 1e-5
if torch.is_tensor(output):
output = torch.sigmoid(output).data.cpu().numpy()
if torch.is_tensor(target):
target = target.data.cpu().numpy()
output_ = output > 0.5
target_ = target > 0.5
intersection = (output_ & target_).sum()
union = (output_ | target_).sum()
return (intersection + smooth) / (union + smooth)
#batch_size > 1 def iou_score(output, target): smooth = 1e-5 if torch.is_tensor(output): output = torch.sigmoid(output).data.cpu().numpy() if torch.is_tensor(target): target = target.data.cpu().numpy() output_ = output > 0.5 target_ = target > 0.5 # intersection = (output_ & target_).sum() # union = (output_ | target_).sum() iou = 0. if len(output)>1: for i in range(len(output)): union = (output_[i] | target_[i]).sum() intersection = (output_[i] & target_[i]).sum() iou += (intersection + smooth) / (union + smooth) else: intersection = (output_ & target_).sum() union = (output_ | target_).sum() iou = (intersection + smooth) / (union + smooth) return iou
Recall公式
def get_sensitivity(output, gt): # 求敏感度 se=TP/(TP+FN)
SE = 0.
output = output > 0.5
gt = gt > 0.5
TP = ((output==1).byte() + (gt==1).byte()) == 2
FN = ((output==0).byte() + (gt==1).byte()) == 2
#wfy:batch_num>1时,改进
if len(output)>1:
for i in range(len(output)):
SE += float(torch.sum(TP[i])) / (float(torch.sum(TP[i]+FN[i])) + 1e-6)
else:
SE = float(torch.sum(TP)) / (float(torch.sum(TP+FN)) + 1e-6) #原本只用这一句
#SE = float(torch.sum(TP)) / (float(torch.sum(TP + FN)) + 1e-6) # 原本只用这一句
return SE #返回batch中所有样本的SE和
特异性:
def get_specificity(SR, GT, threshold=0.5):#求特异性 sp=TN/(FP+TN) SR = SR > threshold #得到true和false GT = GT > threshold SP=0.# wfy # TN : True Negative # FP : False Positive TN = ((SR == 0).byte() + (GT == 0).byte()) == 2 FP = ((SR == 1).byte() + (GT == 0).byte()) == 2 #wfy:batch_num>1时,改进 if len(SR)>1: for i in range(len(SR)): SP += float(torch.sum(TN[i])) / (float(torch.sum(TN[i] + FP[i])) + 1e-6) else: SP = float(torch.sum(TN)) / (float(torch.sum(TN + FP)) + 1e-6) # 原本只用这一句 # # SP = float(torch.sum(TN)) / (float(torch.sum(TN + FP)) + 1e-6) return SP
这两个指标在医疗领域很常用,而在机器学习领域常用的是Recall和Precision。
暂略
ppv=precision
def ppv(output, target): #阳性预测值,准确率(precision)pr = TP/(TP+FP) smooth = 1e-5 if torch.is_tensor(output): output = torch.sigmoid(output).data.cpu().numpy() if torch.is_tensor(target): target = target.data.cpu().numpy() ppv=0. if len(output)>1: for i in range(len(output)): intersection = (output[i] * target[i]).sum() ppv += (intersection + smooth)/(output[i].sum() + smooth) else: intersection = (output * target).sum() # 一个数字,=TP ppv = (intersection + smooth)/(output.sum() + smooth) # intersection = (output * target).sum() # TP return ppv
def get_F1(output, gt):
se = get_sensitivity(output, gt)
pc = get_precision(output, gt)
f1 = 2*se*pc / (se+pc+1e-6)
return f1
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。