У меня есть приложение, которое классифицирует изображения с помощью CNN.Я рассматриваю Mobilenet, Resnet и Densenet на входных размерах блоков изображения 64 x 64.Чтобы классифицировать изображение, я определяю его класс как класс, наиболее присутствующий при классификации его блоков.Проблема очень несбалансированная, у меня больше положительных образцов, чем отрицательных.Я рассматриваю три набора данных.
Чтобы решить эту проблему, я сначала рассчитал такие метрики, как f-мера, нормализованная точность и так далее.Вот нормализованные результаты точности для некоторых наборов данных с учетом трех CNN:
Чтобы построить кривую ROC, я решил определить оценку изображениясредняя оценка его блоков, так что вот где начинается моя проблема.Пожалуйста, взгляните на некоторые кривые ROC для этих наборов данных, учитывая три CNN ниже:
Мне довольно странно видеть, что подходы, которые получили 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