Search code examples
pythontensorflowkerastensorflow2.0

This model has not yet been built error on model.summary()


I've keras model defined as follow

class ConvLayer(Layer) :
    def __init__(self, nf, ks=3, s=2, **kwargs):
        self.nf = nf
        self.grelu = GeneralReLU(leak=0.01)
        self.conv = (Conv2D(filters     = nf,
                            kernel_size = ks,
                            strides     = s,
                            padding     = "same",
                            use_bias    = False,
                            activation  = "linear"))
        super(ConvLayer, self).__init__(**kwargs)

    def rsub(self): return -self.grelu.sub
    def set_sub(self, v): self.grelu.sub = -v
    def conv_weights(self): return self.conv.weight[0]

    def build(self, input_shape):
        # No weight to train.
        super(ConvLayer, self).build(input_shape)  # Be sure to call this at the end

    def compute_output_shape(self, input_shape):
        output_shape = (input_shape[0],
                        input_shape[1]/2,
                        input_shape[2]/2,
                        self.nf)
        return output_shape

    def call(self, x):
        return self.grelu(self.conv(x))

    def __repr__(self):
        return f'ConvLayer(nf={self.nf}, activation={self.grelu})'
class ConvModel(tf.keras.Model):
    def __init__(self, nfs, input_shape, output_shape, use_bn=False, use_dp=False):
        super(ConvModel, self).__init__(name='mlp')
        self.use_bn = use_bn
        self.use_dp = use_dp
        self.num_classes = num_classes

        # backbone layers
        self.convs = [ConvLayer(nfs[0], s=1, input_shape=input_shape)]
        self.convs += [ConvLayer(nf) for nf in nfs[1:]]
        # classification layers
        self.convs.append(AveragePooling2D())
        self.convs.append(Dense(output_shape, activation='softmax'))

    def call(self, inputs):
        for layer in self.convs: inputs = layer(inputs)
        return inputs

I'm able to compile this model without any issues

>>> model.compile(optimizer=tf.keras.optimizers.Adam(lr=lr), 
              loss='categorical_crossentropy',
              metrics=['accuracy'])

But when I query the summary for this model, I see this error

>>> model = ConvModel(nfs, input_shape=(32, 32, 3), output_shape=num_classes)
>>> model.summary()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-220-5f15418b3570> in <module>()
----> 1 model.summary()

/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/network.py in summary(self, line_length, positions, print_fn)
   1575     """
   1576     if not self.built:
-> 1577       raise ValueError('This model has not yet been built. '
   1578                        'Build the model first by calling `build()` or calling '
   1579                        '`fit()` with some data, or specify '

ValueError: This model has not yet been built. Build the model first by calling `build()` or calling `fit()` with some data, or specify an `input_shape` argument in the first layer(s) for automatic build.

I'm providing input_shape for the first layer of my model, why is throwing this error?


Solution

  • The error says what to do:

    This model has not yet been built. Build the model first by calling build()

    model.build(input_shape) # `input_shape` is the shape of the input data
                             # e.g. input_shape = (None, 32, 32, 3)
    model.summary()