复现论文神经网络的Keras多输入模型构建与训练方案咨询
分阶段训练方案的实现逻辑
这个方案是完全可实现的,属于典型的两阶段特征提取+分类头训练范式,常规实现步骤如下:
- 先独立训练三个单分支网络:每个分支完整包含对应预训练骨干、后续两层Dense层、适配单分支的分类输出层,使用同一数据集分别完成训练。训练时可根据你的数据集规模选择冻结预训练骨干底层参数仅微调顶层,或者全参微调。
- 完成单分支训练后,剥离三个分支的分类输出层,仅保留预训练骨干+两层Dense的部分,将三个分支的所有参数设置为
trainable=False,固定为特征提取器(也就是你说的滤波器)。 - 用三个固定的分支分别对全量数据集做推理,得到每个样本对应的三组特征,全部做Flatten处理后,作为最终全连接分类层的输入特征,单独训练最终的分类层即可。
这个方案的优势是训练难度低、单分支调试排查问题方便、对算力要求更低;缺陷是三个分支的特征学习没有和最终分类头联动,存在特征适配偏差,最终精度通常弱于端到端训练的方案。
Keras Functional API多输入方案说明
这个是更推荐的最优方案,端到端训练的特征适配性更好,最终精度表现通常更优。Keras Functional API完全支持你要的结构,没有原理性的使用限制,实现逻辑非常清晰,你可以定义三个独立的输入层分别接入对应预训练网络,输出特征按需选择拼接或者其他合并方式后接入后续分类层即可。
使用该API仅需要注意几个常规限制,完全不影响你的需求实现:
- 三个输入的数据预处理逻辑要和对应预训练网络训练时的预处理规则对齐,比如图像尺寸、归一化范围要匹配对应骨干的要求。
- 如果需要冻结部分预训练骨干的参数,要在编译模型前显式设置对应层的
trainable参数。 - 多输入训练时,需要按输入顺序传入对应批次数据,也可以用字典格式指定输入层和对应数据的映射。
附上极简实现示例供参考:
from tensorflow import keras from tensorflow.keras import layers # 初始化三个预训练骨干,按需替换为你要使用的模型 backbone_a = keras.applications.ResNet50(weights="imagenet", include_top=False, input_shape=(224,224,3)) backbone_b = keras.applications.EfficientNetB0(weights="imagenet", include_top=False, input_shape=(224,224,3)) backbone_c = keras.applications.VGG16(weights="imagenet", include_top=False, input_shape=(224,224,3)) # 可选:冻结预训练骨干参数 backbone_a.trainable = False backbone_b.trainable = False backbone_c.trainable = False # 构建三个独立分支 input_a = layers.Input(shape=(224,224,3), name="input_a") feat_a = backbone_a(input_a, training=False) feat_a = layers.GlobalAveragePooling2D()(feat_a) feat_a = layers.Dense(256, activation="relu")(feat_a) feat_a = layers.Dense(128, activation="relu")(feat_a) input_b = layers.Input(shape=(224,224,3), name="input_b") feat_b = backbone_b(input_b, training=False) feat_b = layers.GlobalAveragePooling2D()(feat_b) feat_b = layers.Dense(256, activation="relu")(feat_b) feat_b = layers.Dense(128, activation="relu")(feat_b) input_c = layers.Input(shape=(224,224,3), name="input_c") feat_c = backbone_c(input_c, training=False) feat_c = layers.GlobalAveragePooling2D()(feat_c) feat_c = layers.Dense(256, activation="relu")(feat_c) feat_c = layers.Dense(128, activation="relu")(feat_c) # 合并特征,不需要拼接的话可替换为对应合并逻辑 merged_feat = layers.Concatenate()([feat_a, feat_b, feat_c]) # 最终分类头,类别数按需调整 output = layers.Dense(10, activation="softmax")(merged_feat) # 实例化模型 model = keras.Model(inputs=[input_a, input_b, input_c], outputs=output) model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
内容的提问来源于stack exchange,提问作者Sensei Munk
相关产品推荐
相关产品推荐

