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

Python TensorFlow/Keras模型在尝试预测时出错,引用了形状不匹配,尽管我提供的形状似乎正确,python,image,opencv,tensorflow,keras,Python,Image,Opencv,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 >= 2

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

模型构建如下:

... 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 ……
ValueError: Input 0 of layer sequential is incompatible with the layer: expected ndim=4, found ndim=3. Full shape received: [32, 128, 3]
当我训练并使用它预测目录中的图像时,一切都正常(或者至少看起来正常)。但我随后尝试以以下方式输入图像,而不使用ImageDataGenerator:

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

然后我使用范围裁剪图像

cropped_area = snapshot[y[0]:y[1], x[0]:x[1]]
然后我使用如下模型进行评分。我还尝试了np.array转换以外的变体

score_val = model.predict(np.array(cropped_area/255.0))
此时会出现如下错误:

... 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 ……
ValueError: Input 0 of layer sequential is incompatible with the layer: expected ndim=4, found ndim=3. Full shape received: [32, 128, 3]
我的图像的形状是(128,128,3),我做的所有检查似乎都证实了我一直在给它喂食


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

您设置了
\u MODEL\u DIMENSION=128

这导致了

if dimension >= 128:
        model.add(Conv2D(128, kernel_size=(3, 3)))
您没有设置输入形状,因此,根据设置,预期输入将为:

输入形状

带形状的4D张量:(批次、通道、行、列)如果数据_格式为“通道_优先”,或带形状的4D张量:(批次、行、列、列)如果数据_格式为“通道_最后”

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

预期ndim=4,发现ndim=3

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

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

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


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

这就是问题所在,谢谢。我们学到的经验是,不要通过参数化模型来减少代码行数,尤其是在不同大小的代码处理方式不同的情况下。