Course 4 Week 1 : a_slice_prev wrong shape

I am having trouble with the shape of a_slice_prev. My A_prev_pad is this (2, 7, 9, 4). But my a_slice_prev is (2,2,0).

(2, 7, 9, 4)
(7, 9, 4)
Vert start: 0
Vert end: 2
horiz start: 0
horiz end: 2
(2, 2, 0)
ValueError                                Traceback (most recent call last)
<ipython-input-31-7e580406a9e8> in <module>
      6                "stride": 2}
----> 8 Z, cache_conv = conv_forward(A_prev, W, b, hparameters)
      9 z_mean = np.mean(Z)
     10 z_0_2_1 = Z[0, 2, 1]

<ipython-input-30-cc64ce5670ee> in conv_forward(A_prev, W, b, hparameters)
     88                     weights = W[0:2,:,:]
     89                     bias = b[0:2,:,:]
---> 90                     z[i,h,w,c]= conv_single_step(a_slice_prev,weights,bias)

<ipython-input-24-3878716d50ca> in conv_single_step(a_slice_prev, W, b)
     23     # Z = None
---> 25     s = np.multiply(a_slice_prev,W)
     26     Z = np.sum(s)
     27     Z = Z + float(b)

ValueError: operands could not be broadcast together with shapes (2,2,0) (2,3,4,8)```

I am abit confused with the array splicing and making it work. I was hoping to get some hints.

Yes, it looks like there are a number of problems with the way you are “slicing” the various arrays. Before we get to the A_slice_prev, also note that the W you are passing down to conv_single_step is also the wrong shape: it should be 3 x 3 x 4, because the filters are 3 x 3 and there are 4 channels in the input. Note that W and b both have 4 dimension, but you are “slicing” them on the first dimension and then only specifying 3 dimensions, so you end up getting “all” of the last dimension, which is the “channels” dimension. That exactly the opposite of what you need: You want to slice it by selecting all of the first 3 dimensions and then only the current value of the output channel (the last dimension), right?

Your A_prev_pad is the correct shape, but then the question is how you “step” through that. Note that the loop index values cover the output space, right? So that will be 2 x 3 x 4 x 8 and you must touch every value in the output space. Then for each combination of i, h, w and c, you must compute where that comes from in the input space. Don’t forget to include the stride value in your computation of vert_start and horiz_start. It also looks like your vert_end and horiz_end values are wrong. Remember that indexing in python is 0-based. If I want to extract the first 3 values from an array, the indices are 0, 1 and 2, but the “range” for that is 0:3, right? The last index is not included in the range.

Also note that it looks like you hard-coded some ranges as 0:2 in the code that we can see in the exception trace you showed. Just generally speaking, it’s a big mistake to “hard-code” numbers like that, unless you really have no choice.

Hi, thank you for the response. I do understand what numbers I need for the correct answer but I’m still confused on the slicing. What exactly in the array am I trying to get sliced? I have to make it 3 x 3 x 4 so I need something that will give


as you mentioned selecting all of the first 3 then only current value for the output channel.

Also for the vert_end and horiz_end, I am iterating the stride in this fashion

for h in range(0,n_H,stride):

for w in range(0,n_W,stride):

I was wondering if this is ok, as for range we have rane(start,end,step)

I think W is OK.

And, here is an overview of convolutions in this assignment.

Key point here is, all iteration indexes should be based on the target size, n_H, n_W, and n_C.
If you set the step (stride) in iterations, then, the location to store the result of convolutions may not be correct. In stead, as you see in the above figure, you should set the starting point (vert_start, horiz_start) and end point with considering the stride and filter size in the source side, A_prev_pad.

I agree with Nobu: the way you are “slicing” W is correct. As you say, you just want the current output channel and all of the other full dimensions.

For the h and w loops, it is a mistake to include the stride in the loop indices. That was the point I was making about the loops being over the output space and you have to touch every position. You only use the stride to compute the vert_start and horiz_start values in the input space. Nobu’s diagrams also are an excellent way to “get” that aspect of how this works. As usual, a picture is worth a lot of words :nerd_face:

Hello, thank you for the response. The graphic does help but I am still struggling with slicing for the other test. The other test I get these dimensions and values:

Shape of A_prev_pad(2, 17, 19, 4)
Shape of a_prev_pad(17, 19, 4)
Vert start: 0
Vert end: 3
horiz start: 0
horiz end: 3
Shape of a_slice_prev(3, 3, 4)
Shape of weights(5, 5, 4)
Shape of bias(1, 1, 1)

Here I can see my a_slice_prev shape is different then the weights. I think the a_slice_prev is the issue. I tried to slice it based on what was given in the hint of the assignment:

a_slice_prev = a_prev_pad[vert_start:vert_end,horiz_start:horiz_end,:]

And here is how I interpreted the striding over all output values:

[requested remove]

The error I’m getting is still a value error, with unbroadcastable operands.

I will check in detail shortly, but with the first look, I have one question.

vert_end = vert_start + 3

Where “3” is from ? As you see in my graphic, it must be a filter size, which is passed from a caller. You can not hardcode it.

Others will follow shortly.

Ahh ok that is my bad. I was under the impression that the assignment was for a specific filter size. I think this confusion may have come from the fact the hint showed 2x2 as an example. After changing it to “f” filter size, the code passed both tests.

Z's mean =
Z[0,2,1] =
 [-2.17796037  8.07171329 -0.5772704   3.36286738  4.48113645 -2.89198428
 10.99288867  3.03171932]
cache_conv[0][1][2][3] =
 [-1.1191154   1.9560789  -0.3264995  -1.34267579]
First Test: All tests passed!
Second Test: All tests passed!

Thank you for your help and insight!

Great. !

One thing that I may want to ask is,
Posting (even part of) code is not recommended. Could you please remove your code ?
Traceback, log, print output,… those are OK. Just remove a block of “for h in range ....”

Hi, sorry about that, I just wanted to be clearer. I have removed what you requested to.

Not to belabor the point, but you had been warned :nerd_face: