MobileNet V1模型报错:Shapes (None,None)与(None,8,2,19)不兼容
问题分析与解决
报错原因
你的报错ValueError: Shapes (None, None) and (None, 8, 2, 19) are incompatible来自两个核心问题:
- 池化层维度格式不匹配:你在
AvgPool2D中使用了data_format='channels_first',但模型输入是(256,256,3)(默认channels_last格式,即高度、宽度、通道),这会导致池化层处理维度时顺序混乱,输出形状异常。 - 全连接层输入未扁平化:经过前面的网络层后,特征图是
(8,8,1024)的空间形状,直接接Dense层会让全连接层仅作用于最后一维(通道维度),输出形状变成(None,8,2,19),和标签的(None,19)无法匹配。
修复后的代码
# MobileNet block def mobilnet_block(x, filters, strides): x = DepthwiseConv2D(kernel_size=3, strides=strides, padding='same')(x) x = BatchNormalization()(x) x = ReLU()(x) x = Conv2D(filters=filters, kernel_size=1, strides=1)(x) x = BatchNormalization()(x) x = ReLU()(x) return x # stem of the model input = Input(shape=(256,256,3)) x = Conv2D(filters=32, kernel_size=3, strides=2, padding='same')(input) x = BatchNormalization()(x) x = ReLU()(x) # main part of the model x = mobilnet_block(x, filters=64, strides=1) x = mobilnet_block(x, filters=128, strides=2) x = mobilnet_block(x, filters=128, strides=1) x = mobilnet_block(x, filters=256, strides=2) x = mobilnet_block(x, filters=256, strides=1) x = mobilnet_block(x, filters=512, strides=2) for _ in range(5): x = mobilnet_block(x, filters=512, strides=1) x = mobilnet_block(x, filters=1024, strides=2) x = mobilnet_block(x, filters=1024, strides=1) # 替换为全局平均池化,自动将空间维度压缩为单值,输出形状为(None, 1024) x = GlobalAveragePooling2D()(x) output = Dense(units=19, activation='softmax')(x) model = Model(inputs=input, outputs=output) model.summary()
关键修改点
- 移除
AvgPool2D,改用GlobalAveragePooling2D:它会对每个通道的所有空间元素取平均值,将(8,8,1024)的特征图转化为(1024)的向量,完美适配全连接层的输入要求。 - 去掉
data_format='channels_first',保持和输入一致的channels_last格式,避免维度顺序错误。
如果你坚持要用AvgPool2D,也可以做如下修改:
# 先将特征图扁平化,再接全连接层 x = AvgPool2D(pool_size=7, strides=1, padding='same')(x) # 去掉channels_first x = Flatten()(x) output = Dense(units=19, activation='softmax')(x)
不过这种方式不如全局平均池化简洁,也容易因输入尺寸变化导致形状问题,更推荐前者。
内容的提问来源于stack exchange,提问作者Rubi Choudhary
相关产品推荐
相关产品推荐

