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.