python - 使用 Keras 对 3 类进行图像分类仅返回一个值,而不是 1 X 3 数组

标签 python machine-learning keras deep-learning classification

我正在训练一个用于多标签图像分类的 Keras 模型,即洪水、野火、 Storm 3 个类别。

但我只得到 [[1.]] 而不是 [0 0 1] 之类的东西。所以如果第三位是 1,那就是一场 Storm 。但我不知道为什么它只返回一个值[[1.]]

# # Importing the Keras libraries and packages
from keras.models import Sequential
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
import numpy as np
from keras.preprocessing import image
from keras.preprocessing.image import ImageDataGenerator
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
def create_model() :
    # Initialising the CNN
    classifier = Sequential()
    # Step 1 - Convolution
    classifier.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
    # Step 2 - Pooling
    classifier.add(MaxPooling2D(pool_size = (2, 2)))
    # Adding a second convolutional layer
    classifier.add(Conv2D(32, (3, 3), activation = 'relu'))
    classifier.add(MaxPooling2D(pool_size = (2, 2)))
    # Step 3 - Flattening
    classifier.add(Flatten())
    # Step 4 - Full connection
    classifier.add(Dense(units = 128, activation = 'relu'))
    classifier.add(Dense(units = 1, activation = 'sigmoid'))
    return classifier

def train_save_model():
    classifier = create_model()
    classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
    # Part 2 - Fitting the CNN to the images
    train_datagen = ImageDataGenerator(rescale = 1./255,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True)
    test_datagen = ImageDataGenerator(rescale = 1./255)
    training_set = train_datagen.flow_from_directory('training_set',
    target_size = (64, 64),
    batch_size = 32,
    class_mode = 'binary')
    test_set = test_datagen.flow_from_directory('validation_set',
    target_size = (64, 64),
    batch_size = 32,
    class_mode = 'binary')
    classifier.fit_generator(training_set,
    steps_per_epoch = 1407,
    epochs = 1,
    validation_data = test_set,
    validation_steps = 100)

    classifier.save_weights("model.h5")

# Part 3 - Making new predictions
def test_model():
    classifier = create_model()
    classifier.load_weights("model.h5")
    test_image = image.load_img('validation_set/tornado/110.jpg', target_size = (64, 64))
    test_image = image.img_to_array(test_image)
    test_image = np.expand_dims(test_image, axis = 0)
    # print(test_image)
    result = classifier.predict(test_image)
    train_datagen = ImageDataGenerator(rescale = 1./255,
    shear_range = 0.2,
    zoom_range = 0.2,
    horizontal_flip = True,
    )
    training_set = train_datagen.flow_from_directory('training_set',
    target_size = (64, 64),
    batch_size = 32,
    class_mode = 'binary')
    training_set.class_indices
    # print(training_set.class_indices)
    print(result)

train_save_model()
test_model()

result = classifier.predict(test_image)

我尝试打印此结果变量,并得到[[1.]]。我完全不明白这是怎么发生的。

最佳答案

如果有 N 个标签,那么最后一层(即 sigmoid 分类器层)也必须有 N 个神经元,每个类一个:

classifier.add(Dense(units=3, activation='sigmoid'))

然后,对于每个输入样本,模型的输出将是对应于三个标签的 3 个数字。

更新:从所有 flow_from_directory 调用中删除 class_mode = 'binary'。这是因为您正在多个类之间进行分类,因此生成的标签应该是分类的(默认行为)或稀疏的(即 class_mode='sparse')。此外,在阅读代码的相关部分后,您似乎正在进行多类分类,而不是多标签分类。阅读 this answer以确定并找出您应该使用哪种激活和损失函数。

关于python - 使用 Keras 对 3 类进行图像分类仅返回一个值,而不是 1 X 3 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57025441/

相关文章:

python - Gitlab CI : Failed building wheel for opencv-python

python - 无法导入 Python 统计库

python - 将空参数传递给 Python 函数?

python - 在 Gunicorn/Flask 应用程序中的进程之间共享静态全局数据

tensorflow - 在测试期间重新加载 Keras Tokenizer

machine-learning - Keras 模型预测数列

python - 经过训练的神经网络使用相同的数据产生不同的预测(TensorFlow)

python - 贝叶斯优化的最大维度(GPyOpt、GPFlow)

python - 将用户输入实现到神经网络中

python - 为 Keras 制作自定义损失函数