Course 4 Week 1 assignment 1 exercise 5 conv_backward issue

Dear community,

I have an issue with my code for the 5th exercise. Here is my error message:

UFuncTypeError Traceback (most recent call last)
in
10
11 # Test conv_backward
—> 12 dA, dW, db = conv_backward(Z, cache_conv)
13
14 print(“dA_mean =”, np.mean(dA))

in conv_backward(dZ, cache)
104 a_slice = a_prev_pad[c]
105
→ 106 da_prev_pad[vert_start:vert_end, horiz_start:horiz_end] += W[:,:,:,c] * dZ[i, h, w, c]
107 dW[:,:,:,c] += a_slice * dZ[i, h, w, c]
108 db[:,:,:,c] += dZ[i, h, w, c]

UFuncTypeError: Cannot cast ufunc ‘add’ output from dtype(‘float64’) to dtype(‘int64’) with casting rule ‘same_kind’

Thanks in advance!
Olivier

My guess is that error means you somehow initialized da_prev_pad to have integer values. Using an “in place” operator like “+=” or “-=” does not work if the LHS is an integer type and the RHS is a floating point time. Or course in python 0 is not the same thing as 0. with the period there.

1 Like

Thank you so moch for your quick reply! Another question: I don’t understand this hint below:

dW[:,:,:,c] \mathrel{+}= a_slice * dZ[i, h, w, c]

What does “\mathrel{+}=” means?

I think that is just a “rendering” error for some LaTeX formatting commands. They really just mean the “+=” operator there.

I still have some issues with my code, here is my error message:

→ 107 dW[:,:,:,c] = dW[:,:,:,c] + a_slice * dZ[i, h, w, c]
108 db[:,:,:,c] = db[:,:,:,c] + dZ[i, h, w, c]
109

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

For the step : Initialize dA_prev, dW, db with the correct shapes, I used a series of np.arange > np.reshape, does that work? Thanks in advance.

What do you believe the shapes should be? What shapes are the actual values? Are they the same?

I believe the shapes should be (2, 3, 3) but I can’t calculate dZ’s since it is the result of the front prop.

What do you mean? The value of dZ is an input parameter to conv_backward, right? So it’s pretty easy to know the shape:

dZ.shape

But there are other ways. They give you A_prev, W, b and hparameters in the cache, right? From the dimensions of those, you could also calculate the shape of Z, which is the same as the shape of dZ.

The same goes for dA_prev, dW and db: they are the same shapes as their corresponding base objects. You initialize them to zeros, so no fancy reshapes should be required. If I have a matrix M and I want another matrix the same shape filled with zeros, I can just say:

Mzeros = np.zeros(M.shape)

Because np.zeros takes a tuple as the argument giving the shape you want.

1 Like

Hello Mr., I have another question here: for the padding of dA_prev, I have an error:

operands could not be broadcast together with remapped shapes [original->remapped]: (4,2) and requested shape (1,2)

What can I do?

There shouldn’t be anything tricky about the padding. It works the same way that it worked in conv_forward: you just call the zero_pad function that you already wrote with the appropriate arguments.

If that hint is not enough to get you there, then please show us a “copy/paste” of the full exception trace you are getting.

But with a bit more thought, note that you don’t have to actually pad anything in the back prop case. You are given dZ and A_prev as arguments and you’re computing dA_prev. But dA_prev is the same shape as A_prev, right?

Update: You work with the padded input objects for most of the logic, but then after all the loops at the end you need to extract just the portion that corresponds to the unpadded input objects. They give you hints in the comments about how to do that. More than a hint, really: they essentially write the code for you.

1 Like

Dear Mr., I finally got it! Thanks for your advice!