我正在训练一个用于多标签图像分类的 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/