0

Compare the following code snippets. I implemented a simple keras model like this

inp = layers.Input((10,2))
x = layers.Flatten()(inp)
x = layers.Dense(5)(x)
m = models.Model(inputs=inp, outputs=x)

For one reason or another, I need to have my model in an objective way. So no problem, it's easy to reimplement that into:

class MyModel(tf.keras.Model):
   def __init__(self, inp_shape, out_size = 5):
       super(MyModel, self).__init__()
       self.inp = layers.InputLayer(input_shape=inp_shape)
       self.flatten = layers.Flatten()
       self.dense = layers.Dense(out_size)

   def call(self, a):
       x = self.inp(a)
       x = self.flatten(x)
       x = self.dense(x)
       return x

However in the second case when I try to run:

m = MyModel((10,2))
m.summary()

I get:

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 don't quite get why? Shouldn't the above be equivalent?

A. Newski
  • 156
  • 1
  • 8

2 Answers2

1

The reason for this is that when you create an object of this model you are just creating its layers and not its graph. So in short the output from layer 1 is not going in layer 2 cause those are entirely separate attributes of the class but when you call the model those separate attributes combines and form the graph.

Abhishek Prajapat
  • 1,793
  • 2
  • 8
  • 19
0

When you define a model in tf. keras with subclassed API, you need to build the model first by calling build or run the model on some data.

m = MyModel((10,2))
m.build(input_shape=(10, 2)) # < -- build the model 
m.summary()

That said, you don't also need to define self.inp while building the model with subclassed API. The .summary() may not look right to you for the subclassed model, you may need to check this instead.

Innat
  • 16,113
  • 6
  • 53
  • 101
  • Isn't that a bit repetitive, as I define input already here: `MyModel((10,2))` ? – A. Newski Jul 13 '21 at 19:42
  • Not exactly. Building model in seq and func API are like data structure whereas in subclass API is simply a piece of python code. That’s why `Input` layer or a specification layer only part of the non-subclassed api model. – Innat Jul 13 '21 at 21:55
  • You shouldn’t or don't need to define the spec layer inside subclassed api model. – Innat Jul 13 '21 at 21:56
  • Which one is spec layer? – A. Newski Jul 14 '21 at 09:08
  • BTW the whole point of me trying to print the summary was to see if the output shapes match, however here I get: output shape "multiple", which does not match functional API summary that correctly printed Dense output shape as 5. – A. Newski Jul 14 '21 at 09:14
  • The spec layer refers to the `keras.Input` layer. It's more like a layer that holds information of the data e.g data type, data shape etc. – Innat Jul 14 '21 at 10:59
  • Check out this [tweet thread](https://twitter.com/fchollet/status/1414667159326715908), you may find it useful. – Innat Jul 14 '21 at 11:00