Search code examples
pythontensorflowkerastensorflow2.0

Changing name for the input layer


Now I have loaded 2 different models and tried to combine them into one model.

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)

model1 and model2 are the same model trained by different training set Then there is an error:

The name "dense_input" is used 2 times in the model. All layer names should be unique.

Therefore, I have tried to change the name of the 2 inputs:

model1.input._name = 'input_1' 
model2.input._name = 'input_2'

But it does not help and the same error still exists.

Then I tried to change the last line of the model to:

model = tf.keras.models.Model(inputs=[input_1, input_2], outputs=model_mul)

Then there is an error:

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: []

Does it mean I should change the input_2 from

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"

to

KerasTensor(type_spec=TensorSpec(shape=(None, 3), dtype=tf.float64, name='input_2'), name='input_2', description="created by layer 'dense_input'") at layer "dense_2_0"

and how can I do it?

On the other hand, is there any other way for me so that this model can work?

update: my tensorflow version is 2.15.0 my code is like:

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')

for model 1. for model 2, I just read from the model1:

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')

for another set of data.

I have tried to use the code:

for layer in model1.layers:
    layer._name = layer._name+'__1'
for layer in model2.layers:
    layer._name = layer._name+'__2'

but even I have used it. There is still an error exist:

The name "dense_input" is used 2 times in the model. All layer names should be unique.

Solution

  • I see now you have tried many approach and it looks like there has been some changes in the API that prevents the available workaround. Even after you are renaming the input layer name, the remain unchaged, for example

    model1 = keras.models.load_model('my_model_E1') 
    model2 = keras.models.load_model('my_model_E2') 
    
    # renaming
    model1.input._name = 'model1_input'
    model2.input._name = 'model2_input'
    
    # input name changes
    print(model1.input._name, model2.input._name)
    ('model1_input', 'model2_input')
    
    # input name unchange
    print(model1.input, model2.input)
    (<KerasTensor: shape=(None, 10) .. layer 'dense_16_input')>,
     <KerasTensor: shape=(None, 10) .. layer 'dense_16_input')>)
    

    This might be potential bug. Feel free to raise a ticket in the GitHub. Now, current workaround only works on the computational layers (not the input layer). So, all you can do is to create new input layers for your model and run the current workarounds on the remaining layers to both mdoels. Here is the complete code.

    build the model

    def get_model():
        model = keras.Sequential([
            layers.Dense(10),
            layers.Dense(10),
            layers.Dense(10, activation='sigmoid'),
            layers.Dense(1)
        ])                                                   
        optimizer = keras.optimizers.Adam(learning_rate=0.01)
        model.compile(
            loss='mse',
            optimizer=optimizer,
            metrics=[
                'mae', 
                'mse',
                keras.metrics.RootMeanSquaredError("RMSE")
            ]
        )         
        return model
      
    model = get_model()
    model(tf.ones(shape=(1, 10)))
    model.save('my_model_E1')
    model.save('my_model_E2')
    

    load and rename

    model1 = keras.models.load_model('my_model_E1') 
    model2 = keras.models.load_model('my_model_E2') 
    
    model1._name = 'model1' # rename model name
    model2._name = 'model2' # rename model name
    
    # rename the computational layers (non-input layers)
    for i, layer in enumerate(model1.layers):
        layer._name = layer._name + str("_")
    
    # rename the computational layers's weights (if needed)
    for i in range(len(model1.weights)):
        model1.weights[i]._handle_name = model1.weights[i].name + "_" + str(i)
    
    for i, layer in enumerate(model1.layers):
        print(layer, layer.name)
    
    print()
    
    for i, layer in enumerate(model2.layers):
        print(layer, layer.name)
    
    <keras.src.layers.core.dense.Dense object at 0x7d2309e71c30> dense_20_
    <keras.src.layers.core.dense.Dense object at 0x7d2309e737f0> dense_21_
    <keras.src.layers.core.dense.Dense object at 0x7d2309d158a0> dense_22_
    <keras.src.layers.core.dense.Dense object at 0x7d2309d17070> dense_23_
    
    <keras.src.layers.core.dense.Dense object at 0x7d230930ab60> dense_20
    <keras.src.layers.core.dense.Dense object at 0x7d23093aa860> dense_21
    <keras.src.layers.core.dense.Dense object at 0x7d23093aa830> dense_22
    <keras.src.layers.core.dense.Dense object at 0x7d23093a9390> dense_23
    

    build combine model

    input_layer1 = keras.Input(shape=(10,), name='model1_input1')
    input_layer2 = keras.Input(shape=(10,), name='model2_input2')
    
    output_model1 = model1(input_layer1)
    output_model2 = model2(input_layer2)
    model_add = layers.Add()([output_model1, output_model2])
    
    model = keras.Model(
        inputs=[input_layer1, input_layer2], outputs=model_add
    )
    model.summary()
    # OK