Классификатор CNN с keras показывает точность (и категориальную точность) 1, но все же многие прогнозы ложны - PullRequest
0 голосов
/ 03 августа 2020

Я обучил классификатор CNN и получаю странные результаты. При обучении достигает 1 точности (а также категориальной точности, какая бы разница ни была). Однако, когда я предсказываю на обучающих выборках вручную, я редко получаю правильный класс после np.argmax (), что кажется очень странным. Я подумал, что это может быть плохое сопоставление классов, но после проверки сопоставления классов генератора все выглядит нормально.

Я подозреваю, что способ ввода изображений для тестирования отличается от способа, которым генератор данных передает изображения для обучение, это единственное возможное объяснение. Вот код:

datagen = ImageDataGenerator(rescale=1./255)
train_classif_generator = datagen.flow_from_directory('full_ae_output/classifier_classes',target_size=image_dims_original, batch_size=batch_size,shuffle=True, color_mode='grayscale')

classifier = Sequential()

classifier.add(Conv2D(8, (3, 3), padding='same', input_shape=image_input_dims))
classifier.add(Activation('relu'))
classifier.add(MaxPooling2D(pool_size=(2,2), padding='same'))

#2nd convolution layer
classifier.add(Conv2D(8, (3, 3), padding='same'))
classifier.add(Activation('relu'))
classifier.add(MaxPooling2D(pool_size=(2,2), padding='same'))

#3rd convolution layer
classifier.add(Conv2D(16, (3, 3), padding='same'))
classifier.add(Activation('relu'))
classifier.add(MaxPooling2D(pool_size=(2,2), padding='same'))


# Classifier
classifier.add(Flatten())
classifier.add(Dense(n_classes*2,activation='relu'))
#classifier.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
classifier.add(Dense(n_classes, activation='softmax'))

classifier.summary()

classifier.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['categorical_accuracy'])

Эпоха 1/3 92/92 [============================ ====] - 108 с 1 с / шаг - потеря: 0,0638 - категориальная_точность: 0,9853 Эпоха 2/3 92/92

[============ ==================] - 107 с 1 с / шаг - потеря: 0,0141 - категориальная_точность: 0,9969 Эпоха 3/3 92/92

[==============================] - 108 с 1 с / шаг - потеря: 0,0188 - категориальная_точность: 0,9938

input_class = 10
i = 0
image_path = glob.glob("full_ae_output/classifier_classes/class"+"{0:0=3d}".format(input_class)+"/*")[i]
input_img = np.array([np.array(Image.open(image_path).convert('L').resize(image_dims_original[::-1]))/255])
pred = classifier.predict(np.expand_dims(input_img,axis=3))
print("Predicted class = ",np.argmax(pred[0]))

Я не пересчитывал фактическую точность, но подозреваю, что она ниже 50%, поскольку каждый образец, который я пробую, я никогда не получаю нужного класса.

Есть идеи, что может мешать ? Является ли точность обучения, вычисляемая keras, ложной?

Ответы [ 2 ]

0 голосов
/ 03 августа 2020

Точность обучения определенно не является ложной, как вычислено Керасом.

Ваша интуиция хороша, действительно, именно этап предварительной обработки на тестовых изображениях вызывает эту проблему.

Я бы порекомендовал что вы загружаете одно изображение и проверяете, как ImageDataGenerator работает за кулисами, и проверяете, что при использовании Pillow применяются точные шаги предварительной обработки.

0 голосов
/ 03 августа 2020

Нашел! Это просто вопрос интерполяции, генератор данных по умолчанию использует ближайший, а opencv.resize использует билинейную интерполяцию. Невероятно, как эта разница портит классификатор и меняет все прогнозы. Исправлено, и я получаю свою 100% точность прямо сейчас. Проблема решена!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...