Just a small suggestion for a better explanation and description of exercise 2

Let’s say we do not add input layer in our sequential model, I noticed the following error after executing model.summary():

ValueError                                Traceback (most recent call last)
<ipython-input-39-5f15418b3570> in <module>
----> 1 model.summary()

/opt/conda/lib/python3.7/site-packages/keras/engine/training.py in summary(self, line_length, positions, print_fn, expand_nested, show_trainable)
   2774     if not self.built:
   2775       raise ValueError(
-> 2776           'This model has not yet been built. '
   2777           'Build the model first by calling `build()` or by calling '
   2778           'the model on a batch of data.')

ValueError: This model has not yet been built. Build the model first by calling `build()` or by calling the model on a batch of data.

Googling and stackoverflowing the error would lead to a fix in which one could potentially add model.build(input_shape=(None,400)) as an alternative for tf.keras.Input(shape=(400,)), which is given as some sort of a hint in the notebook.

  1. It would be great if we could get both alternatives in the exercise description.
  2. can somebody explain why input_shape=(None,400) is the correct shape for the input? why not just input_shape=(400) as in we get image shapes of 20 x 20. I do not get the None part!

PS. adding model.build(input_shape=(400)) would lead to the following error:

TypeError                                 Traceback (most recent call last)
<ipython-input-40-e58b09a2541d> in <module>
     17     ], name = "my_model" 
     18 )
---> 19 model.build(input_shape=(400))

/opt/conda/lib/python3.7/site-packages/keras/engine/sequential.py in build(self, input_shape)
    343       if input_shape is None:
    344         raise ValueError('You must provide an `input_shape` argument.')
--> 345       self._build_graph_network_for_inferred_shape(input_shape)
    346       if not self.built:
    347         input_shape = tuple(input_shape)

/opt/conda/lib/python3.7/site-packages/tensorflow/python/training/tracking/base.py in _method_wrapper(self, *args, **kwargs)
    627     self._self_setattr_tracking = False  # pylint: disable=protected-access
    628     try:
--> 629       result = method(self, *args, **kwargs)
    630     finally:
    631       self._self_setattr_tracking = previous_value  # pylint: disable=protected-access

/opt/conda/lib/python3.7/site-packages/keras/engine/sequential.py in _build_graph_network_for_inferred_shape(self, input_shape, input_dtype)
    272       # Determine whether the input shape is novel, i.e. whether the model
    273       # should be rebuilt.
--> 274       input_shape = tuple(input_shape)
    275       if self._inferred_input_shape is None:
    276         new_shape = input_shape

TypeError: 'int' object is not iterable


Thanks for your suggestion.

Here “None” in model.build(input_shape=(None,400)) means that there can be variable number of samples. For example we are first using 20 samples during training, and then use 40 samples later. “None” helps in increasing the flexibility of our code.

Thanks for the post. I was stuck here too. The replies in this thread make more sense now.