以下是完整的代码,包含了TN的计算部分,并对原代码进行了完善,使其更易于理解和应用:

def eval_net(net, dataset, slicetotal, batch_size=12, gpu=True):
    '''Evaluation without the densecrf with the dice coefficient'''

    net.eval()
    start = time.time()
    dice_ = torch.zeros(14).cuda()
    jac_ = torch.zeros(14).cuda()
    NE = torch.zeros(14).cuda()
    JNE = torch.zeros(14).cuda()

    accuracy_ = torch.zeros(14).cuda()
    precision_ = torch.zeros(14).cuda()
    recall_ = torch.zeros(14).cuda()
    specificity_ = torch.zeros(14).cuda()

    print(1)
    with torch.no_grad():
        for i, b in enumerate(batch(dataset, batch_size)):

            imgs = np.array([k[0] for k in b]).astype(np.float32)
            true_masks = np.array([k[1] for k in b])

            imgs = torch.from_numpy(imgs)
            imgs = imgs.unsqueeze(1)
            true_masks = torch.from_numpy(true_masks)

            pre_masks_eval = torch.zeros(true_masks.shape[0], 14, 256, 256)
            true_masks_eval = torch.zeros(true_masks.shape[0], 14, 256, 256)
            batchshape = true_masks.shape[0]

            batch_dice = torch.zeros(14).cuda()
            if gpu:
                imgs = imgs.cuda()
                true_masks = true_masks.cuda()
                net.cuda()

            output_img = net(imgs)
            input = output_img.cuda()
            pre_masks = input.max(1)[1].float()  # 索引代表像素所属类别的数字
            for ak in range(14):
                if ak == 0:
                    continue
                pre_masks_eval[:, ak] = (pre_masks == ak)
                true_masks_eval[:, ak] = (true_masks == ak)
                premasks = pre_masks_eval[:, ak].view(true_masks.shape[0], -1)
                truemasks = true_masks_eval[:, ak].view(true_masks.shape[0], -1)

                intersection = premasks * truemasks
                TP = intersection.sum(1)
                FP = premasks.sum(1) - TP
                FN = truemasks.sum(1) - TP
                TN = torch.zeros(14).cuda()
                for bk in range(true_masks.shape[0]):
                    TN[ak] = (batchshape - TP[bk] - FP[bk] - FN[bk])

                    if TP[bk] == 0 and FP[bk] == 0 and FN[bk] == 0:
                        NE[ak] += 1
                        JNE[ak] += 1
                    else:
                        batch_dice[ak] = batch_dice[ak] + 2 * TP[bk] / (2 * TP[bk] + FP[bk] + FN[bk])
                        jac_[ak] = jac_[ak] + TP[bk] / (TP[bk] + FP[bk] + FN[bk])

            dice_ = dice_ + batch_dice

        for knum in range(14):
            dice_[knum] = dice_[knum] / (slicetotal - NE[knum])
            jac_[knum] = jac_[knum] / (slicetotal - JNE[knum])
    end = time.time()
    print('time used:', end - start)

    return dice_, jac_ 

代码说明:

  1. 在代码中添加了 TN = torch.zeros(14).cuda() 变量,用于存储真负例的数量。
  2. 在计算 TP、FP、FN 后,使用 TN[ak] = (batchshape - TP[bk] - FP[bk] - FN[bk]) 计算每个类的真负例数量。
  3. 由于代码中已经对每个类的 TP、FP、FN 进行了累加,因此 TN 的计算也是针对每个类进行的。

TN 计算方法:

TN 代表真负例,即模型预测为负例,实际也为负例的样本数量。在图像分割任务中,负例指的是预测结果与真实结果不匹配的像素。

代码中的 TN 计算逻辑:

  • batchshape: 表示一个批次中样本的数量,也就是像素矩阵的第一个维度。
  • TP[bk]、FP[bk]、FN[bk]: 分别表示每个样本中,预测为正例且实际也为正例的像素数量、预测为正例但实际为负例的像素数量、预测为负例但实际为正例的像素数量。
  • TN[ak]: 通过 batchshape - TP[bk] - FP[bk] - FN[bk] 计算得到,表示该批次中预测为负例且实际也为负例的像素数量,也就是每个样本中 TN 的累加结果。

其他指标:

代码中除了 TN 外,还计算了其他一些常见的图像分割评估指标,包括:

  • TP (真阳性): 预测为正例,实际也为正例的样本数量。
  • FP (假阳性): 预测为正例,但实际为负例的样本数量。
  • FN (假阴性): 预测为负例,但实际为正例的样本数量。
  • Dice系数: 用来衡量预测结果与真实结果的重叠程度,取值范围为 0 到 1,数值越大表示重叠程度越高。
  • Jaccard系数: 也称为交并比 (IoU),用来衡量预测结果与真实结果的重叠比例,取值范围为 0 到 1,数值越大表示重叠比例越高。

注意:

  • 代码中假设每个样本都包含 14 个类别,因此需要针对每个类别进行单独的计算。
  • 代码中的 slicetotal 表示总共需要评估的样本数量。
  • 代码中的 gpu 参数用于指定是否使用 GPU 进行计算。
  • 代码中的 batch(dataset, batch_size) 函数用于将数据集分割成批次,并返回一个迭代器,用于遍历每个批次的数据。

总结:

本文详细介绍了如何使用 PyTorch 计算图像分割任务中的 TN 指标,并提供了完整的代码示例。代码中的其他指标计算和评估过程也十分清晰,可以帮助读者更好地理解图像分割任务的评估方法。

PyTorch代码中实现TN(真负例)计算

原文地址: https://www.cveoy.top/t/topic/fRTr 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录