GRADED FUNCTION: convolutional_model Conv2D test case failing

Getting following unit test failure for Conv2D call…
Code for Conv2D is :

    ## CONV2D: 8 filters 4x4, stride of 1, padding 'SAME'
    Z1 = tfl.Conv2D(filters = 8 , kernel_size= (4,4) ,strides=(1,1), padding='SAME')(input_img)
Test failed 
 Expected value 

 ['Conv2D', (None, 64, 64, 8), 392, 'same', 'linear', 'GlorotUniform'] 

 does not match the input value: 

 ['TensorFlowOpLayer', [(None, 64, 64, 1)], 0]
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-16-f1284300b767> in <module>
     15         ['Dense', (None, 6), 390, 'softmax']]
     16 
---> 17 comparator(summary(conv_model), output)

~/work/release/W1A2/test_utils.py in comparator(learner, instructor)
     20                   "\n\n does not match the input value: \n\n",
     21                   colored(f"{a}", "red"))
---> 22             raise AssertionError("Error in test")
     23     print(colored("All tests passed!", "green"))
     24 

AssertionError: Error in test

My guess is that the problem is that you have inserted an extraneous layer between the input layer (which they provided for you) and the first Conv2D layer. Here’s what the full list of layers should look like:

output = [['InputLayer', [(None, 64, 64, 3)], 0],
        ['Conv2D', (None, 64, 64, 8), 392, 'same', 'linear', 'GlorotUniform'],
        ['ReLU', (None, 64, 64, 8), 0],
        ['MaxPooling2D', (None, 8, 8, 8), 0, (8, 8), (8, 8), 'same'],
        ['Conv2D', (None, 8, 8, 16), 528, 'same', 'linear', 'GlorotUniform'],
        ['ReLU', (None, 8, 8, 16), 0],
        ['MaxPooling2D', (None, 2, 2, 16), 0, (4, 4), (4, 4), 'same'],
        ['Flatten', (None, 64), 0],
        ['Dense', (None, 6), 390, 'softmax']]

I’m guessing you’ll see something between InputLayer and the first Conv2D in your output. So how did that get there? Also note that there is nothing of shape (m, 64, 64, 1) here.

Thank you @paulinpaloalto .
I looked up my code and did not see any extraneous layer between the input layer and first Conv2D layer.

Here is my code:

def convolutional_model(input_shape):
    input_img = tf.keras.Input(shape=input_shape)
    # YOUR CODE STARTS HERE

    ## CONV2D: 8 filters 4x4, stride of 1, padding 'SAME'
    Z1 = tfl.Conv2D(filters = 8 , kernel_size= (4,4) ,padding='same')(input_img)

    ## RELU
    A1 = tfl.ReLU()(Z1)

Doesn’t that arise from a mathematical operation? Eg reduce_mean()
Anything in the code that would make TF think you’re doing math?

@ai_curious , I think the code is pretty straight forward in this case as listed in , so not sure if the parameters i passed to Conv2D is messing up somewhere ?

GRADED FUNCTION: convolutional_model Conv2D test case failing - #4 by pravinunni

does tfl.ReLU()(Z1) expects any parameters to be passed ? my understanding was those params are optional and will take default values.

Fingers working independently of brain this morning. Will stop until I have something useful. :face_with_open_eyes_and_hand_over_mouth:

Well, that’s your code and it looks correct as far as it goes. But evidently running it does not produce the correct results. So let’s see the output, e.g. like this:

Model: "functional_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 64, 64, 3)]       0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 64, 64, 8)         392       
_________________________________________________________________
re_lu_1 (ReLU)               (None, 64, 64, 8)         0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 8, 8, 8)           0         
_________________________________________________________________

That’s the beginning of the output when I run it and mine passes.

One other thing to note: just typing new code and then calling that function again still runs the old code, right? So what you are looking at may not be what is compiled into the runtime image. You need to actually click “Shift - Enter” on the changed cell get the new code compiled after you change the code. One simple way to make sure everything is consistent (WYSIWYG):

Kernel -> Restart and Clear Output
Cell -> Run All

What happens if you do that?

yes @paulinpaloalto , i did multiple kernel restarts and clear output and also changed browser to make sure everything is clean. Still seeing same failure message.

And can you please show us the output of your model summary? As I did above …

sure, here it is …

