python - 使用 flow_from_directory 进行多类和可变大小的图像分类
问题描述
我有一个大小可变的 7 类图像。
调整大小已完成flow_from_directory
,但此处弹出错误消息Error when checking target: expected activation_21 to have shape (1,) but got array with shape (7,)
。
文件夹:
data/
train/
dogs/
dog001.jpg
dog002.jpg
...
cats/
cat001.jpg
cat002.jpg
...
sheep/
sheep001.jpg
sheep002.jpg
...
validation/
dogs/
dog001.jpg
dog002.jpg
...
cats/
cat001.jpg
cat002.jpg
...
sheep/
sheep001.jpg
sheep002.jpg
...
我的模型是一个简单的 CNN:
train_datagen = ImageDataGenerator(
rescale=1./255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1./255)
train_generator = train_datagen.flow_from_directory(
training_path, # this is the target directory
target_size=(200, 350), # all images will be resized to 200x350
batch_size=batch_size, class_mode='categorical'
)
validation_generator = test_datagen.flow_from_directory(
validation_path,
target_size=(200, 350),
batch_size=batch_size,class_mode='categorical'
)
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(200, 350, 3),data_format='channels_last'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3)))
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(GlobalMaxPooling2D()) # this converts our 3D feature maps to 1D feature vectors
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(7))
model.add(Activation('softmax'))
model.compile(loss='sparse_categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.fit_generator(
train_generator,
steps_per_epoch=500 // batch_size,
epochs=10,
validation_data=validation_generator,
validation_steps=500 // batch_size)
模型总结是:
________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_13 (Conv2D) (None, 198, 348, 32) 896
_________________________________________________________________
activation_17 (Activation) (None, 198, 348, 32) 0
_________________________________________________________________
max_pooling2d_13 (MaxPooling (None, 99, 174, 32) 0
_________________________________________________________________
conv2d_14 (Conv2D) (None, 97, 172, 32) 9248
_________________________________________________________________
activation_18 (Activation) (None, 97, 172, 32) 0
_________________________________________________________________
max_pooling2d_14 (MaxPooling (None, 48, 86, 32) 0
_________________________________________________________________
conv2d_15 (Conv2D) (None, 46, 84, 64) 18496
_________________________________________________________________
activation_19 (Activation) (None, 46, 84, 64) 0
_________________________________________________________________
max_pooling2d_15 (MaxPooling (None, 23, 42, 64) 0
_________________________________________________________________
global_max_pooling2d_3 (Glob (None, 64) 0
_________________________________________________________________
dense_5 (Dense) (None, 64) 4160
_________________________________________________________________
activation_20 (Activation) (None, 64) 0
_________________________________________________________________
dropout_3 (Dropout) (None, 64) 0
_________________________________________________________________
dense_6 (Dense) (None, 7) 455
_________________________________________________________________
activation_21 (Activation) (None, 7) 0
=================================================================
Total params: 33,255
Trainable params: 33,255
Non-trainable params: 0
_________________________________________________________________
我也尝试过生成单独的 x_input 和 y_input np.array,但我不知道如何调整图像输入的大小,因为它们的大小不同。因此我无法获得 4 维输入向量,这种方法给了我这样的错误:
Error when checking input: expected conv2d_16_input to have 4 dimensions, but got array with shape (5721, 1)
解决方案
您的代码需要保持一致,在您的flow_from_generator
调用中将类模式设置为categorical
,这会产生单热编码的类标签,但您使用sparse_categorical_crossentropy
损失,它需要整数标签(不是单热编码的标签)。
您可以将类模式设置为sparse
以获得正确的标签,或将损失更改为categorical_crossentropy
.
推荐阅读
- python - Python - 根据变量触发特定函数
- relational-database - 这张表是 1NF 还是 2NF?
- babylonjs - 在网格点击时,ArcRotateCamera 专注于
- wpf - 在 ControlTemplate.Triggers 中查找 AncestorType 的问题
- java - 显示错误的输出,我无法弄清楚我的错误
- python - scipy.stats.chi2 返回 Nan 概率
- r - 如何计算每小时的入住率?
- javascript - 如何在 Markdown 文件中嵌入视频、图片库、表单?
- kotlin - 具有通用输入的高阶函数的重载分辨率模糊性
- python - 如何将身份验证功能放入烧瓶中的@app.before_request