Why we can't get the output_shpape when I emplement own layer and model?

how can i get the output_shape of custom model when I use model.summary()? It only appear ‘?’ in the column of ‘output_shape’

1 Like

Hi @user520, This happens when input shape is not defined in the model architecture. For example if you create a model without defining the input shape when you get the model.summary() the output shape will be ‘?’

model = models.Sequential([
    layers.Dense(64, activation='relu'),   
    layers.Dense(1, activation='sigmoid')  
])

If you define the input shape based upon the input the corresponding output shape will be displayed for the respective layers

model = models.Sequential([
    layers.InputLayer(input_shape=(20,)),  
    layers.Dense(64, activation='relu'),   
    layers.Dense(1, activation='sigmoid')  
])

Thank You.

Thank you for your answer! But when I customize a layer named ‘DenseBlock’ and ‘ConvDense’ and use them to customize a model named ‘DenseModel’ , I can’t know the model’s shape by using model.summary().

But when I use custom layers to define a Sequential model I can get the shape of model by using model.summary(). So why I can’t get the shape of model when I define custom model using custom layers?

Hi @user520, If possible could you please share the model to debug. Thank You.

Of Course, hope my problem can be solved, thank you

import tensorflow as tf


class ConvDense(tf.keras.layers.Layer):
    def __init__(self, output_dim):
        super(ConvDense, self).__init__()
        self.Conv2D = tf.keras.layers.Conv2D(output_dim, (3, 3), activation='relu')

    def call(self, inputs):
        inputs_pad = tf.pad(inputs, [[0, 0], [1, 1], [1, 1], [0, 0]], mode='REFLECT')
        output = self.Conv2D(inputs_pad)
        return output


class DenseBlock(tf.keras.layers.Layer):
    def __init__(self):
        super(DenseBlock, self).__init__()
        self.DC1 = ConvDense(16)
        self.DC2 = ConvDense(16)
        self.DC3 = ConvDense(16)

    def call(self, inputs):
        i1 = inputs
        # i1_pad = tf.pad(i1, [[0, 0], [1, 1], [1, 1], [0, 0]], mode='REFLECT')
        o1 = self.DC1(i1)
        i2 = tf.concat([i1, o1], axis=-1)
        # i2_pad = tf.pad(i2, [[0, 0], [1, 1], [1, 1], [0, 0]], mode='REFLECT')
        o2 = self.DC2(i2)
        i3 = tf.concat([i2, o2], axis=-1)
        # i3_pad = tf.pad(i3, [[0, 0], [1, 1], [1, 1], [0, 0]], mode='REFLECT')
        o3 = self.DC3(i3)
        outputs = tf.concat([i3, o3], axis=-1)
        return outputs


class DenseNet(tf.keras.Model):
    def __init__(self):
        super(DenseNet, self).__init__()

        # normalization
        self.normalize = tf.keras.layers.Rescaling(1./255)

        # encoder
        self.C1 = ConvDense(16)
        self.DB = DenseBlock()
        # decoder
        self.C2 = ConvDense(64)
        self.C3 = ConvDense(32)
        self.C4 = ConvDense(16)
        self.C5 = ConvDense(1)

    def call(self, inputs):
        normalize_inputs = self.normalize(inputs)
        print('normalize', normalize_inputs.shape, type(normalize_inputs))
        c1 = self.C1(normalize_inputs)
        print('c1', c1.shape)
        db = self.DB(c1)
        print('db', db.shape)
        c2 = self.C2(db)
        print('c2', c2.shape)
        c3 = self.C3(c2)
        print('c3', c3.shape)
        c4 = self.C4(c3)
        print('c4', c4.shape)
        c5 = self.C5(c4)
        print('c5', c5.shape)
        return c5

    def encoder(self, inputs):
        normalize_inputs = self.normalize(inputs)
        c1 = self.C1(normalize_inputs)
        db = self.DB(c1)
        return db

    def decoder(self, inputs):
        c3 = self.C3(inputs)
        c4 = self.C4(c3)
        c5 = self.C5(c4)
        return c5

Hi @user520, If you try to see the output shape for the ConvDense, DenseBlock you will get ValueError: The layer conv_dense_24 has never been called and thus has no defined output.
as these layers do not have a specified output shape that might be the reason for not getting the output shape in the model.summary() for those layers. Thank You.