Keras搭建Unet时Concatenate层形状不匹配报错如何解决
报错原因
- 报错本质是
Concatenate拼接层要求除了拼接轴之外的所有维度尺寸必须匹配,你的问题来源于输入尺寸不符合U-Net网络的设计要求:你实现的U-Net包含4次步长为2的下采样(MaxPooling2D)和4次步长为2的上采样(Conv2DTranspose),要求输入宽高必须是2^4=16的整数倍,否则下采样遇到奇数尺寸时会向下取整,导致上采样后尺寸和对应下采样层的特征图尺寸不一致。
300×300输入的尺寸变化流程验证:
- 第1次下采样:300/2=150 → 特征图尺寸150×150
- 第2次下采样:150/2=75 → 特征图尺寸75×75
- 第3次下采样:75/2向下取整为37 → c4层特征图尺寸37×37
- 第4次下采样:37/2向下取整为18 → c5层特征图尺寸18×18
- 第1次上采样:18×2=36 → u6层特征图尺寸36×36,和c4的37×37尺寸不匹配,触发拼接报错。
修复方案
方案1:调整输入尺寸(最简便,推荐)
直接将输入图像的宽高调整为16的整数倍即可,例如288×288、320×320等,修改输入定义代码:
# 288是16的18倍,完全符合下采样/上采样的尺寸要求 input_img = Input((288, 288, 1), name="img")
方案2:强制对齐特征图尺寸(适用于必须保留300×300输入的场景)
方式A:给Conv2DTranspose添加output_padding参数
上采样时补1个像素,让输出尺寸和对应下采样层对齐,修改4处上采样代码:
# 第1次上采样补1像素,输出37×37和c4对齐 u6 = Conv2DTranspose(n_filters*8, (3, 3), strides=(2, 2), padding='same', output_padding=1)(c5) u6 = concatenate([u6, c4]) # 第2次上采样补1像素,输出75×75和c3对齐 u7 = Conv2DTranspose(n_filters*4, (3, 3), strides=(2, 2), padding='same', output_padding=1)(c6) u7 = concatenate([u7, c3]) # 第3次上采样输出150×150,和c2尺寸一致不需要补 u8 = Conv2DTranspose(n_filters*2, (3, 3), strides=(2, 2), padding='same')(c7) u8 = concatenate([u8, c2]) # 第4次上采样输出300×300,和c1尺寸一致不需要补 u9 = Conv2DTranspose(n_filters*1, (3, 3), strides=(2, 2), padding='same')(c8) u9 = concatenate([u9, c1], axis=3)
方式B:裁剪较大的特征图
拼接前将尺寸更大的特征图裁剪到和小特征图一致:
# 裁剪c4的1个边缘像素,对齐u6的36×36尺寸 c4_cropped = Cropping2D(cropping=((0,1),(0,1)))(c4) u6 = concatenate([u6, c4_cropped]) # 裁剪c3的1个边缘像素,对齐u7的74×74尺寸 c3_cropped = Cropping2D(cropping=((0,1),(0,1)))(c3) u7 = concatenate([u7, c3_cropped])
内容的提问来源于stack exchange,提问作者Zaki Jefferson
相关产品推荐
相关产品推荐

