Neural style transfer, programming exercise, compute_content_cost reshape confusion

Here is the experiment that I described. First the function:

# routine to generate a telltale 4D array to play with
def testarray(shape):
    (d1,d2,d3,d4) = shape
    A = np.zeros(shape)

    for ii1 in range(d1):
        for ii2 in range(d2):
            for ii3 in range(d3):
                for ii4 in range(d4):
                    A[ii1,ii2,ii3,ii4] = ii1 * 1000 + ii2 * 100 + ii3 * 10 + ii4 

    return A

So you can see that the value of any position in the tensor is the coordinates in order. Meaning that A[1,2,3,4] = 1234.

Now run that as follows:

# test case for Art Transfer exercise C4W4A2
A = testarray((1,4,2,3))
# The correct way
Ashape1 = np.transpose(np.reshape(A,[-1,3]))
# The wrong way
Ashape2 = np.reshape(A, [3,-1])
# Another correct way to do it
Ashape3 = np.reshape(np.transpose(A, [0,3,1,2]), [3,-1])
    
np.set_printoptions(suppress=True)
print("Ashape1.shape = " + str(Ashape1.shape))
print(Ashape1)

print("Ashape2.shape = " + str(Ashape2.shape))
print(Ashape2)

print("Ashape3.shape = " + str(Ashape3.shape))
print(Ashape3)

And here is the result you get:

Ashape1.shape = (3, 8)
[[  0.  10. 100. 110. 200. 210. 300. 310.]
 [  1.  11. 101. 111. 201. 211. 301. 311.]
 [  2.  12. 102. 112. 202. 212. 302. 312.]]
Ashape2.shape = (3, 8)
[[  0.   1.   2.  10.  11.  12. 100. 101.]
 [102. 110. 111. 112. 200. 201. 202. 210.]
 [211. 212. 300. 301. 302. 310. 311. 312.]]
Ashape3.shape = (3, 8)
[[  0.  10. 100. 110. 200. 210. 300. 310.]
 [  1.  11. 101. 111. 201. 211. 301. 311.]
 [  2.  12. 102. 112. 202. 212. 302. 312.]]

So we have 3 as the first dimension in all three cases, but read across each row and look at the last dimension of the values. In Ashape1 and Ashape3, they are consistent across the row: 0 for the first row, 1 for the second row and 2 for the third row.

But look at Ashape2: the rows are all a mix of elements from different channels, right? That’s what I meant by “scrambling” the data.

Note that I did all the above in numpy, just because I already had the numpy implementation available from the earlier “flatten” thread. But if you rewrite this using TF, you’ll get exactly the same behavior.

3 Likes