【问题标题】:How to create a confusion matrices for an image segmentation task?如何为图像分割任务创建混淆矩阵?
【发布时间】:2022-04-08 18:20:30
【问题描述】:

我正在处理二进制图像分割问题。我已经成功编译并训练了模型。现在我正在努力实现两个目标:

  1. 获取测试集的总混淆矩阵(原因:了解误报和误报的比例)
  2. 为测试集中的每个图像获取单独的混淆矩阵(原因:查找并分析拖累模型性能的图像)

据我了解,scikit-learn 包中的confusion_matrix 可以帮助处理完全混淆矩阵,但我无法使其与我的自定义数据生成器一起使用。根据文档,这是confusion_matrix 的代码:

sklearn.metrics.confusion_matrix(y_true, y_pred, *, labels=None, sample_weight=None, normalize=None)

我不明白如何使用我的自定义数据生成器检索 y_true

def learn_generator(templates_folder, masks_folder, image_width, batch_size, shuffle=True):
    """Generate individual batches form dataset"""
    counter = 0
    images_list = os.listdir(templates_folder)
    if shuffle:
        random.shuffle(images_list)
    while True:
        templates_pack = np.zeros((batch_size, image_width, image_width, 3)).astype('float')
        masks_pack = np.zeros((batch_size, image_width, image_width, 1)).astype('float')
        for i in range(counter, counter + batch_size):
            template = cv2.imread(templates_folder + '/' + images_list[i]) / 255.
            templates_pack[i - counter] = template
            mask = cv2.imread(masks_folder + '/' + images_list[i], cv2.IMREAD_GRAYSCALE) / 255.
            mask = np.expand_dims(mask, axis=2)
            masks_pack[i - counter] = mask
        counter += batch_size
        if counter + batch_size >= len(images_list):
            counter = 0
            if shuffle:
                random.shuffle(images_list)
        yield templates_pack, masks_pack

test_templates_path = "E:/Project/images/all_templates/test"
test_masks_path = "E:/Project/images/all_masks/test"
TEST_SET_SIZE = len(os.listdir(test_templates_path))
IMAGE_WIDTH = 512
BATCH_SIZE = 4
TEST_STEPS = TEST_SET_SIZE / BATCH_SIZE

test_generator = learn_generator(test_templates_path, test_masks_path, IMAGE_WIDTH, batch_size=BATCH_SIZE)
Y_pred = model.predict_generator(test_generator, steps=TEST_STEPS)
y_pred = np.argmax(Y_pred, axis=1)

y_true = ???

至于个人混淆矩阵,根本没有想法...... 任何帮助表示赞赏。

【问题讨论】:

    标签: python keras image-segmentation


    【解决方案1】:

    我想对你来说为时已晚,但也许这可以帮助其他人:

    我确实通过使用混淆矩阵的定义,通过计算真阳性、真阴性、假阳性、假阴性来实现这一点。

    此代码仅适用于二进制分割,假设“1”是“正”的输出,“0”是“负”的输出...

        import seaborn as sns
    
        FP = len(np.where(Y_pred - Y_val  == -1)[0])
        FN = len(np.where(Y_pred - Y_val  == 1)[0])
        TP = len(np.where(Y_pred + Y_val ==2)[0])
        TN = len(np.where(Y_pred + Y_val == 0)[0])
        cmat = [[TP, FN], [FP, TN]]
    
        plt.figure(figsize = (6,6))
        sns.heatmap(cmat/np.sum(cmat), cmap="Reds", annot=True, fmt = '.2%', square=1,   linewidth=2.)
        plt.xlabel("predictions")
        plt.ylabel("real values")
        plt.show()
    

    confusion_matrix

    【讨论】:

      【解决方案2】:

      https://www.kite.com/blog/python/image-segmentation-tutorial/

      我认为您可以从本网站更改两个类的代码并将其应用于您的用例。

      另外,我认为这个答案确实提供了sklearn混淆矩阵方法Faster method of computing confusion matrix?的实现@

      【讨论】:

        【解决方案3】:

        x - 预测

        y - 基本事实

        6 是图像数量,576 X 576 是分辨率,[0]-(一个通道) 是图像数量。在我的情况下,您可以相应地更改它。您可能需要为多通道图像添加另一个循环。此外,这是用于二进制分割。所以,真阳性我考虑过黑色像素和白色像素的真阴性。您可以根据需要的功能进行互换。另外我已经根据我的要求修改了我之前的答案,你可以在你的情况下做同样的事情。

        def res_eval(x,y):
                TP = 0
                TN = 0
                FP = 0
                FN = 0
                for i in range(6):
                    for j in range(576):
                      for k in range(576):
                        if round(x[i][j][k][0])==True and y[i][j][k][0]==True:
                          TP = TP + 1
                        elif round(x[i][j][k][0])==False and y[i][j][k][0]==False:
                          TN = TN + 1
                        elif round(x[i][j][k][0])==True and y[i][j][k][0]==False:
                          FP = FP + 1
                        elif round(x[i][j][k][0])==False and y[i][j][k][0]==True:
                          FN = FN + 1
                return TP, TN, FP, FN
        
        def conf_mat(TP, TN, FP, FN):
            cmat = [[TP, FN], [FP, TN]]
        
            plt.figure(figsize = (6,6))
            sns.heatmap(cmat/np.sum(cmat), cmap="Reds", annot=True, fmt = '.2%', square=1,   linewidth=2.)
            plt.xlabel("predictions")
            plt.ylabel("real values")
            plt.show()
        

        【讨论】:

          猜你喜欢
          • 2021-03-26
          • 2021-03-02
          • 2018-04-27
          • 2018-12-19
          • 2017-08-20
          • 1970-01-01
          • 1970-01-01
          • 2017-02-01
          • 1970-01-01
          相关资源
          最近更新 更多