3D ResNet残差块后特征图数量未按预期翻倍问题咨询
问题原因分析
- 显示截断导致你误以为通道数没有按预期变化:你贴出的3D模型summary输出列宽不足,将最后一维通道数的数字截断了:
你设置的第一个残差块输出通道为16,summary里显示的(None, 32, 32, 32, 1实际完整值是(None, 32, 32, 32, 16),末尾的6被列宽截断;第二个残差块设置的输出通道为32,显示的(None, 32, 32, 32, 3实际完整值是(None, 32, 32, 32, 32),末尾的2被截断。
可以通过参数量验证:第一个shortcut路径的1x1x1卷积参数量为32,对应输入通道1、输出通道16的计算结果1*1*1*1*16 + 16 = 32,完全匹配,说明通道数实际已经按配置生成,没有异常。你也可以直接打印层的输出形状print(layer.shape),不会存在截断问题。 - 你提到的「残差块运算后图像尺寸减半」的特性,你的2D、3D代码都没有实现,遗漏了下采样步长配置:标准ResNet需要降尺寸的残差块会将第一个卷积层、shortcut路径的1x1卷积步长设为2(2D)/ (2,2,2)(3D),你当前所有卷积都是默认步长1,所以特征图尺寸会一直保持输入大小不变。
补全下采样能力的3D残差块参考代码
from tensorflow.keras.layers import Input, Conv3D, add, Activation from tensorflow.keras.models import Model def residual_module(layer_in, n_filters, downsample=False): merge_input = layer_in # 下采样时步长设为2,否则为1 strides = (2,2,2) if downsample else (1,1,1) # 通道数变化或需要下采样时,调整shortcut路径 if layer_in.shape[-1] != n_filters or downsample: merge_input = Conv3D(n_filters, (1,1,1), strides=strides, padding='same', activation='relu', kernel_initializer='he_normal')(layer_in) # 第一个卷积层同步步长实现下采样 conv1 = Conv3D(n_filters, (3,3,3), strides=strides, padding='same', activation='relu', kernel_initializer='he_normal')(layer_in) conv2 = Conv3D(n_filters, (3,3,3), padding='same', activation='linear', kernel_initializer='he_normal')(conv1) # 残差相加 layer_out = add([conv2, merge_input]) layer_out = Activation('relu')(layer_out) return layer_out # 适配你的业务输入:32x32x44单通道 visible = Input(shape=(32,32,44,1)) # 第一个残差块:通道升至16,尺寸不变 layer = residual_module(visible,16) # 第二个残差块:通道升至32,尺寸减半 layer_1 = residual_module(layer,32, downsample=True) model = Model(inputs=visible, outputs=layer_1) # 调整summary列宽避免截断 model.summary(line_length=120)
内容的提问来源于stack exchange,提问作者Iram shahzadi
相关产品推荐
相关产品推荐

