@paulinpaloalto I am stuck. When I do the calculation by hand, the result I get agrees with my code, but when I run the model it doesn’t apply the style correctly. For example, it doesn’t see the red colored splotches that Monet has. So I think my compute_layer_cost is not right.
There are two “Additional Hints” sections about “unrolling” and “reshaping”. Try reading the one before the compute_content_cost section and then the shorter one before the compute_layer_style_cost section. The key point is that you can’t just directly reshape the inputs into the end shape that you want: you need to do a transpose as part of the process so that the “channels” dimension of the data is preserved. There are several ways (orders in which) to accomplish this: transpose first and then reshape or reshape first and then transpose. Obviously the dimensions won’t be the same on the reshape between the two cases.
In order to understand the reason for this, you need to delve into the details of how reshape actually works. There was a similar situation in Course 1 Week 2 Logistic Regression in which we needed a transpose in order to get the results to be correct when we “flattened” the 4D image tensor into a matrix. Here’s a thread which explains the background there and the same fundamental ideas apply here as well. The key point is that you need to preserve the “samples” dimension of the data during the reshape: if you don’t, then you end up scrambling the data .
Update: here’s a more recent thread that shows a very specific example for the given case here of the right and wrong ways to do the reshaping in order to preserve the “channels” dimension.
The error is in the two lines of code where you reshape the matrices. The simplest way of reshaping produces matrices of the correct shape but with the elements in the wrong order
Hi,
I’m pretty sure I’ve done things in the right order (vis-a-vis first reshape then transpose). The cost ends up being off by a factor of 10… I’ve re-read my code and tried variations on the calculation… I always get the same result, so it must be that I’ve reshaped it wrong (>but it looks like the right steps to me… !) Please advise:
Your reshape and transpose logic looks right to me. My guess is that your problem is to do with the way you used TF functions to compute the scaling factor that includes only integer types. The type coercion rules in TF are different than base python and numpy and I think that gets you in trouble. Here’s a thread which demonstrates one version of the issue. Please have a look at that and see if that sheds any light. Let us know one way or the other!
Oh, sorry, I wasn’t reading your code closely enough the first time. That’s not the problem. The problem is that the inputs for that computation are supposed to the Gram Matrices, right? But you are using the reshaped/transposed tensors that were the inputs to compute the Gram Matrices.
Thank you SOOO much (for both your quick replies, and for the thread before…even though the type coercion wasn’t the problem, I learned a lot from both your answers). Hugely appreciated!
I’m so glad that it was helpful. I learned a couple of things in the process as well: I took your implementation and tried it to make sure I understood what was happening. I’d never seen the TF math squared_difference function, so I also wanted to play with that. What I also learned was that it looks like TF has done a fix similar to the python 3.x fix to the \frac {1}{m} problem. So when I tried a couple of different ways to fix what I thought was your problem with integer type coercion, it didn’t change the answer. So I had a scientific theory and then I ran the experiment and the experiment failed. So I needed a new theory! Then I went back and looked at the code more carefully and saw what I missed the first time. Science!
I fixed my unrolling logic based on the updated thread you shared, but I’m still getting the wrong answer.
I wonder if there might be something wrong with my loss function implementation? How do I implement the double summation? I had originally applied two layers of tf.sum_reduce with the axis referencing each of the n_C dimensions in order to represent the i and j in the loss equation, but I didn’t realize that tf.sum_reduce reduces the tensor by a rank, so the second dimension is no longer present for the second layer of tf.sum_reduce. Unless it’s essentially the same implementation as exercise 1 for the content cost (only one tf.sum_reduce and axis=None)?
The double summation is just over the two axes of the resultant tensor after the subtract and square elementwise operations, so you only need one “reduce_sum” with no axis. It will work if you do the axes individually, but why write more code than you need? It works the same as np.sum in that regard. You can select the axis or axes if you need to and you can even use “keepdims”, but neither is required in this case.
If that still doesn’t give the correct answer, then there are other things to check. E.g. that you’re using the Gram Matrices as the inputs to the final cost and that you’ve got the order of operations right.
Thank you, I finally got it! I keep forgetting that exponentiation in Python is ‘**’ instead of ‘^’ like in other languages. I had rewritten each equation so many times and in different ways trying to figure out what the problem was.