【问题标题】:Why do I keep having class "1" as the predicted class?为什么我一直将“1”类作为预测类?
【发布时间】:2019-06-01 18:26:50
【问题描述】:

我在 Keras 中有以下卷积神经网络 (CNN),但如果训练数据是平衡的,则将测试图像的预测保持为“1”类。关于如何解决这个问题的任何想法?谢谢。

from keras import layers
from keras import models
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator
from sklearn.metrics import roc_curve
from sklearn.metrics import auc
import cv2
import numpy as np
import os

train_directory = '/train'
validation_directory = '/valid'
test_directory = '/test'
results_directory = '/results'
correct_classification = 0
number_of_test_images = 0
labels = []
prediction_probabilities = []

model = models.Sequential()

model.add(layers.Conv2D(32,(3,3),activation='relu',input_shape=(512,512,3)))
model.add(layers.MaxPooling2D(2,2))
model.add(layers.Conv2D(64,(3,3),activation='relu'))
model.add(layers.MaxPooling2D(2,2))
model.add(layers.Conv2D(128,(3,3),activation='relu'))
model.add(layers.MaxPooling2D(2,2))
model.add(layers.Conv2D(256,(3,3),activation='relu'))
model.add(layers.MaxPooling2D(2,2))
model.add(layers.Conv2D(512,(3,3),activation='relu'))
model.add(layers.MaxPooling2D(2,2))

model.add(layers.Flatten())
model.add(layers.Dense(1024,activation='relu'))
model.add(layers.Dense(1,activation='sigmoid'))

model.compile(loss='binary_crossentropy',optimizer='rmsprop',metrics=['acc'])

train_data = ImageDataGenerator(rescale=1.0/255)
validation_data = ImageDataGenerator(rescale=1.0/255)

train_generator = train_data.flow_from_directory(train_directory,target_size=(512,512),batch_size=20,class_mode='binary')
validation_generator = validation_data.flow_from_directory(validation_directory,target_size=(512,512),batch_size=20,class_mode='binary')

history = model.fit_generator(train_generator,
    steps_per_epoch=10,
    epochs=10,
    validation_data=validation_generator,
    validation_steps=5)

model.save('my_model.h5')

for root, dirs, files in os.walk(test_directory):
    for file in files:
        img = cv2.imread(root + '/' + file)
        img = cv2.resize(img,(512,512),interpolation=cv2.INTER_AREA)
        img = np.expand_dims(img, axis=0)
        img = img/255.0
        if os.path.basename(root) == 'nevus':
            label = 1
        elif os.path.basename(root) == 'melanoma':
            label = 0
        labels.append(label)
        img_class = model.predict_classes(img)
        img_class_probability = model.predict(img)
        prediction_probability = img_class_probability[0]
        prediction_probabilities.append(prediction_probability)
        prediction = img_class[0]
        if prediction == label:
            correct_classification = correct_classification + 1

【问题讨论】:

    标签: python tensorflow keras roc auc


    【解决方案1】:

    你的网络的输出是不断预测“1”的原因。您需要在最后一层有两个输出单元。类似的问题被问到here,为方便起见,我在下面引用了 Matias 的解释。

    Softmax 通过每个输出的指数之和进行归一化。由于只有一个输出,因此唯一可能的输出是 1.0。

    对于二元分类器,您可以使用带有“binary_crossentropy”损失的 sigmoid 激活,或者将两个输出单元放在最后一层,继续使用 softmax 并将损失更改为 categorical_crossentropy。

    【讨论】:

    • 代码在输出层已经有sigmoid而不是softmax,model.add(layers.Dense(1,activation='sigmoid')),可能你忽略了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 2018-06-22
    • 1970-01-01
    • 2021-11-08
    • 2011-03-07
    • 2014-10-18
    相关资源
    最近更新 更多