Unet模型解码层Concatenate拼接张量尺寸不匹配报错求解
报错原因
Unet跳层拼接操作要求除了拼接轴(通道轴)之外的所有维度尺寸完全匹配,本次报错的核心原因如下:
你使用的输入图像尺寸为2652×3519,两个维度都不是2的整数次幂的倍数,经过编码器多次2倍下采样后,得到的中间特征图尺寸为奇数,再次2倍上采样后无法和对应编码器层的特征图尺寸对齐。从报错信息可以看到,上采样后的conv5特征图尺寸为164×218,而编码器对应层conv4_1的尺寸为165×219,两个维度各差1个像素,因此拼接失败。
另外你提供的代码存在冗余问题:连续对up6_1赋值两次拼接操作,分别用Conv2DTranspose和UpSampling2D对conv5做上采样后拼接,即使尺寸匹配也会出现逻辑错误,需要先删掉其中一行不需要的上采样拼接逻辑。
解决方案
可根据业务需求选择以下任意一种方案:
- 方案1:调整输入图像尺寸(最推荐)
先统计你的Unet总共有多少次2倍下采样,记为n次,将输入图像的长宽都resize为2ⁿ的整数倍。比如你使用的是5次下采样的标准Unet,2⁵=32,可将输入尺寸调整为2656×3520(均为32的倍数),模型输出结果后再resize回原始尺寸即可,该方案不会损失特征信息,适配性最高。 - 方案2:裁剪特征图对齐尺寸
在上采样后的特征图和编码器特征图拼接前,将尺寸更大的特征图裁剪到和小尺寸特征图一致,比如本次报错可以裁剪conv4_1的多余像素:
裁剪时建议优先保留中心区域的特征,避免边缘信息丢失过多。# 裁剪conv4_1的高度和宽度各1个像素,对齐上采样后的conv5尺寸 cropped_conv4_1 = tf.keras.layers.Cropping2D(cropping=((0, 1), (0, 1)))(conv4_1) up6_1 = tf.keras.layers.concatenate([tf.keras.layers.Conv2DTranspose(n_filters, (2, 2), strides=(2, 2), padding='same',kernel_initializer = 'he_normal')(conv5), cropped_conv4_1]) - 方案3:调整上采样层参数补全尺寸
使用Conv2DTranspose做上采样时,可以显式指定output_padding参数补全缺少的1个像素,让上采样后的尺寸和conv4_1完全匹配:
该方案不需要修改输入尺寸,也不会损失特征,但需要针对每个上采样层单独计算需要补全的像素数。up6_1 = tf.keras.layers.concatenate([tf.keras.layers.Conv2DTranspose(n_filters, (2, 2), strides=(2, 2), padding='same', output_padding=(1,1), kernel_initializer = 'he_normal')(conv5), conv4_1])
内容的提问来源于stack exchange,提问作者Fatima-Ezzahra Mohtich
相关产品推荐
相关产品推荐

