根据流程图搭建卷积神经网络(CNN)的代码纠错求助
你的代码存在多处语法、API使用和结构逻辑错误,无法直接运行,具体问题和修正方案如下:
参考网络结构图:
存在的错误
- 模型API混用:你同时使用Sequential顺序模型和函数式API写法,还试图对
Concatenate输出的张量对象调用.add()方法——.add()是Sequential模型类的专属方法,普通Keras张量没有该方法。这类带多分支拼接的结构必须使用函数式API搭建。 - 导入项缺失/混乱:代码用到了
LeakyReLU、MaxPooling2D、Dropout层但未导入;同时混用tensorflow.keras和独立keras的导入路径,极易触发版本兼容、维度不匹配类报错,所有层需统一从tensorflow.keras导入。 - 参数名拼写错误:所有Conv2D层的步长参数为复数形式
strides,你全部误写为stride,会触发未知参数报错。 - 特征拼接维度错误:TensorFlow默认张量维度顺序为
(批次, 高度, 宽度, 通道数),多分支特征的通道拼接需指定axis=-1(最后一个维度),你写的axis=1是在高度维度做拼接,会直接触发维度不匹配错误。 - 基础语法错误:三个堆叠块开头的Conv2D层调用都缺失右括号,代码无法通过语法检查。
- 结构逻辑错误:
- 第一层Conv2D已经设置了
activation='relu',后续又接BatchNormalization和LeakyReLU,存在重复激活,和设计结构不符 - 多分支卷积层未设置
padding='same',不同尺寸卷积核输出的特征图宽高不一致,无法直接拼接 - 错误给Dropout层设置
activation='softmax':Dropout是正则化层,不承担激活变换功能,softmax需配置在最后一层分类全连接层上 - 缺失最终分类输出层,Dense(200)接Dropout后没有对应多分类类别数的输出节点
- 变量名拼写错误:最后定义的
model_dfu_spnet后续误写为mode_dfu_spnet,会触发变量不存在报错
- 第一层Conv2D已经设置了
修正后的可运行代码
import tensorflow as tf from tensorflow.keras.layers import ( Input, Conv2D, Concatenate, Dense, Flatten, BatchNormalization, LeakyReLU, MaxPooling2D, Dropout ) from tensorflow.keras.models import Model # 输入层,单通道灰度图输入尺寸128*128 inputs = Input(shape=(128, 128, 1)) # 第一个堆叠卷积块 x = Conv2D(filters=64, kernel_size=7, strides=(2,2), padding='same')(inputs) x = BatchNormalization()(x) x = LeakyReLU(alpha=0.1)(x) # 多分支卷积,统一same padding保证输出特征图尺寸一致 branch1 = Conv2D(filters=32, kernel_size=3, strides=(1,1), padding='same', activation='relu')(x) branch2 = Conv2D(filters=64, kernel_size=5, strides=(1,1), padding='same', activation='relu')(x) branch3 = Conv2D(filters=128, kernel_size=5, strides=(1,1), padding='same', activation='relu')(x) concat1 = Concatenate(axis=-1)([branch1, branch2, branch3]) # 第二个堆叠卷积块 x = Conv2D(filters=64, kernel_size=1, strides=(1,1), padding='same', activation='relu')(concat1) x = BatchNormalization()(x) x = LeakyReLU(alpha=0.1)(x) x = MaxPooling2D((2,2), strides=(2,2), padding='same')(x) branch1 = Conv2D(filters=32, kernel_size=1, strides=(1,1), padding='same', activation='relu')(x) branch2 = Conv2D(filters=64, kernel_size=3, strides=(1,1), padding='same', activation='relu')(x) branch3 = Conv2D(filters=128, kernel_size=5, strides=(1,1), padding='same', activation='relu')(x) concat2 = Concatenate(axis=-1)([branch1, branch2, branch3]) # 第三个堆叠卷积块 x = Conv2D(filters=64, kernel_size=1, strides=(1,1), padding='same', activation='relu')(concat2) x = BatchNormalization()(x) x = LeakyReLU(alpha=0.1)(x) x = MaxPooling2D((2,2), strides=(2,2), padding='same')(x) branch1 = Conv2D(filters=32, kernel_size=1, strides=(1,1), padding='same', activation='relu')(x) branch2 = Conv2D(filters=64, kernel_size=3, strides=(1,1), padding='same', activation='relu')(x) branch3 = Conv2D(filters=128, kernel_size=5, strides=(1,1), padding='same', activation='relu')(x) concat3 = Concatenate(axis=-1)([branch1, branch2, branch3]) # 分类头 x = Conv2D(filters=64, kernel_size=1, strides=(1,1), padding='same', activation='relu')(concat3) x = BatchNormalization()(x) x = LeakyReLU(alpha=0.1)(x) x = MaxPooling2D((2,2), strides=(2,2), padding='same')(x) x = Flatten()(x) x = Dense(200, activation='relu')(x) x = Dropout(0.3)(x) # 请将下方数字替换为你实际的多分类类别总数 outputs = Dense(10, activation='softmax')(x) # 组装模型 model_dfu_spnet = Model(inputs=inputs, outputs=outputs) # 打印模型结构核对参数 model_dfu_spnet.summary()
使用提示
- 若你使用3通道RGB伤口图像训练,需将输入层shape修改为
(128, 128, 3) - 最后一层Dense的神经元数量必须和你的分类类别数保持一致
- 训练时若标签为整数编码,损失函数选择
sparse_categorical_crossentropy;若标签为独热编码,损失函数选择categorical_crossentropy
内容的提问来源于stack exchange,提问作者Azhan Ahmed
相关产品推荐
相关产品推荐


