Что не так с моими кривыми ROC при рассмотрении подходов глубокого наклона? - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть приложение, которое классифицирует изображения с помощью CNN.Я рассматриваю Mobilenet, Resnet и Densenet на входных размерах блоков изображения 64 x 64.Чтобы классифицировать изображение, я определяю его класс как класс, наиболее присутствующий при классификации его блоков.Проблема очень несбалансированная, у меня больше положительных образцов, чем отрицательных.Я рассматриваю три набора данных.

Чтобы решить эту проблему, я сначала рассчитал такие метрики, как f-мера, нормализованная точность и так далее.Вот нормализованные результаты точности для некоторых наборов данных с учетом трех CNN:

enter image description here

Чтобы построить кривую ROC, я решил определить оценку изображениясредняя оценка его блоков, так что вот где начинается моя проблема.Пожалуйста, взгляните на некоторые кривые ROC для этих наборов данных, учитывая три CNN ниже:

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

Мне довольно странно видеть, что подходы, которые получили 50% нормированную точность, также получили 0,85, 0,90 и даже 0,97 AUC.Этот последний AUC, кажется, от почти идеального классификатора, но как это возможно, если его нормализованная точность составляет 50%?

Итак, каковы причины этого?это потому что:

1 - моя проблема не сбалансирована.Так есть ли положительные образцы, которые в основном встречаются в моих наборах данных и влияет ли на результат мой класс 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 Ответ

0 голосов
/ 27 декабря 2018

Из того, что я понимаю о вашем методе - входное изображение делится на отдельные патчи, которые обрабатываются независимо моделью CNN.Каждый патч получает свою собственную классификацию (или оценку, в зависимости от того, идет ли он после или до Softmax).Чем класс изображения определяется на основе голосования классов исправлений.

Но, когда вы строите свою кривую ROC, вы используете средние оценки отдельных исправлений для определения классификацииimage.

Эти два разных подхода являются причиной диссоциации между AUC и нормированной точностью.

Например:

Скажем, у вас есть3 пятна на изображении со следующими вероятностями (для 2 классов):

[cls a, cls b]

[0.51, 0.49]

[0.51, 0.49]

[0,01, 0,99]

При голосовании класс a является прогнозом (2 патча против 1), по среднему классу баллов b является прогнозом (0,657 против 0,343).

Лично я не думаю, что голосование - это правильный способ классификации изображения на основе исправлений, поскольку он не учитывает определенность модели в отношении различных исправлений, как было показано в примере.Но вы более знакомы с вашим набором данных, так что, возможно, я ошибаюсь.

Относительно того, как преодолеть вашу проблему, я думаю, что некоторая дополнительная информация о природе набора данных и задаче поможет (насколько несбалансированным, что являетсяконечная цель и т.д ..)

...