Keras深度学习:预测输出与输入栅格形状不符问题求助
问题:Keras模型推理输出形状不符合预期
我使用Keras训练深度学习模型,训练数据为125x125像素的3D RGB数组。推理阶段给输入添加批量维度后(输入形状变为(1,128,128,3))脚本可运行,但输出形状完全错误,当前输出为TensorShape([1,4096,2]),该形状与模型最后两层输出一致。附上相关信息,寻求解决方法:
模型结构信息
model.summary() Model: "model_13" __________________________________________________________________________________________________ Layer (type) Output Shape Param # Connected to ================================================================================================== input_4 (InputLayer) [(None, 128, 128, 3 0 [] )] block1_conv1 (Conv2D) (None, 128, 128, 64 1792 ['input_4[0][0]'] ) block1_conv2 (Conv2D) (None, 128, 128, 64 36928 ['block1_conv1[0][0]'] ) block1_pool (MaxPooling2D) (None, 64, 64, 64) 0 ['block1_conv2[0][0]'] block2_conv1 (Conv2D) (None, 64, 64, 128) 73856 ['block1_pool[0][0]'] block2_conv2 (Conv2D) (None, 64, 64, 128) 147584 ['block2_conv1[0][0]'] block2_pool (MaxPooling2D) (None, 32, 32, 128) 0 ['block2_conv2[0][0]'] block3_conv1 (Conv2D) (None, 32, 32, 256) 295168 ['block2_pool[0][0]'] block3_conv2 (Conv2D) (None, 32, 32, 256) 590080 ['block3_conv1[0][0]'] block3_conv3 (Conv2D) (None, 32, 32, 256) 590080 ['block3_conv2[0][0]'] block3_pool (MaxPooling2D) (None, 16, 16, 256) 0 ['block3_conv3[0][0]'] block4_conv1 (Conv2D) (None, 16, 16, 512) 1180160 ['block3_pool[0][0]'] block4_conv2 (Conv2D) (None, 16, 16, 512) 2359808 ['block4_conv1[0][0]'] block4_conv3 (Conv2D) (None, 16, 16, 512) 2359808 ['block4_conv2[0][0]'] block4_pool (MaxPooling2D) (None, 8, 8, 512) 0 ['block4_conv3[0][0]'] zero_padding2d_4 (ZeroPadding2 (None, 10, 10, 512) 0 ['block4_pool[0][0]'] D) conv2d_27 (Conv2D) (None, 8, 8, 512) 2359808 ['zero_padding2d_4[0][0]'] batch_normalization_4 (BatchNo (None, 8, 8, 512) 2048 ['conv2d_27[0][0]'] rmalization) up_sampling2d_7 (UpSampling2D) (None, 16, 16, 512) 0 ['batch_normalization_4[0][0]'] concatenate_7 (Concatenate) (None, 16, 16, 768) 0 ['up_sampling2d_7[0][0]', 'block3_pool[0][0]'] zero_padding2d_5 (ZeroPadding2 (None, 18, 18, 768) 0 ['concatenate_7[0][0]'] D) conv2d_28 (Conv2D) (None, 16, 16, 256) 1769728 ['zero_padding2d_5[0][0]'] batch_normalization_5 (BatchNo (None, 16, 16, 256) 1024 ['conv2d_28[0][0]'] rmalization) up_sampling2d_8 (UpSampling2D) (None, 32, 32, 256) 0 ['batch_normalization_5[0][0]'] concatenate_8 (Concatenate) (None, 32, 32, 384) 0 ['up_sampling2d_8[0][0]', 'block2_pool[0][0]'] zero_padding2d_6 (ZeroPadding2 (None, 34, 34, 384) 0 ['concatenate_8[0][0]'] D) conv2d_29 (Conv2D) (None, 32, 32, 128) 442496 ['zero_padding2d_6[0][0]'] batch_normalization_6 (BatchNo (None, 32, 32, 128) 512 ['conv2d_29[0][0]'] rmalization) up_sampling2d_9 (UpSampling2D) (None, 64, 64, 128) 0 ['batch_normalization_6[0][0]'] concatenate_9 (Concatenate) (None, 64, 64, 192) 0 ['up_sampling2d_9[0][0]', 'block1_pool[0][0]'] zero_padding2d_7 (ZeroPadding2 (None, 66, 66, 192) 0 ['concatenate_9[0][0]'] D) conv2d_30 (Conv2D) (None, 64, 64, 64) 110656 ['zero_padding2d_7[0][0]'] batch_normalization_7 (BatchNo (None, 64, 64, 64) 256 ['conv2d_30[0][0]'] rmalization) conv2d_31 (Conv2D) (None, 64, 64, 2) 1154 ['batch_normalization_7[0][0]'] reshape_3 (Reshape) (None, 4096, 2) 0 ['conv2d_31[0][0]'] activation_3 (Activation) (None, 4096, 2) 0 ['reshape_3[0][0]'] ================================================================================================== Total params: 12,322,946 Trainable params: 12,321,026 Non-trainable params: 1,920 __________________________________________________________________________________________________ model.inputs Out[52]: [<KerasTensor: shape=(None, 128, 128, 3) dtype=float32 (created by layer 'input_4')>]
输入输出形状信息
val_data.shape Out[53]: (1, 128, 128, 3) out.shape Out[54]: TensorShape([1, 4096, 2])
解决方法
问题根源
从模型结构可以看到:
- 模型最后一个卷积层
conv2d_31输出形状是(None,64,64,2),之后的reshape_3层把64x64的空间维度展平成了4096(64*64),得到(None,4096,2),这就是当前输出形状的来源。 - 你的任务应该是需要输出和输入同尺寸的特征图(比如
(1,128,128,2)),但当前模型的上采样路径只恢复到了64x64,还额外做了不必要的Reshape操作。
修复步骤
- 移除Reshape和后置激活层:如果是语义分割类任务,不需要展平空间维度,直接删除
reshape_3和activation_3层,把激活函数移到conv2d_31层(比如定义时用Conv2D(2, ..., activation='sigmoid'))。 - 补充上采样到输入尺寸:当前模型最后一次上采样后是64x64,离输入的128x128还差一次2倍上采样。在
batch_normalization_7之后添加UpSampling2D(size=(2,2))层,然后再接输出卷积层,确保输出空间尺寸和输入一致。示例代码:# 修改模型末尾部分 x = layers.UpSampling2D(size=(2,2))(batch_normalization_7.output) x = layers.Conv2D(2, (3,3), padding='same', activation='softmax')(x) # 根据任务选激活函数 model = Model(inputs=input_4, outputs=x) - 对齐训练与推理数据尺寸:训练数据是125x125,但模型输入是128x128,训练时肯定做了resize操作,推理时也要保证输入先resize到128x128,避免尺寸不匹配问题。
- 验证模型结构:修改后重新打印
model.summary(),确认输出形状为(None,128,128,2),再用测试输入验证输出形状是否符合预期。
内容的提问来源于stack exchange,提问作者Phanster
相关产品推荐
相关产品推荐

