SE, SP, PC, F1, JS, DC医学图像分割训练的时候全为0?医学图像分割的评价指标

本文讨论了在使用深度学习模型进行图像分割时遇到的评价指标为0的问题。作者详细分析了问题原因,包括数据集非严格二值化、标签处理方式以及代码中的逻辑错误。通过调整代码,特别是修正了比较逻辑,解决了TP、FN等计数始终为0的错误,从而能够正确计算精确率、召回率等指标。


出现的问题

验证是一个深度图像分割模型是一个基本的任务,它评价了模型的好坏,以便于更好改进。
自己模型训练时候评价指标出现的问题,使用别人的代码https://github.com/LeeJunHyun/Image_Segmentation,改成自己的数据集之后错误频出,终于能开始训练,SE, SP, PC, F1, JS, DC这些指标全为0。整了1天。
还有一种可能,可能训练失败,Loss为NAN,然后其他指标也是0。我用的Focal Loss,把初始学习率调小一点。

解决方法

最新发现自己的数据集不是严格的二值,但是像素集中在0和255,为什么用他的evaluation不行,待研究。就是用我修改后的代码是可以的。

import cv2
import numpy as np
import matplotlib.pyplot as plt
path = '../tg3k/thyroid-mask/'
img = cv2.imread(path+'0001.jpg',-1)  
hist = cv2.calcHist([img], [0], None, [256], [0, 256])

在这里插入图片描述

最后发现自己的mask是灰度图,不是二值图像。转变成tensor,进行二值化即可。不必修改原作者的代码。😂

分割线————————————————————————————————————————

刚开始的时候,在考虑是不是模型崩塌了,输出的全是黑的,所以这些值全为0。看着Loss一点一点减少,acc增加,以及准确率明显大于只输出为黑色mask的情况,排除这个可能。
第二个我试了试GT,输出出来它是单通道,但是评价指标里面GT变成bool量,我觉得是二值化,他是用的 GT == torch.max(GT)。我测试一下,在我的数据集上输出来全是0。可能这个模型的标签是二值图像可以这样,我的图片还需要自己二值化。然后我就把它二值化了。

GT =GT/torch.max(GT) > threshold

训练了一次还是全为0????
我看着代码没问题。后来我输出TN,TP,FN,FP,发现他们也是全为0。这就奇怪了。
最后,我发现问题出现在这个代码上。

TP = ((SR==1)+(GT==1))==2

我在jupyter notebook里面跑了一下,发现这个不管SR和GT是什么它跑出来全是False。我才发现就是SR,GT相加也是bool值0-1,不会出现2。就只能用逻辑运算替换了。或者把这个bool量转换成float或者其他类型(我没试过)。我用的逻辑运算替换。

import torch


# SR : Segmentation Result
# GT : Ground Truth

def get_accuracy(SR, GT, threshold=0.5):
    SR = SR > threshold
    GT = GT / torch.max(GT) > threshold
    corr = (SR == GT).sum().item()
    tensor_size = SR.size(0) * SR.size(1)* SR.size(2) * SR.size(3)
    acc = float(corr) / float(tensor_size)

    return acc


def get_sensitivity(SR, GT, threshold=0.5):
    # Sensitivity == Recall
    SR = SR > threshold
    GT = GT / torch.max(GT) > threshold

    # TP : True Positive
    # FN : False Negative
    TP = ((SR == 1) & (GT == 1)).sum().item()
    FN = ((SR == 0) & (GT == 1)).sum().item()
    FP = ((SR == 1) & (GT == 0)).sum().item()
    TN = ((SR == 0) & (GT == 0)).sum().item()
    # TN = ((SR==0)*(GT==0))
    # FP = ((SR==1)*(GT==0))
    SE = float(TP) / (float(TP + FN)+ 1e-6)
    # print('TP:'+str(TP))
    # print('FN:' + str(FN))
    # print('FP:' + str(FP))
    # print('TN:' + str(TN))
    
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值