Week 2 Assignment 2

I am having trouble with the second exercise. I have the following line to apply data augmentation

x = data_augmentation(inputs)

and I am getting the following error:

Input 0 of layer sequential_1 is incompatible with the layer: expected ndim=4, found ndim=3. Full shape received: [None, 160, 160]

I would imagine this means that I passed the wrong variable into the data_augmentation function but I’m not quite sure what the right variable to pass would be

1 Like

bro use
X = data_augmentation()(inputs)

1 Like
I'm also getting an error with input/augmentation, 
even though I called data_augmentation(inputs) in the way that was suggested above 
(see below for error output trace).  I'm guessing that I didn't call the Input correctly, 
but I can't figure out what's wrong?  
Also, how about some more comments in the pre-written lines of the assignment 
(i.e. outside the ### START CODE HERE) ... like what in the heck
does this mean:  input_shape = image_shape + (3,) ???  #adding a channel dimension of size 3?

ValueError Traceback (most recent call last)
in
----> 1 model2 = alpaca_model(IMG_SIZE, data_augmentation)

in alpaca_model(image_shape, data_augmentation)
26
27 # apply data augmentation to the inputs
—> 28 x = data_augmentation()(inputs)
29
30 # data preprocessing using the same weights the model was trained on

/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in call(self, *args, **kwargs)
914 # not to any other argument.
915 # - setting the SavedModel saving spec.
→ 916 inputs, args, kwargs = self._split_out_first_arg(args, kwargs)
917 input_list = nest.flatten(inputs)
918

/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in _split_out_first_arg(self, args, kwargs)
2978 else:
2979 raise ValueError(
→ 2980 ‘The first argument to Layer.call must always be passed.’)
2981 return inputs, args, kwargs
2982

ValueError: The first argument to Layer.call must always be passed.

Contrary to some suggestion I’ve seen posted, the code works with x = data_augmentation(inputs) instead of x = data_augmentation()(inputs). But make sure to use the input_shape as param when initialising the inputs: inputs = tf.keras.Input(shape=input_shape)

2 Likes

It might have been nice, if the assignment had included some import macros so that (just like before) we could use Input instead of tf.keras.Input, but thanks for the tip. I was led astray by another comment, and that cleared that part up, but it’s still not clear what was meant by the comment:

“# create a prediction layer with one neuron (as a classifier only needs one)”

There are many other confusing comments in this assignment, for example:
“Same as the imageNetv2 input size”

  • which is it imagenet or imageNetv2? → “# From imageNet”
    There was another mention in Andrew Ng’s lecture notes about MobileNetv1 vs v2, so is there a connection between the v1’s and v2’s of MobileNet and imagenet?

Also, what’s up with this syntax?:
“input_shape = image_shape + (3,)” - at some point, Andrew Ng mentioned that we should only use array datatypes in Python with the double parentheses ((3,)), and why is it not ((,3)) for the 3rd dimension??

I finally got it working. This assignment was really not as good as they usually are. Too much mystery about what syntax to use. Just for example, I was trying to find out where the “base_learning_rate” was defined… it was somewhat hidden in an early execution cell among the test code… Also, if you go through the API guide, under tf.keras.metrics, it gives some examples that show metrics done with this line of code: m = tf.keras.metrics.Accuracy(), but in the end you had to figure out (somehow) that the proper syntax uses ‘accuracy’ within “[ ]” brackets.

Overall, the concepts of Transfer learning were obscured by the stress of trying to figure out the proper syntax from the ridiculously overcomplicated documentation. The assignment made everything sound a lot more complicated than it really was. And by the way, what ever happened to the practice of telling how many lines of code?

2 Likes

I receive the same error,
" The first argument to Layer.call must always be passed."
I have defined
x = data_augmenter()(inputs)
x = preprocess_input(x)
How did you solve it?
@paulinpaloalto could you please help me?

You are implementing the alpaca_model here and the data augmenter is passed in as a function called data_augmentation, right? It is programmable which augmentation function is to be used here, so what you have done is to “hard-code” the value by ignoring the passed parameters and directly calling data_augmenter. That may work in this specific case, because that is what is actually passed in this test case, but what if the grader passes a different augmentation function?

The correct solution is to just use the parameter function that you are given:

x = data_augmentation(inputs)

1 Like

The function name is defined as data_augmenter() but it returns data_augmentation.
I used x = data_augmentation(inputs), but still has the same error.

ValueError Traceback (most recent call last)
in
----> 1 model2 = alpaca_model(IMG_SIZE, data_augmentation)

in alpaca_model(image_shape, data_augmentation)
44
45 # create a prediction layer with one neuron (as a classifier only needs one)
—> 46 prediction_layer = tfl.Dense(units=1, activation=‘linear’)()
47
48 ### END CODE HERE

/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in call(self, *args, **kwargs)
914 # not to any other argument.
915 # - setting the SavedModel saving spec.
→ 916 inputs, args, kwargs = self._split_out_first_arg(args, kwargs)
917 input_list = nest.flatten(inputs)
918

/opt/conda/lib/python3.7/site-packages/tensorflow/python/keras/engine/base_layer.py in _split_out_first_arg(self, args, kwargs)
2978 else:
2979 raise ValueError(
→ 2980 ‘The first argument to Layer.call must always be passed.’)
2981 return inputs, args, kwargs
2982

ValueError: The first argument to Layer.call must always be passed.

But the error is not being thrown by the data augmentation line, right? Where in the trace you show does it say anything about data augmentation? The error is thrown on this line:

prediction_layer = tfl.Dense(units=1, activation=‘linear’)()

The problem there is that they are going to later call prediction_layer in the template code as a function. So you only want to “instantiate” the dense layer on the line that is throwing, but you are both instantiating it and calling it, so that the LHS of that assignment statement would have been a tensor instead of a function, if you had called it correctly. That’s what the actual error message is complaining about. Then it tries to call it like this in the template code:

outputs = prediction_layer(x)

Thank you so much!
I fixed it

1 Like

IMO There is a bug in the signature of this function alpaca_model
Because the arg is actually passed as a positional arg, in the following cell, the bug is hidden.
If it was not actually passed, data_augmentation would be set to a sequential model instead of a function
The correct signature should be
def alpaca_model(image_shape=IMG_SIZE, data_augmentation=data_augmenter):

But a sequential model is a function, right?

The function signature as it is defined is this:

def alpaca_model(image_shape=IMG_SIZE, data_augmentation=data_augmenter()):

It is not a positional argument: it is a “named parameter” with a default value, which happens to be the return value of the data_augmenter function which is a function, right? But the way python works is you can treat it as a positional parameter, even though it is named. And they invoke it with the previously defined global value data_augmentation which happens also to be a function, right? The return value of data_augmenter is a function.

But if they omitted that parameter, the result would be the same, right?