如何多次加载Keras模型且不共享权重,构建新模型并保存
多次加载模型不共享权重并构建新模型的解决方案
嘿,我来帮你搞定这个问题!你的思路其实已经对了一半——核心就是让每个加载的模型层名唯一,避免Keras默认的权重共享机制,然后用Functional API把这些独立模型组合起来,最后保存完整的新模型。下面是完整的实现方案:
1. 完善预训练模型加载函数
首先把你写的加载函数补全并优化,确保每次加载的模型都是独立的,不共享权重:
from keras.models import model_from_json def load_pretrained_model(minus_layers, add_str): # 加载预训练模型的结构(myModelJson是你的模型结构字符串) model = model_from_json(myModelJson) # 加载对应权重文件 model.load_weights(weightsfile) # 移除顶层指定数量的层 for _ in range(minus_layers): model.layers.pop() # 关键:更新模型的输出和节点连接,避免结构混乱 model.outputs = [model.layers[-1].output] model.layers[-1].outbound_nodes = [] # 刷新模型的输入和内部层列表,确保结构有效 model.inputs = [model.layers[0].input] model._layers = model.layers # 给所有层加上唯一后缀,彻底避免权重共享 for layer in model.layers: layer.name = f"{layer.name}_{add_str}" model.name = f"{model.name}_{add_str}" return model
2. 多次加载独立模型
现在你可以多次调用这个函数,每次传入不同的add_str参数,得到完全独立、权重不共享的模型实例:
# 加载两个独立的模型,分别加后缀"a"和"b" model_a = load_pretrained_model(minus_layers=2, add_str="a") model_b = load_pretrained_model(minus_layers=2, add_str="b")
3. 构建新的组合模型
用Keras的Functional API把这些独立模型拼接起来,比如做特征融合后加分类层:
from keras.layers import Concatenate, Dense from keras.models import Model # 获取两个模型的输出特征 output_a = model_a.output output_b = model_b.output # 拼接两个特征向量 concat_features = Concatenate(axis=-1)([output_a, output_b]) # 添加自定义的顶层(这里以10分类为例) final_output = Dense(10, activation="softmax")(concat_features) # 构建完整的新模型 combined_model = Model(inputs=[model_a.input, model_b.input], outputs=final_output)
4. 保存新模型
最后可以直接保存整个模型(结构+权重),或者分开保存结构和权重:
方式1:一次性保存完整模型(推荐)
combined_model.save("my_combined_model.h5") # 后续加载只需:from keras.models import load_model; model = load_model("my_combined_model.h5")
方式2:分开保存结构和权重
# 保存模型结构 model_json = combined_model.to_json() with open("combined_model_structure.json", "w") as f: f.write(model_json) # 保存模型权重 combined_model.save_weights("combined_model_weights.h5") # 后续加载: # model = model_from_json(open("combined_model_structure.json").read()) # model.load_weights("combined_model_weights.h5")
关键注意点
- 层名唯一化:这是避免权重共享的核心!Keras中同名层默认会共享权重,所以给每个加载的模型层加上独特后缀是必须的。
- 模型结构刷新:移除顶层后,一定要手动更新模型的
outputs、outbound_nodes、inputs和_layers,否则模型结构会无效,后续拼接会报错。 - Functional API的灵活性:如果你的组合逻辑更复杂(比如分支、多输入多输出),Functional API是最佳选择,能清晰定义各个组件的连接关系。
内容的提问来源于stack exchange,提问作者maniac
相关产品推荐
相关产品推荐

