Keras模型不断提供相同的输出类别?

时间:2018-08-06 11:38:37

标签: python neural-network keras

我一直在尝试按照“猫与狗”教程建立一个keras模型,但是不幸的是,我总是得到相同的输出类“猫”。我知道有一些帖子,人们在同样的挣扎中。我已经尝试了所有方法,但仍然无法弄清自己在做什么错。我的一个朋友告诉我,由于我的准确率会根据每个类的图像数量而变化,因此我没有正确标记类,但是我在教程中读到,如果我有子目录使用“ flow_from_directory”方法,它已经根据我的文件夹的名称为我的班级添加了标签,如果有人可以告诉我我在做什么错,那将非常有帮助。这是我的原型的一小段代码示例:

# MODEL CONSTRUCTION -----------------------------------------
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(128,128,3))) #(3, 150, 150)
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())  # this converts all our 3D feature maps to 1D feature vectors
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid')) #sigmoid for binary outcome, softmax for more than two outcomes

model.compile(loss='binary_crossentropy', #since its a binary classification
              optimizer='rmsprop',
              metrics=['accuracy'])


#-------------------------------------------------------------

#augmentation configuration for training
train_datagen = ImageDataGenerator(
        rotation_range=40,
        width_shift_range=0.2,
        height_shift_range=0.2,
        #rescale=1. / 255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        fill_mode='nearest')

#augmentation configuration for validating
valid_datagen = ImageDataGenerator(
        rotation_range=60,
        width_shift_range=0.4,
        height_shift_range=0.1,
        zoom_range=0.1,
        vertical_flip=True,)

#augmentation configuration for testing
test_datagen = ImageDataGenerator(
    rescale=1. / 255)

train_generator = train_datagen.flow_from_directory(
        directory='data/train',  # this is the target directory
        target_size=(img_width, img_height), # all images will be resized to the given dimensions
        color_mode="rgb",
        #classes = ['dog', 'cat'], 
        batch_size=batch_size,
        class_mode='binary')  # since we use binary_crossentropy loss, we need binary labels

# this is a similar generator, for validation data
validation_generator = valid_datagen.flow_from_directory(
        directory='data/validation',
        target_size=(img_width, img_height),
        color_mode="rgb",
        #classes = ['dog', 'cat'], 
        batch_size=batch_size,
        class_mode='binary',
        seed=42)

test_generator = test_datagen.flow_from_directory(
    directory='data/test',
    target_size=(img_width, img_height),
    color_mode="rgb",
    batch_size=1,
    class_mode=None,
    #shuffle=False,
)

model.fit_generator(
        train_generator,
        steps_per_epoch=nb_train_samples / batch_size,
        epochs=epochs,
        validation_data=validation_generator,
        validation_steps=nb_validation_samples / batch_size)

model.evaluate_generator(
    generator=validation_generator
)

test_generator.reset()
pred=model.predict_generator(test_generator,verbose=1)
predicted_class_indices=np.argmax(pred,axis=1)

labels = (train_generator.class_indices)
labels = dict((v,k) for k,v in labels.items())
predictions = [labels[k] for k in predicted_class_indices]

这是当我用一些随机图像进行测试时的结果图像:model_output

2 个答案:

答案 0 :(得分:2)

模型中的输出层具有1个节点,该节点已通过sigmoid激活功能激活。

模型产生的输出将是一维的。由于激活为sigmoid,因此每个值都小于1。

您正在做出这样的预测。

pred=model.predict_generator(test_generator,verbose=1)
predicted_class_indices=np.argmax(pred,axis=1)

您正在使用模型进行预测,然后在此上使用argmax。由于您与每个图像对应的输出将是单个值,例如0.99或0.001。

对它取argmax将始终输出0。因此,您始终获得的输出为0。这对应于cat。

如果您希望模型正确进行预测,则必须将模型做出的预测,然后根据需要将阈值映射到类,如果您将阈值保持为0.5

pred=model.predict_generator(test_generator,verbose=1)
predicted_class_indices=[1 if x >= 0.5 else 0 for x in preds]

答案 1 :(得分:0)

为什么您不使用教程中的确切代码和确切的培训数据,这是解决此类问题的推荐方法,当您弄乱事情并且不知道要解决什么问题时。