代码之家  ›  专栏  ›  技术社区  ›  mad

在考虑深度倾斜方法时,我的ROC曲线有什么问题?

  •  1
  • mad  · 技术社区  · 7 年前

    我有一个应用程序,用CNN对图像进行分类。我正在考虑在64 x 64图像块的输入大小上使用Mobilenet、Resnet和Densenet。为了对图像进行分类,我将其类定义为对其块进行分类时最常见的类。问题是高度不平衡的,我的阳性样本比阴性样本多。我正在考虑三个数据集。

    enter image description here

    enter image description here enter image description here enter image description here

    我觉得很奇怪的是,获得50%标准化准确度的方法也得到了0.85、0.90甚至0.97 AUC。最后一个AUC似乎来自一个近乎完美的分类器,但如果其标准化精度为50%,这怎么可能呢?

    我的问题是不平衡的。那么,主要在我的数据集中发现的阳性样本,以及我的ROC兴趣类别是否影响结果?

    2-我使用块的平均分数作为图像的分数。这是解决这个问题的方法吗?

    下面是我用来生成标签和分数的代码(PYTHON)

     base_model=MobileNet(input_shape (64,64,3),weights=None,include_top=False)
        x = base_model.output
        x = GlobalAveragePooling2D()(x)
        x = Dense(64, activation='relu')(x)
        predictions = Dense(2, activation='softmax')(x)
        model = Model(inputs=base_model.input, outputs=predictions)
        model.load_weights(model_path)
    
        intermediate_layer_model = Model(inputs=model.input, outputs=model.get_layer("dense_2").output)
        print("Loaded model from disk")
        intermediate_layer_model.compile(loss='categorical_crossentropy', optimizer=algorithm, metrics=['accuracy'])
    
        #read images, divide them into blocks, predict images and define the mean scores as the score for an image
        with open(test_images_path) as f:
                images_list = f.readlines()
                images_name = [a.strip() for a in images_list]
                predicted_image_vector = []
                groundtruth_image_vector = []
    
                for line in images_name:
                    x_test=[]
                    y_test=[]
                    print(line)
                    image = cv2.imread(line,1)
                    #divide into blocks
                    windows = view_as_windows(image, (64,64,3), step=64)
    
                    #prepare blocks to be tested later 
                    for i in range(windows.shape[0]):
                        for j in range(windows.shape[1]):
                                block=np.squeeze(windows[i,j])
                                x_test.append(block)
                                label = du.define_class(line)
                                y_test.append(label)
    
                #predict scores for all blocks in the current test image
                intermediate_output = intermediate_layer_model.predict(np.asarray(x_test), batch_size=32, verbose=0)
                #the score for an image is the mean score of its blocks
                prediction_current_image=np.mean(intermediate_output, axis=0)
                predicted_image_vector.append(prediction_current_image)
     groundtruth_image_vector.append(np.argmax(np.bincount(np.asarray(y_test))))
    
        predicted_image_vector=np.array(predicted_image_vector)
        groundtruth_image_vector=np.array(groundtruth_image_vector)
        print("saving scores and labels to plot ROC curves")
    
        np.savetxt(dataset_name+ '-scores.txt', predicted_image_vector, delimiter=',') 
        np.savetxt(dataset_name+ '-labels.txt', groundtruth_image_vector, delimiter=',') 
    

    下面是我用来生成ROC曲线的代码(MATLAB)

    function plot_roc(labels_file, scores_file, name_file, dataset_name)
    
        format longG
        label=dlmread(labels_file);
        scores=dlmread(scores_file);
        [X,Y,T,AUC] = perfcurve(label,scores(:,2),1);   
    
        f=figure()
        plot(X,Y);
        title(['ROC Curves for Mobilenet in ' dataset_name])
        xlabel('False positive rate'); 
        ylabel('True positive rate');
        txt = {'Area Under the Curve:', AUC};
        text(0.5,0.5,txt)
        saveas(f, name_file);
        disp("ok")
    
    
    
    end
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Mark.F    7 年前

    从我对你的方法的理解来看,输入图像被划分为单独的面片,这些面片由CNN模型独立处理。每个补丁都有自己的分类(或分数,取决于它是在softmax之后还是之前)。然后,根据面片类的投票确定图像的类。

    但是,当你建立ROC曲线时,你使用的是单个面片的平均分数来确定图像的分类。

    这两种不同的方法是AUC和标准化精度之间不关联的原因。

    例如:

    [cls a,cls b]

    [0.51, 0.49]

    [0.51, 0.49]

    通过投票,a类为预测(2个补丁vs 1),平均得分b类为预测(0.657 vs 0.343)。

    就我个人而言,我不认为投票是基于面片对图像进行分类的正确方法,因为它没有考虑到关于不同面片的模型的确定性,如示例所示。但您更熟悉您的数据集,所以可能我错了。

    关于如何克服您的问题,我认为有关数据集性质和任务的更多信息会有所帮助(有多不平衡,最终目标是什么,等等)