C4 W3 A6 Unet utput tensors of a Functional model must be the output of a TensorFlow `Layer`

  • for the unet example, I did everything as mentioned in exercise 1
Exercise 1 - conv_block
Implement conv_block(...). Here are the instructions for each step in the conv_block, or contracting block:

Add 2 Conv2D layers with n_filters filters with kernel_size set to 3, kernel_initializer set to 'he_normal', padding set to 'same' and 'relu' activation.
if dropout_prob > 0, then add a Dropout layer with parameter dropout_prob
If max_pooling is set to True, then add a MaxPooling2D layer with 2x2 pool size
  • but still i am getting the below error
ValueError                                Traceback (most recent call last)
Input In [10], in <cell line: 5>()
      3 inputs = Input(input_size)
      4 cblock1 = conv_block(inputs, n_filters * 1)
----> 5 model1 = tf.keras.Model(inputs=inputs, outputs=cblock1)
      7 output1 = [['InputLayer', [(None, 96, 128, 3)], 0],
      8             ['Conv2D', (None, 96, 128, 32), 896, 'same', 'relu', 'HeNormal'],
      9             ['Conv2D', (None, 96, 128, 32), 9248, 'same', 'relu', 'HeNormal'],
     10             ['MaxPooling2D', (None, 48, 64, 32), 0, (2, 2)]]
     12 print('Block 1:')

File /usr/local/lib/python3.8/dist-packages/tensorflow/python/training/tracking/base.py:587, in no_automatic_dependency_tracking.<locals>._method_wrapper(self, *args, **kwargs)
    585 self._self_setattr_tracking = False  # pylint: disable=protected-access
    586 try:
--> 587   result = method(self, *args, **kwargs)
    588 finally:
    589   self._self_setattr_tracking = previous_value  # pylint: disable=protected-access

File /usr/local/lib/python3.8/dist-packages/keras/engine/functional.py:148, in Functional.__init__(self, inputs, outputs, name, trainable, **kwargs)
    145   if not all([functional_utils.is_input_keras_tensor(t)
    146               for t in tf.nest.flatten(inputs)]):
    147     inputs, outputs = functional_utils.clone_graph_nodes(inputs, outputs)
--> 148 self._init_graph_network(inputs, outputs)

File /usr/local/lib/python3.8/dist-packages/tensorflow/python/training/tracking/base.py:587, in no_automatic_dependency_tracking.<locals>._method_wrapper(self, *args, **kwargs)
    585 self._self_setattr_tracking = False  # pylint: disable=protected-access
    586 try:
--> 587   result = method(self, *args, **kwargs)
    588 finally:
    589   self._self_setattr_tracking = previous_value  # pylint: disable=protected-access

File /usr/local/lib/python3.8/dist-packages/keras/engine/functional.py:186, in Functional._init_graph_network(self, inputs, outputs)
    183   if any(not hasattr(tensor, '_keras_history') for tensor in self.outputs):
    184     base_layer_utils.create_keras_history(self._nested_outputs)
--> 186 self._validate_graph_inputs_and_outputs()
    188 # A Network does not create weights of its own, thus it is already
    189 # built.
    190 self.built = True

File /usr/local/lib/python3.8/dist-packages/keras/engine/functional.py:740, in Functional._validate_graph_inputs_and_outputs(self)
    738 if not hasattr(x, '_keras_history'):
    739   cls_name = self.__class__.__name__
--> 740   raise ValueError(f'Output tensors of a {cls_name} model must be '
    741                    'the output of a TensorFlow `Layer` '
    742                    f'(thus holding past layer metadata). Found: {x}')

ValueError: Output tensors of a Functional model must be the output of a TensorFlow `Layer` (thus holding past layer metadata). Found: <keras.layers.pooling.max_pooling2d.MaxPooling2D object at 0x7efc8b0ae970>

I suggest going through the instruction again. It is common to make mistakes on the first attempt. So, check the instructions and your code again.

  • thanks for the reply, i checked i solved that issue
  • but i got another issue

output

ValueError                                Traceback (most recent call last)
Input In [28], in <cell line: 6>()
      3 img_width = 128
      4 num_channels = 3
----> 6 unet = unet_model((img_height, img_width, num_channels))
      7 comparator(summary(unet), outputs.unet_model_output)

Input In [27], in unet_model(input_size, n_filters, n_classes)
     32 ublock6 = upsampling_block(cblock5[0], cblock4[1],  n_filters*8)
     33 # Chain the output of the previous block as expansive_input and the corresponding contractive block output.
     34 # Note that you must use the second element of the contractive block i.e before the maxpooling layer. 
     35 # At each step, use half the number of filters of the previous block 
---> 36 ublock7 = upsampling_block(cblock4[0], cblock3[1],  n_filters*4)
     37 ublock8 = upsampling_block(cblock3[0], cblock2[1],  n_filters*2)
     38 ublock9 = upsampling_block(cblock2[0], cblock1[1],  n_filters)

Input In [17], in upsampling_block(expansive_input, contractive_input, n_filters)
     16 up = Conv2DTranspose(
     17              n_filters,    # number of filters
     18              (3,3),    # Kernel size
     19              strides=(2,2),
     20              padding='same')(expansive_input)
     22 # Merge the previous output and the contractive_input
---> 23 merge = concatenate([up, contractive_input], axis=3)
     24 conv = Conv2D(n_filters,   # Number of filters
     25              (3,3),     # Kernel size
     26              activation='relu',
     27              padding='same',
     28              kernel_initializer='he_normal')(merge)
     29 conv = Conv2D(n_filters,  # Number of filters
     30              (3,3),   # Kernel size
     31              activation='relu',
     32              padding='same',
     33               # set 'kernel_initializer' same as above
     34              kernel_initializer='he_normal')(conv)

