1. Dcie
1.1. 定义
Dice系数是一种基于像素级别的相似度度量,通常用于比较两个二进制图像的相似程度。它计算两个集合之间的相似度,即预测结果和真实标签之间的相似度,其计算公式如下:
D i c e = 2 ∗ T P 2 ∗ T P + F P + F N Dice=\frac{2*TP}{2*TP+FP+FN} Dice=2∗TP+FP+FN2∗TP
其中,TP(True Positive)表示预测为正样本且标签为正样本的像素数量,FP(False Positive)表示预测为正样本但标签为负样本的像素数量,FN(False Negative)表示预测为负样本但标签为正样本的像素数量。
Dice系数的取值范围在0到1之间,其值越接近1,表示预测结果与真实标签的重叠度越高,相似度越高。
1.2. 代码实现
A
def dice_coefficient_numpy(binary_segmentation, binary_gt_label):
'''
Compute the Dice coefficient between two binary segmentation.
Dice coefficient is defined as here: https://en.wikipedia.org/wiki/S%C3%B8rensen%E2%80%93Dice_coefficient
Input:
binary_segmentation: binary 2D numpy array representing the region of interest as segmented by the algorithm
binary_gt_label: binary 2D numpy array representing the region of interest as provided in the database
Output:
dice_value: Dice coefficient between the segmentation and the ground truth
'''
# turn all variables to booleans, just in case
binary_segmentation = np.asarray(binary_segmentation, dtype=bool)
binary_gt_label = np.asarray(binary_gt_label, dtype=bool)
# compute the intersection
intersection = np.logical_and(binary_segmentation, binary_gt_label)
# count the number of True pixels in the binary segmentation
segmentation_pixels = float(np.sum(binary_segmentation.flatten()))
# same for the ground truth
gt_label_pixels = float(np.sum(binary_gt_label.flatten()))
# same for the intersection
intersection = float(np.sum(intersection.flatten()))
# compute the Dice coefficient
dice_value = (2 * intersection + 1.0) / \
(1.0 + segmentation_pixels + gt_label_pixels)
# return it
return dice_value
def dice_coeff_2label(pred, target):
"""This definition generalize to real valued pred and target vector.
This should be differentiable.
pred: tensor with first dimension as batch
target: tensor with first dimension as batch
"""
target = target.data.cpu()
# pred = torch.sigmoid(pred)
# pred = pred.data.cpu()
# pred[pred > 0.75] = 1
# pred[pred <= 0.75] = 0
# print target.shape
# print pred.shape
if len(pred.shape) == 3:
return dice_coefficient_numpy(pred[0, ...], target[0, ...])
else:
dice_cup = []
dice_disc = []
for i in range(pred.shape[0]):
# cup, disc = dice_coefficient_numpy(pred[i, 0, ...], target[i, 0, ...]), dice_coefficient_numpy(pred[i, 1, ...], target[i, 1, ...])
cup = dice_coefficient_numpy(pred[i, 0, ...], target[i, 0, ...])
dice_cup.append(cup)
# dice_disc.append(disc)
return sum(dice_cup) / len(dice_cup)
def iou_coefficient_numpy(binary_segmentation, binary_gt_label):
'''
Compute the Intersection over Union (IoU) coefficient between two binary segmentations.
IoU is defined as intersection area divided by union area.
Input:
binary_segmentation: binary 2D numpy array representing the region of interest as segmented by the algorithm
binary_gt_label: binary 2D numpy array representing the region of interest as provided in the database
Output:
iou_value: IoU coefficient between the segmentation and the ground truth
'''
# Convert inputs to boolean arrays
binary_segmentation = np.asarray(binary_segmentation, dtype=bool)
binary_gt_label = np.asarray(binary_gt_label, dtype=bool)
# Compute the intersection and union
intersection = np.logical_and(binary_segmentation, binary_gt_label)
union = np.logical_or(binary_segmentation, binary_gt_label)
# Count the number of True pixels
intersection_pixels = float(np.sum(intersection))
union_pixels = float(np.sum(union))
# Compute IoU
# Add small epsilon to avoid division by zero
iou_value = intersection_pixels / (union_pixels + 1e-6)
return iou_value
def iou_coeff_2label(pred, target):
'''
Generalized IoU computation for batched input.
pred: tensor with first dimension as batch
target: tensor with first dimension as batch
'''
target = target.data.cpu()
if len(pred.shape) == 3:
return iou_coefficient_numpy(pred[0, ...], target[0, ...])
else:
iou_cup = []
for i in range(pred.shape[0]):
cup = iou_coefficient_numpy(pred[i, 0, ...], target[i, 0, ...])
iou_cup.append(cup)
return sum(iou_cup) / len(iou_cup)
B
def iou_score(output, target):
smooth = 1e-5
if torch.is_tensor(output):
# output = torch.sigmoid(output).data.cpu().numpy()
output = 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 = (intersection + smooth) / (union + smooth)
# dice = dice_coef(output, target)
dice = (2 * intersection) / (output_.sum() + target_.sum())
# dice = (2 * iou) / (iou + 1)
auc = 0
# = roc_auc_score(target.flatten(), output.flatten())
output_ = torch.tensor(output_)
target_ = torch.tensor(target_)
# SE = get_sensitivity(output_, target_, threshold=0.5)
# PC = get_precision(output_, target_, threshold=0.5)
# SP = get_specificity(output_, target_, threshold=0.5)
# ACC = get_accuracy(output_, target_, threshold=0.5)
# F1 = 2 * SE * PC / (SE + PC + 1e-6)
SE = 0
PC = 0
SP = 0
ACC = 0
F1 = 2 * SE * PC / (SE + PC + 1e-6)
return iou, dice, SE, PC, F1, SP, ACC, auc
2. IoU
IOU是一种广泛用于目标检测和语义分割中的指标,它表示预测结果与真实标签的交集与并集之比,其计算公式如下:
I o U = T P T P + F P + F N IoU=\frac{TP}{TP+FP+FN} IoU=TP+FP+FNTP
与Dice系数类似,IOU的取值范围也在0到1之间,其值越接近1,表示预测结果与真实标签的重叠度越高,相似度越高。
Dice系数和IOU的计算方式略有不同,但它们的主要区别在于Dice系数对预测结果和真实标签的交集和并集的贡献是相等的,而IOU更加关注预测结果与真实标签的交集。因此,Dice系数更加敏感于小目标,而IOU则更加适用于大目标的检测和分割任务。
3. Precision
精确度(Precision, PC) 是评估分类模型性能的一项重要指标,它衡量了模型在预测为正类别的样本中有多少是真正的正类别。Precision 的计算公式如下:
P C = T P T P + F P PC=\frac{TP}{TP+FP} PC=TP+FPTP
Precision 的取值范围是 0 到 1,数值越高表示模型在正类别的预测上越准确。高 Precision 值意味着模型很少地将负类别误判为正类别。
4. Recall
R e c a l l = T P T P + F N Recall=\frac{TP}{TP+FN} Recall=TP+FNTP
通常情况下,精确率(PC)和召回率(Reacll)是相互矛盾的,提高精确率会降低召回率,反之亦然。
因此,常常使用 F1-Score 来综合评价模型的性能,其计算公式如下: F 1 = 2 ∗ P r e c i s i o n ∗ R e c a l l P r e c i s i o n + R e c a l l F1 = \frac{2 * Precision * Recall}{Precision + Recall} F1=Precision+Recall2∗Precision∗Recall
5. AUC
AUC(Area Under the Curve)是一种用于评估二分类模型性能的指标,通常是 ROC 曲线(Receiver Operating Characteristic Curve)下的面积。ROC 曲线是一种以真正类别率(True Positive Rate,也称为 Recall 或 Sensitivity)为纵轴,假正类别率(False Positive Rate)为横轴的图形,展示了在不同阈值下模型的性能。AUC 的计算公式如下:
A U C = Σ I ( p 正样本 , p 负样本 ) P + F AUC=\frac{\Sigma{I(p_{正样本},p_{负样本})}}{P+F} AUC=P+FΣI(p正样本,p负样本)
其中:
Σ I ( p 正样本 , p 负样本 ) = { 1 , ( p 正样本 > p 负样本 1 , ( p 正样本 = p 负样本 , p 表示预测得分 1 , ( p 正样本 < p 负样本 \Sigma{I(p_{正样本},p_{负样本})} = \begin{cases} 1, & (p_{正样本}>p_{负样本} \\ 1, & (p_{正样本}=p_{负样本} , p表示预测得分\\ 1, & (p_{正样本}<p_{负样本} \end{cases} ΣI(p正样本,p负样本)=⎩ ⎨ ⎧1,1,1,(p正样本>p负样本(p正样本=p负样本,p表示预测得分(p正样本<p负样本
AUC 的优势在于它对类别不平衡的数据具有较好的鲁棒性,不受正负样本分布不均匀的影响。
通过PC和IoU计算Recall:
pc=57.21
iou=44.09
recall = 100/(1+(100-iou)/iou-(100-pc)/pc)
print(recall)