Model: "functional_1"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            [(None, 64, 64, 3)]  0                                            
__________________________________________________________________________________________________
tf_op_layer_Max (TensorFlowOpLa [(None, 64, 64, 1)]  0           input_1[0][0]                    
__________________________________________________________________________________________________
tf_op_layer_Sub (TensorFlowOpLa [(None, 64, 64, 3)]  0           input_1[0][0]                    
                                                                 tf_op_layer_Max[0][0]            
__________________________________________________________________________________________________
tf_op_layer_Exp (TensorFlowOpLa [(None, 64, 64, 3)]  0           tf_op_layer_Sub[0][0]            
__________________________________________________________________________________________________
tf_op_layer_Sum (TensorFlowOpLa [(None, 64, 64, 1)]  0           tf_op_layer_Exp[0][0]            
__________________________________________________________________________________________________
tf_op_layer_RealDiv (TensorFlow [(None, 64, 64, 3)]  0           tf_op_layer_Exp[0][0]            
                                                                 tf_op_layer_Sum[0][0]            
==================================================================================================
Total params: 0
Trainable params: 0
Non-trainable params: 0
__________________________________________________________________________________________________
Test failed 
 Expected value 

 ['Conv2D', (None, 64, 64, 8), 392, 'same', 'linear', 'GlorotUniform'] 

 does not match the input value: 

 ['TensorFlowOpLayer', [(None, 64, 64, 1)], 0]
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-14-f1284300b767> in <module>
     15         ['Dense', (None, 6), 390, 'softmax']]
     16 
---> 17 comparator(summary(conv_model), output)

~/work/release/W1A2/test_utils.py in comparator(learner, instructor)
     20                   "\n\n does not match the input value: \n\n",
     21                   colored(f"{a}", "red"))
---> 22             raise AssertionError("Error in test")
     23     print(colored("All tests passed!", "green"))
     24 

AssertionError: Error in test

Ok, that is completely wrong, right? So how could that happen from the code you showed? Where are all those TensorFlowOp layers coming from?

Are you sure you’re running this on the course website and not in your own environment with a much later version of TF? The course uses TF 2.3.0 which is pretty “old school” compared to what Google has published lately.

Either that or you’ve messed with the imports and changed what tfl means. That is a symbol defined in the notebook, right?

i am using course website to run the lab assignments.
this is tfl → import tensorflow.keras.layers as tfl

Ok, it’s time to punt: I’m at a loss to explain the strange results, so I’ll need to see the source code. Please check your DMs.

that model.summary() is so weird. It goes straight from the input layer to math operations directly on the input. Here’s what I get when I run the code fragment above on my local env

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers as tfl

input_shape = (64,64,3)
input_img = tfl.Input(shape=input_shape)
Z1 = tfl.Conv2D(filters = 8 , kernel_size= (4,4) ,padding='same')(input_img)
A1 = tfl.ReLU()(Z1)
model = keras.Model(inputs=input_img, outputs=A1)
model.summary()

Model: “model_1”


Layer (type) Output Shape Param #


input_6 (InputLayer) [(None, 64, 64, 3)] 0


conv2d_3 (Conv2D) (None, 64, 64, 8) 392


re_lu_3 (ReLU) (None, 64, 64, 8) 0


Total params: 392
Trainable params: 392
Non-trainable params: 0


I agree that it’s crazy. More news after I have a chance to look at the code. It’s gotta be something interesting …

Ok, it turns out to be simple, but the problem is way later and is not shown in the code Pravin gave us. Instead of the correct Dense layer at the end of the model, you have this:

    ## Dense layer
    ## 6 neurons in output layer. Hint: one of the arguments should be "activation='softmax'" 
    outputs = tf.keras.activations.softmax(input_img)

So that completely messes up the computation graph, because input_img is the input to two later layers. Not sure why calling softmax like that would generate those specific TensorFlowOps, but it’s now clear why the graph is a mess. Not worth thinking about that probably, now that we know what the problem is.

@pravinunni: You have a comment for something that is close to the correct Dense layer, but the way you specified the softmax activation is wrong, which is probably why you tried your alternate approach. They gave you the correct syntax in the comments for that line, right? Have a closer look and that should fix things.

@paulinpaloalto thank you for the details, yes i did update the code and it worked fine. Was a silly thing, since i kept on trying different syntax i missed the correct one in between.

To me that looks exactly like the algebra of a vectorized computation of softmax, and model.summary() tells us it has been chained to the input layer in the computation graph, exactly as it was told to do :rofl:

Good find