File /usr/local/lib/python3.8/dist-packages/keras/layers/merging/concatenate.py:217, in concatenate(inputs, axis, **kwargs)
    185 @keras_export('keras.layers.concatenate')
    186 def concatenate(inputs, axis=-1, **kwargs):
    187   """Functional interface to the `Concatenate` layer.
    188 
    189   >>> x = np.arange(20).reshape(2, 2, 5)
   (...)
    215       A tensor, the concatenation of the inputs alongside axis `axis`.
    216   """
--> 217   return Concatenate(axis=axis, **kwargs)(inputs)

File /usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py:67, in filter_traceback.<locals>.error_handler(*args, **kwargs)
     65 except Exception as e:  # pylint: disable=broad-except
     66   filtered_tb = _process_traceback_frames(e.__traceback__)
---> 67   raise e.with_traceback(filtered_tb) from None
     68 finally:
     69   del filtered_tb

File /usr/local/lib/python3.8/dist-packages/keras/layers/merging/concatenate.py:123, in Concatenate.build(self, input_shape)
    120 unique_dims = set(
    121     shape[axis] for shape in shape_set if shape[axis] is not None)
    122 if len(unique_dims) > 1:
--> 123   raise ValueError(err_msg)

ValueError: A `Concatenate` layer requires inputs with matching shapes except for the concatenation axis. Received: input_shape=[(None, 12, 16, 128), (None, 24, 32, 128)]
  • isnt my code same as mentioned in the exercise comments?
  • where am i doing wrong?

It is given that:

Chain the output of the previous block as expansive_input

So, for ublock7, input should be the “output of the previous block”. What is the “previous” block for ublock7? Is it ublock6 or ublock4? Same for ublock8 and ublock9.

1 Like
  • i didnt understand that line, according to the example, it is cbock5[0] and cblock4[1]

  • since the output of conv block layers should feed into the input , then it should be the next conv layers right? which are cblock4[0] and cblock3[1]`?

For ublock7, what is the previous block?

  • according to the diagram , now i understood that ,for ublock7, ublock6 is the previous layer and skip layers are conv4 , conv3,conv2 etc
  • i tried that, even that isnt working
ublock6 = upsampling_block(cblock5[0], cblock4[1],  n_filters*8)
    # Chain the output of the previous block as expansive_input and the corresponding contractive block output.
    # Note that you must use the second element of the contractive block i.e before the maxpooling layer. 
    # At each step, use half the number of filters of the previous block 
    ublock7 = upsampling_block(ublock6[0], cblock3[1],  n_filters*4)
    ublock8 = upsampling_block(ublock7[0], cblock2[1],  n_filters*2)
    ublock9 = upsampling_block(ublock8[0], cblock1[1],  n_filters)
    ### END CODE HERE
  • i am getting the error
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [22], in <cell line: 6>()
      3 img_width = 128
      4 num_channels = 3
----> 6 unet = unet_model((img_height, img_width, num_channels))
      7 comparator(summary(unet), outputs.unet_model_output)

Input In [21], in unet_model(input_size, n_filters, n_classes)
     32 ublock6 = upsampling_block(cblock5[0], cblock4[1],  n_filters*8)
     33 # Chain the output of the previous block as expansive_input and the corresponding contractive block output.
     34 # Note that you must use the second element of the contractive block i.e before the maxpooling layer. 
     35 # At each step, use half the number of filters of the previous block 
---> 36 ublock7 = upsampling_block(ublock6[0], cblock3[1],  n_filters*4)
     37 ublock8 = upsampling_block(ublock7[0], cblock2[1],  n_filters*2)
     38 ublock9 = upsampling_block(ublock8[0], cblock1[1],  n_filters)

Input In [9], in upsampling_block(expansive_input, contractive_input, n_filters)
      4 """
      5 Convolutional upsampling block
      6 
   (...)
     12     conv -- Tensor output
     13 """
     15 ### START CODE HERE
---> 16 up = Conv2DTranspose(
     17              n_filters,    # number of filters
     18              (3,3),    # Kernel size
     19              strides=(2,2),
     20              padding='same')(expansive_input)
     22 # Merge the previous output and the contractive_input
     23 merge = concatenate([up, contractive_input], axis=3)

File /usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py:67, in filter_traceback.<locals>.error_handler(*args, **kwargs)
     65 except Exception as e:  # pylint: disable=broad-except
     66   filtered_tb = _process_traceback_frames(e.__traceback__)
---> 67   raise e.with_traceback(filtered_tb) from None
     68 finally:
     69   del filtered_tb

File /usr/local/lib/python3.8/dist-packages/keras/engine/input_spec.py:228, in assert_input_compatibility(input_spec, inputs, layer_name)
    226   ndim = x.shape.rank
    227   if ndim is not None and ndim < spec.min_ndim:
--> 228     raise ValueError(f'Input {input_index} of layer "{layer_name}" '
    229                      'is incompatible with the layer: '
    230                      f'expected min_ndim={spec.min_ndim}, '
    231                      f'found ndim={ndim}. '
    232                      f'Full shape received: {tuple(shape)}')
    233 # Check dtype.
    234 if spec.dtype is not None:

ValueError: Input 0 of layer "conv2d_transpose_11" is incompatible with the layer: expected min_ndim=4, found ndim=3. Full shape received: (12, 16, 256)

You don’t need the subindex of unblock6. Same for unblock7 and unblock8.