EfficientNetV2B0模型fit训练时张量形状不兼容报错求解
问题根因
核心错误为分类头搭建时缺失全局池化层:直接将EfficientNetV2B0骨干网络输出的4维特征图接入全连接层,导致模型最终输出形状不符合分类任务要求,无法和标签形状匹配,触发两类报错。
- 骨干网络输出的特征为4维张量,形状为
(batch_size, 特征图高度, 特征图宽度, 通道数),直接接Dense层时,Dense仅作用在最后一个通道维度,最终模型输出为4维结构(batch_size, 特征图高度, 特征图宽度, 类别数),不是分类任务要求的2维输出(batch_size, 类别数)。 - 场景1使用CategoricalCrossentropy时,传入的one-hot标签形状为2维
(batch_size, 类别数),和4维模型输出形状完全不兼容,触发Shapes (None, None) and (None, None, None, 3) are incompatible报错。 - 场景2使用SparseCategoricalCrossentropy时,传入的整数标签形状为1维
(batch_size,),模型输出的空间维度被自动展平后,第一维长度变为batch_size * 特征图高度 * 特征图宽度,和你报错中logits形状[1568,3]、标签形状[32]的维度差完全吻合(32 batch、77特征图的情况下,327*7=1568)。
修复方案
修改分类头代码,在骨干网络输出后、接入全连接层之前新增全局池化层,将4维特征图压缩为2维特征向量即可:
x = base_model.layers[-6].output # 新增全局平均池化层,输出形状转为(batch_size, 通道数) x = tf.keras.layers.GlobalAveragePooling2D()(x) x = Dense(1024,activation='relu')(x) # 全连接层1 x = Dense(512,activation='relu')(x) # 全连接层2 output = Dense(CLASSES, activation='softmax')(x) # 分类输出层 model = Model(inputs=base_model.input, outputs=output)
配套参数匹配要求
模型结构修复后,保持数据生成器的class_mode参数和损失函数一一对应即可正常训练,两种搭配均可:
- 若
train_generator设置class_mode='categorical'(标签为one-hot编码格式),损失函数使用tf.keras.losses.CategoricalCrossentropy() - 若
train_generator设置class_mode='sparse'(标签为整数类别索引格式),损失函数使用tf.keras.losses.SparseCategoricalCrossentropy()
内容的提问来源于stack exchange,提问作者Bet
相关产品推荐
相关产品推荐

