Search code examples
tensorflowkerasmodelfunctional-programmingsequential

Tensorflow: Build new model from input and middle layers of another model


I'm trying to build new_model from another model layers for class activation mapping purposes.

def vgg_sequential():
    input_shape = IMG_SIZE + (3,)
    model = Sequential()
    model.add(tf.keras.applications.vgg16.VGG16(input_shape=input_shape, include_top=False, weights='imagenet'))
    model.add(layers.GlobalAveragePooling2D())
    model.add(layers.Dense(1))
    return model
cam_model = tf.keras.Model(inputs=seq_vgg.layers[0].input, outputs=(seq_vgg.layers[-3].output, seq_vgg.layers[-1].output))

And with this code i get the following error:

ValueError: Graph disconnected: cannot obtain value for tensor KerasTensor(type_spec=TensorSpec(shape=(None, 480, 480, 3), dtype=tf.float32, name='vgg16_input'), name='vgg16_input', description="created by layer 'vgg16_input'") at layer "vgg16". The following previous layers were accessed without issue: ['block1_conv1', 'block1_conv2', 'block1_pool', 'block2_conv1', 'block2_conv2', 'block2_pool', 'block3_conv1', 'block3_conv2', 'block3_conv3', 'block3_pool', 'block4_conv1', 'block4_conv2', 'block4_conv3', 'block4_pool', 'block5_conv1']

Already tried functional model API, providing Input() layer inside vgg_sequential() with the same error that my Input layer is disconected from the rest of my model. Beside this when using tf.keras.applications.efficientnet_v2 that provides input layers for rescaling and resizing images i don't have any problem.

Any help, information, tips or links to docs that getas me to a solution will be very much appreciated.

Thanks in advance.


Solution

  • In your case, you may need to write your model definition in the following way in order to build class activation mapping network. Know more details in this ticket.

    def vgg_sequential():
        inputs = keras.Input(shape=(224, 224, 3,))
        pretrained_model = keras.applications.VGG16(
                weights='imagenet', 
                include_top=False, 
                input_tensor=inputs,
            )
        x = keras.layers.GlobalAveragePooling2D()(pretrained_model.output)
        outputs = keras.layers.Dense(1)(x)
        model = keras.Model(inputs, outputs)
        return model
    

    And then you can do

    cam_model = keras.Model(
        inputs=seq_vgg.layers[0].input, 
        outputs=(
            seq_vgg.layers[-3].output, 
            seq_vgg.layers[-1].output
        )
    )
    
    a, b = cam_model(tf.ones((1, 224, 224, 3)))
    a.shape, b.shape
    (TensorShape([1, 7, 7, 512]), TensorShape([1, 1]))