You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

搭建自定义ResNet模型时出现Input has undefined rank错误如何解决?

错误原因

  • 核心错误出在ConvBlock的捷径分支实现:你定义了Conv2D层后没有把输入张量X_shortcut传入层实例做前向计算,直接将Conv2D层对象传给了后续的BatchNormalization层。BN层拿到的不是具备shape属性的张量,无法推断输入维度,因此抛出undefined rank错误。
  • 次要错误1:你自定义的模型函数命名为ResNet,但调用时使用了ResNet50,函数名不匹配无法调用。
  • 次要错误2:构建Model实例时参数应为inputs和outputs,你写的input和output在高版本Keras/TensorFlow中会触发参数错误。
  • 潜在错误:恒等块要求主路径输出和捷径分支的shape、通道数完全一致,你主路径第一个Conv2D使用了padding='valid'会导致特征图尺寸缩小,和捷径分支的原始输入尺寸不匹配,调用Add层时会触发维度不兼容错误。

修复方案

1. 修正ConvBlock的捷径分支代码

给Conv2D层传入输入张量X_shortcut,同时根据主路径的降采样情况配置卷积步长,保证输出维度和主路径匹配。

2. 修正恒等块的padding配置、函数名、Model参数等问题

修正后的完整代码如下:

修正后的恒等块(Identity Block)

def IdentityBlock(X, f, filters):
    F1, F2, F3 = filters
    X_shortcut = X
    
    # padding改为same,避免特征图尺寸缩小和shortcut不匹配
    X = Conv2D(filters = F1, kernel_size = (3, 3), padding = 'same')(X)
    X = BatchNormalization()(X)
    X = Activation('relu')(X)
    
    X = Conv2D(filters = F2, kernel_size = (f, f), padding = 'same')(X)
    X = BatchNormalization()(X)
    X = Activation('relu')(X)
    
    X = Conv2D(filters = F3, kernel_size = (3, 3), padding = 'same')(X)
    X = BatchNormalization()(X)
    
    X = Add()([X, X_shortcut])
    X = Activation('relu')(X)
    
    return X

修正后的卷积块(Conv Block)

def ConvBlock(X, f, filters, s=2):
    F1, F2, F3 = filters
    X_shortcut = X
    
    X = Conv2D(filters = F1, kernel_size = (3, 3), strides=(s,s), padding = 'same')(X)
    X = BatchNormalization()(X)
    X = Activation('relu')(X)
    
    X = Conv2D(filters = F2, kernel_size = (f, f), padding = 'same')(X)
    X = BatchNormalization()(X)
    X = Activation('relu')(X)
    
    X = Conv2D(filters = F3, kernel_size = (3, 3), padding = 'same')(X)
    X = BatchNormalization()(X)
    
    # 修正:给shortcut的Conv2D传入输入张量,同时配置步长和主路径对齐
    X_shortcut = Conv2D(filters = F3, kernel_size = (3, 3), strides=(s,s), padding = 'same')(X_shortcut)
    X_shortcut = BatchNormalization()(X_shortcut)
    
    X = Add()([X, X_shortcut])
    X = Activation('relu')(X)
    
    return X

修正后的ResNet模型定义

def ResNet50(input_shape = (224, 224, 3)):
    X_input = Input(input_shape)
    
    X = Conv2D(64, (7, 7), strides=(2,2), padding='same')(X_input)
    X = BatchNormalization()(X)
    X = Activation('relu')(X)
    X = MaxPooling2D((3, 3), strides=(2,2), padding='same')(X)
    
    X = ConvBlock(X, f = 3, filters = [64, 64, 256], s=1)
    X = IdentityBlock(X, 3, filters = [64, 64, 256])
    X = IdentityBlock(X, 3, filters = [64, 64, 256])
    
    X = ConvBlock(X, f = 3, filters = [128, 128, 512])
    X = IdentityBlock(X, 3, filters = [128, 128, 512])
    X = IdentityBlock(X, 3, filters = [128, 128, 512])
    X = IdentityBlock(X, 3, filters = [128, 128, 512])
    
    X = GlobalAveragePooling2D()(X) # 替换原MaxPooling2D,符合ResNet标准实现
    model = Model(inputs = X_input, outputs = X)
    
    return model

调用代码保持不变即可正常运行:

base_model = ResNet50(input_shape=(224, 224, 3))

内容的提问来源于stack exchange,提问作者Sticky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 19:24:03