Week 1 Assignment 1 pool_forward

Interesting. It’s a good point that my theory about the reversing of vert and horizontal would cause errors in the stride = 1 case as well, so that can’t be it. FWIW I added the equivalent print statements and I get the same results you show.

Hmmmmm, more thought required.

2 Likes

Hi there.

I am experiencing a somewhat similar situation that has been puzzling me for several days now. I have added several print statements in my attempt to debug. I can confirm the following:
h for height is in the Vertical statement, w for width in Horizontal. Stride factored in.
a_prev_slice has the correct number of dimensions in the right order.
both cases are the right shape and the first column values are correct in each case.
printing horiz and vert start and end within the loop shows the correct movement of a 3 x 3 shape in case 1, from 0,0 1,0 2,0 0,1 1,1 2,1 0,2 1,2 2,2 coordinates for the top left position.
I attach the case 1 traceback and case 2 screen grab.

case 2

I also printed A.shape within the loop
At first glance it remains consistent in both cases: 2, 3, 3, 3 in case 1 and 2, 2, 2, 3 in case 2, however after the mean is computed in case 1 it begins to change shape (in the later channels?), first to 2, 2, 3, 3 then 4, 1, 3, 4 and finally 2, 4, 4, 3

I doubt if this relates to my issue.
I have exhausted all the variations in the code that I can think of.
Please advise

The shapes should stay the same across all the channels. The stride logic looks the same as for the conv_forward function previously. Note that the one significant difference in how things work for pooling is that pooling happens “per channel”, not across the channels as with convolutions.

Why would the shapes change as you progress through the loops with a given test case? That would be the first question to answer (assuming I’m not just misinterpreting what you are describing :scream_cat:).

Hi Paul.

I have:
retrieved the 4 dimensions from the input shape

retrieved the 2 hyperparameters from the hparameters dictionary

defined n_H, n_W and n_C as per the Exercise 4 instructions

initialised the 4 dimensions of A

looped through the training examples (the first dimension)

looped through the vertical axis of the output volume (the second dimension), factoring in the stride and adding f to define the end coordinate

looped through the horizontal axis of the output volume (the third dimension), factoring in the stride and adding f to define the end coordinate

looped over the channels of the output volume (the fourth dimension)

defined the current slice on the ith training example of A_prev using a term for “everything”, for the vertical start and end, for the horizontal start and end, and for channel c as given in the instructions.

the code supplied for case 1 gives:
A_prev = np.random.randn(2, 5, 5, 3) which correspond to the 4 dimensions
hparameters = {“stride” : 1, “f”: 3}

a slice with a “f” of 3 has 3 positions in the vertical if there is a “stride” of 1
it also has 3 positions in the horizontal

2 training examples x 3 vertical positions x 3 horizontal positions x 3 channels =
54 values for I in the range (m)

if I then print A.shape I get 54 rows of A.shape: (2, 3, 3, 3) – these are in a slider window and I know of no way to confirm there are 54, but this would seem logical.

these are followed by:
mode = max
A.shape = (2, 3, 3, 3)
A[1, 1] =
[[1.96710175 0.90159072 2.10025514]
[1.96710175 0.90159072 1.65980218]
[1.62765075 1.6924546 1.65980218]]

the first three (vertical) values are correct

this is followed by another 54 rows of A.shape: (2, 3, 3, 3), followed by:
mode = average
A.shape = (2, 3, 3, 3)
A[1, 1] =
[[ 0.03158753 0.0066912 -0.06992018]
[ 0.27774273 -0.10450644 -0.07378899]
[ 0.07921582 0.16487069 0.06209026]]

This is followed by (I am guessing) 162 further rows of A.shape, but now the shape changes periodically

The 54 values for I in the range that I have defined are the right shape. I do not know what the later “162” rows are referring to.

There do not seem to be many parameters to adjust. If I remove the “stride” from the vertical and horizontal looping, the A[1, 1] numbers change, as expected. These seem to be the only lines of code that influence the A[1, 1], but, with “stride” factored in, they seem to be correct.

Am I missing something?

As I mentioned in my previous reply, the shape of the slice should not change in a given test case. I’m worried by your reference to “everything” here:

When you are extracting the “current slice” of A_prev, there should be no “everything” dimensions. You have a specific value for the samples dimension, specific ranges for h and w and a specific channel, right?

I added the following code to my innermost loop right after the line that does the “slicing”:

 if i + vert_start + horiz_start + c == 0:
     print(f"a_prev_slice.shape {a_prev_slice.shape}")
     a_prev_shape = a_prev_slice.shape
 if a_prev_slice.shape != a_prev_shape:
     print(f"slice shape changed! {a_prev_shape} != {a_prev_slice.shape}")

You’ll have to fiddle with the indentation to get that to fit (I had to remove some indentation to get it to format here). But you see what that does, right? When I run the test cell with that code in place, the second “if” never triggers and here’s what I see for the stride = 1 test cell:

a_prev_slice.shape (3, 3)
mode = max
A.shape = (2, 3, 3, 3)
A[1, 1] =
 [[1.96710175 0.84616065 1.27375593]
 [1.96710175 0.84616065 1.23616403]
 [1.62765075 1.12141771 1.2245077 ]]
a_prev_slice.shape (3, 3)
mode = average
A.shape = (2, 3, 3, 3)
A[1, 1] =
 [[ 0.44497696 -0.00261695 -0.31040307]
 [ 0.50811474 -0.23493734 -0.23961183]
 [ 0.11872677  0.17255229 -0.22112197]]
a_prev_slice.shape (2, 2)
a_prev_slice.shape (5, 5)
a_prev_slice.shape (2, 2)
a_prev_slice.shape (2, 2)
All tests passed!

Note that those last 4 lines are from the additional test cases in the public_tests.py file, which have different inputs.

Thank you Paul.

All tests passed. I had an incorrect first term in my “a_prev_slice =” code.

With the correct code my result is identical to the expected result.

With your code added after the “a_prev_slice =” line the result is identical to yours, above.

If I substitute your code with;
print("A.shape: ", A.shape)
A.shape runs on to the other shapes previously mentioned.

I have removed print("A.shape: ", A.shape) from my code.

Many thanks.

1 Like

It’s great news that you found the solution! Thanks for confirming. Onward! :nerd_face:

1 Like

That was a good hint cuz I spent more than 30 min to figure out why I am getting wrong results!
Please make sure you calculate pooling for each individual channel, i.e., n_C!
Cheers,

@paulinpaloalto I have worked on this for over 3 hours now and I am very confused by what is happening. First of all, it seems that the stride parameter is changed somewhere to 1 in my code, and then even if I hardcode it to 2, it wouldn’t run. I am completely baffled and do not know what to do. Can you have a look at the notebook? Thank you very much.

The mentors do not have the superpower to directly examine anyone else’s notebooks. Please click my name and then “Message” to send me a private message with your notebook file (ipynb) attached.

Hi, @paulinpaloalto! I have managed to solve this issue. The funny thing is that I have done a lot of debugs and some of them might have triggered some state of the variable to change. After I have refreshed the workspace, then everything is fine.