TensorFlow/Keras模型在尝试预测时出错,理由是形状不匹配,尽管我提供的形状似乎是正确的



我不确定我是否不很好地理解输入张量的想法,或者我是否用错误的输入形状训练了模型,或者是否需要以某种方式指定图像。

模型构建如下:

... import all the usual libraries - TF, Keras, Numpy, OpenCV etc. ...
_MODEL_DIMENSION = 128
def create_model_for_dimension(dimension):
model = Sequential()
if dimension >= 256:
model.add(Conv2D(256, kernel_size=(5, 5), input_shape=(dimension, dimension, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
if dimension >= 128:
model.add(Conv2D(128, kernel_size=(3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
…… more convolution layers ……..
…………………………………………..
……………………………………………..
model.add(Flatten())
……… More layers …………………
……………………………………………..
……………………………………………..
model.add(Dense(2))
model.add(Activation('sigmoid'))
model.compile(loss='categorical_crossentropy',
optimizer=tf.keras.optimizers.Adam(),
metrics=['accuracy'])
return model
train_datagen = ImageDataGenerator(
rotation_range=10,
width_shift_range=0.2,
height_shift_range=0.2,
rescale=1./255,
shear_range=0.2,
zoom_range=1.2,
horizontal_flip=True,
vertical_flip=True,
fill_mode='nearest')
train_generator = train_datagen.flow_from_directory(
train_data_directory, 
target_size=(_MODEL_DIMENSION, _MODEL_DIMENSION),
batch_size=_BATCH_SIZE,
class_mode='categorical')
……… validate_generator …………………
……………………………………………………
………………………………………………………
……… test_generator ………………………
………………………………………………………
………………………………………………………
……… train and save the model ……

当我训练并使用它来预测目录中的图像时,一切都起作用了(至少看起来是这样(。但我随后尝试在不使用ImageDataGenerator的情况下以以下方式输入图像:

首先,我使用OpenCV读取图像(我希望使用OpenCV进行其他处理,所以不使用PIL(

ml_model = … read the model back from the saved model ……
snapshot = cv.imread(file_name)
snapshot = cv.cvtColor(snapshot, cv.COLOR_BGR2RGB)

然后我使用范围裁剪图像

cropped_area = snapshot[y[0]:y[1], x[0]:x[1]]

然后我用下面的模型打分。我还尝试了np.array转换以外的变体。

score_val = model.predict(np.array(cropped_area/255.0))

这是当它错误如下时:

ValueError: Input 0 of layer sequential is incompatible with the layer: expected ndim=4, found ndim=3. Full shape received: [32, 128, 3]

我的图像的形状是(1281283(,我所做的所有检查似乎都证实了我一直在喂它

任何建议都将不胜感激,因为我花了一天的大部分时间试图解决这个问题!谢谢

您设置了_MODEL_DIMENSION = 128

这导致

if dimension >= 128:
model.add(Conv2D(128, kernel_size=(3, 3)))

您没有设置输入形状,因此根据文档,预期的输入将是:

输入形状

具有形状的4D张量:(批、通道、行、列(如果data_format是";channels_ first";或具有形状的4D张量:(批、行、列、通道(,如果data_format是";channels_last";。

您的输入不合适,因此出现错误

预期ndim=4,发现ndim=3

解决方案是定义一个输入形状,它已经存在于您的代码中:

if dimension >= 256:
model.add(Conv2D(256, kernel_size=(5, 5), input_shape=(dimension, dimension, 3)))

您的数据缺少批次维度。您的模型需要4D数据,而不是3D数据。

您的图像形状应该是(1, 128,128, 3)

相关内容

最新更新