合并同架构不同训练集的Keras模型时遇层名重复问题求助
合并同架构TensorFlow模型时的层名冲突问题
问题重现
我有两个基于同一架构、不同训练集训练的TensorFlow模型,尝试合并为一个模型,初始代码如下:
model1 = tf.keras.models.load_model('my_model_E1.keras') model2 = tf.keras.models.load_model('my_model_E2.keras') model_add= tf.keras.layers.Add()([model1.output, model2.output]) model = tf.keras.models.Model(inputs=[model1.input, model2.input], outputs=model_add)
运行时报错:
The name "dense_input" is used 2 times in the model. All layer names should be unique.
尝试过的方法及新问题
- 修改输入名称:
model1.input._name = 'input_1' model2.input._name = 'input_2'
问题依旧。
- 修改模型定义的输入参数:
model = tf.keras.models.Model(inputs=[input_1, input_2], outputs=model_mul)
出现新错误:
Graph disconnected: cannot obtain value for tensor KerasTensor(type_spec=TensorSpec(shape=(None, 3), dtype=tf.float64, name='dense_input'), name='input_2', description="created by layer 'dense_input'") at layer "dense_2_0". The following previous layers were accessed without issue: []
- 给所有层添加后缀:
for layer in model1.layers: layer._name = layer._name+'__1' for layer in model2.layers: layer._name = layer._name+'__2'
仍出现层名重复错误。
补充信息
TensorFlow版本:2.15.0
model1的定义与训练代码
def model1(): model = keras.Sequential([ layers.Dense(10, activation='sigmoid'), layers.Dense(10, activation='sigmoid'), layers.Dense(10, activation='sigmoid'), layers.Dense(1) ]) optimizer = tf.keras.optimizers.Adam(learning_rate=0.01) model.compile(loss='mse', optimizer=optimizer, metrics=['mae', 'mse',tf.keras.metrics.RootMeanSquaredError("RMSE")]) return model model1 = model1() history = model.fit( normed_train_input, train_output,batch_size=100, epochs=1000, validation_data=(normed_test_input, test_output), verbose=0,shuffle=False) model.save('my_model_E1.keras')
model2的训练代码
model = tf.keras.models.load_model('my_model_E1.keras') history = model.fit( normed_train_input, train_output,batch_size=100, epochs=1000, validation_data=(normed_test_input, test_output), verbose=0,shuffle=False) model.save('my_model_E2.keras')
解决方法
方法1:加载模型时同步重命名层和输入张量
直接修改层名后需要同步更新输入张量的名称,确保Keras内部的图关联正确:
import tensorflow as tf def load_model_with_prefix(model_path, prefix): model = tf.keras.models.load_model(model_path) # 遍历所有层添加前缀 for layer in model.layers: old_name = layer.name layer._name = f"{prefix}_{old_name}" # 更新输入张量的名称 for tensor in layer.inputs: tensor_base_name = tensor.name.split(':')[0] tensor._name = f"{prefix}_{tensor_base_name}:0" return model # 加载两个带前缀的模型 model1 = load_model_with_prefix('my_model_E1.keras', 'model1') model2 = load_model_with_prefix('my_model_E2.keras', 'model2') # 合并模型 model_add = tf.keras.layers.Add()([model1.output, model2.output]) merged_model = tf.keras.models.Model(inputs=[model1.input, model2.input], outputs=model_add) # 验证合并结果 merged_model.summary()
方法2:重新构建带唯一层名的模型,加载权重
因为两个模型结构完全一致,可以重新定义带前缀的模型结构,再加载原有权重:
import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers def build_model(prefix): model = keras.Sequential([ layers.Dense(10, activation='sigmoid', name=f"{prefix}_dense_1"), layers.Dense(10, activation='sigmoid', name=f"{prefix}_dense_2"), layers.Dense(10, activation='sigmoid', name=f"{prefix}_dense_3"), layers.Dense(1, name=f"{prefix}_dense_4") ]) # 编译模型(和原模型一致) optimizer = tf.keras.optimizers.Adam(learning_rate=0.01) model.compile(loss='mse', optimizer=optimizer, metrics=['mae', 'mse', tf.keras.metrics.RootMeanSquaredError("RMSE")]) return model # 构建两个带唯一层名的模型 model1 = build_model('model1') model2 = build_model('model2') # 加载已有权重 model1.load_weights('my_model_E1.keras') model2.load_weights('my_model_E2.keras') # 合并模型 model_add = tf.keras.layers.Add()([model1.output, model2.output]) merged_model = tf.keras.models.Model(inputs=[model1.input, model2.input], outputs=model_add) merged_model.summary()
失败原因说明
- 仅修改
model.input._name只改变了张量的显示名称,但Keras内部绑定的输入层名称(如dense_input)并未更新,层名冲突依旧。 - 单独修改
layer._name后,输入张量与层的关联没有同步更新,导致模型计算图断开,出现"Graph disconnected"错误。
内容的提问来源于stack exchange,提问作者Martin-Yiu
相关产品推荐
相关产品推荐

