More reshaping fun - let's go 4D!

(perceptilabs-gpu 0.11.7)

Here I am exploring and presenting perceptilabs reshaping capabilities using as local data perceptilabs demo shape recognition images of 224 x 224 x 3 (i.e. RGB)

Note the error message associated with reshape 3_1_2 (which is a copy of 3_1) - perceptilabs thinks it should add a dimension… that was in fact because the permutation was specified by accident as Z, Y, X = 3, 224, 2124, but not having enough data is no excuse for trying to escape into the 4th dimension :wink: (I didn’t think that was possible :wink: )

I couldn’t tell which node thinks it is missing an input.

Final question: my intuition and combinatorial abilities failed me: what are the settings to undo 3_1 - it merely swapped Z & X but doing that again doesn’t seem to work.

Also, probably repeating myself here, it would be helpful to label the reshape nodes with the permutation details as X, Z, Y (224, 3, 224) or similar, and more space for numbers in the settings of the reshape would have made the entry error more visible (also - tab between fields? frustrating to have to click; and related to another discussion, immediately applying changes to individual values when consistency of the set matters is undesirable.)

UPDATE the permutation of 3_1_2 is X, Y, Z -> Z, Y, Z, i.e. the permutation is (2, 1, 0)

I tested applying this permutation twice with my own code and I got back what I started with - as (previously) expected. Where are we diverging?

import tensorflow as tf
import numpy as np
import pandas as pd # pandas dataframe printing is nice

# make sure pandas dataframe printing will work with full mnist size of side = 28
pd.options.display.max_columns = 28
pd.options.display.width = 400

def pixelZ(label, size):
    # I don't like appending in general, but these arrays are small
    '''make a Z shape of label in cells of square grid - simplest way to see rotation & reflection of some permutations'''
    resultM =[]
    rng = range(1, size+1)
    for i in rng:
        for j in rng:
            if i == 1 or i == size:
                resultM = resultM + ['r' + str(i) + '_' + label]
            else:
                if size - j + 1 == i:
                    resultM = resultM + ['r' + str(i) + '_' + label]
                else:
                    resultM = resultM + ["   "]
    return(resultM)

mnist_side = 5
mnistredZ = pixelZ('R', mnist_side)
mnistgreenZ = pixelZ('G', mnist_side)
mnistblueZ = pixelZ('B', mnist_side)
mnistrgbZ = mnistredZ + mnistgreenZ + mnistblueZ
mnistrgbZChannels = tf.reshape(mnistrgbZ,[3, mnist_side, mnist_side])

def showPermEffect(perm, tensorToPerm):
    '''It is assumed that we are working with a rank 3 tensor'''
    with tf.Session() as sess:
        # .decode('UTF-8') doesn't work for numpy.ndarray; see https://stackoverflow.com/questions/40388792/how-to-decode-a-numpy-array-of-encoded-literals-strings-in-python3-attributeerr
        # use .astype('U13') instead
        # use pandas DataFrame to get nice matrices
        um1 = sess.run(tensorToPerm)
        print ('Before transpose, shape = ', um1.shape)
        [print(pd.DataFrame(um1.astype('U13')[m]), '\n') for m in range(um1.shape[0])]
        
        permutedTensor = tf.transpose(tensorToPerm, perm)
        um2 = sess.run(permutedTensor)
        print ('\nAfter permutation with', perm, ', shape = ', um2.shape)
        [print(pd.DataFrame(um2.astype('U13')[m]), '\n') for m in range(um2.shape[0])]
        
        rePermutedTensor = tf.transpose(permutedTensor, perm)
        um3 = sess.run(rePermutedTensor)
        print ('\nAfter permutation again with', perm, ', shape = ', um3.shape)
        [print(pd.DataFrame(um3.astype('U13')[m]), '\n') for m in range(um3.shape[0])]

permutation = list((2, 1, 0))
showPermEffect(permutation, mnistrgbZChannels)

Output

Before transpose, shape =  (3, 5, 5)
      0     1     2     3     4
0  r1_R  r1_R  r1_R  r1_R  r1_R
1                    r2_R      
2              r3_R            
3        r4_R                  
4  r5_R  r5_R  r5_R  r5_R  r5_R 

      0     1     2     3     4
0  r1_G  r1_G  r1_G  r1_G  r1_G
1                    r2_G      
2              r3_G            
3        r4_G                  
4  r5_G  r5_G  r5_G  r5_G  r5_G 

      0     1     2     3     4
0  r1_B  r1_B  r1_B  r1_B  r1_B
1                    r2_B      
2              r3_B            
3        r4_B                  
4  r5_B  r5_B  r5_B  r5_B  r5_B 


After permutation with [2, 1, 0] , shape =  (5, 5, 3)
      0     1     2
0  r1_R  r1_G  r1_B
1                  
2                  
3                  
4  r5_R  r5_G  r5_B 

      0     1     2
0  r1_R  r1_G  r1_B
1                  
2                  
3  r4_R  r4_G  r4_B
4  r5_R  r5_G  r5_B 

      0     1     2
0  r1_R  r1_G  r1_B
1                  
2  r3_R  r3_G  r3_B
3                  
4  r5_R  r5_G  r5_B 

      0     1     2
0  r1_R  r1_G  r1_B
1  r2_R  r2_G  r2_B
2                  
3                  
4  r5_R  r5_G  r5_B 

      0     1     2
0  r1_R  r1_G  r1_B
1                  
2                  
3                  
4  r5_R  r5_G  r5_B 


After permutation again with [2, 1, 0] , shape =  (3, 5, 5)
      0     1     2     3     4
0  r1_R  r1_R  r1_R  r1_R  r1_R
1                    r2_R      
2              r3_R            
3        r4_R                  
4  r5_R  r5_R  r5_R  r5_R  r5_R 

      0     1     2     3     4
0  r1_G  r1_G  r1_G  r1_G  r1_G
1                    r2_G      
2              r3_G            
3        r4_G                  
4  r5_G  r5_G  r5_G  r5_G  r5_G 

      0     1     2     3     4
0  r1_B  r1_B  r1_B  r1_B  r1_B
1                    r2_B      
2              r3_B            
3        r4_B                  
4  r5_B  r5_B  r5_B  r5_B  r5_B