为什么我继续将类“ 1”作为预测类?

时间:2019-01-07 04:11:54

标签: python tensorflow keras roc auc

我在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

1 个答案:

答案 0 :(得分:0)

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

  

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

     

对于二进制分类器,您可以使用Sigmoid激活并损失“ binary_crossentropy”,也可以在最后一层放置两个输出单元,继续使用softmax并将损耗更改为categorical_crossentropy。