如何在tensorflow中进行置换转置操作?

21
文档中得知:
转置a。根据perm重新排列维度。
返回的张量的维度 i 将对应于输入维度perm[i]。如果未给出perm,则设置为(n-1...0),其中 n 是输入张量的等级。因此,默认情况下,此操作在二维输入张量上执行常规矩阵转置。
但对于我来说还不太清楚我应该如何切片输入张量。例如,从文档中也可以看到:
tf.transpose(x, perm=[0, 2, 1]) ==> [[[1  4]
                                      [2  5]
                                      [3  6]]

                                     [[7 10]
                                      [8 11]
                                      [9 12]]]

为什么perm=[0,2,1]会产生一个1x3x2的张量?

经过一些试错后:

twothreefour = np.array([ [[1,2,3,4], [5,6,7,8], [9,10,11,12]] , 
                        [[13,14,15,16], [17,18,19,20], [21,22,23,24]] ])
twothreefour

[out]:

array([[[ 1,  2,  3,  4],
        [ 5,  6,  7,  8],
        [ 9, 10, 11, 12]],

       [[13, 14, 15, 16],
        [17, 18, 19, 20],
        [21, 22, 23, 24]]])

如果我进行转置:

fourthreetwo = tf.transpose(twothreefour) 
with tf.Session() as sess:
    init = tf.initialize_all_variables()
    sess.run(init)
    print (fourthreetwo.eval())
我把一个 4x3x2 变成了 2x3x4,这听起来很合理。

[out]:

[[[ 1 13]
  [ 5 17]
  [ 9 21]]

 [[ 2 14]
  [ 6 18]
  [10 22]]

 [[ 3 15]
  [ 7 19]
  [11 23]]

 [[ 4 16]
  [ 8 20]
  [12 24]]]

但是,当我使用perm参数时,我不确定我实际得到了什么输出:

twofourthree = tf.transpose(twothreefour, perm=[0,2,1]) 
with tf.Session() as sess:
    init = tf.initialize_all_variables()
    sess.run(init)
    print (threetwofour.eval())
[输出]:
[[[ 1  5  9]
  [ 2  6 10]
  [ 3  7 11]
  [ 4  8 12]]

 [[13 17 21]
  [14 18 22]
  [15 19 23]
  [16 20 24]]]

为什么perm=[0,2,1]从一个2x3x4的矩阵返回一个2x4x3的矩阵?

再试一次,使用perm=[1,0,2]

threetwofour = tf.transpose(twothreefour, perm=[1,0,2]) 
with tf.Session() as sess:
    init = tf.initialize_all_variables()
    sess.run(init)
    print (threetwofour.eval())
[输出]:
[[[ 1  2  3  4]
  [13 14 15 16]]

 [[ 5  6  7  8]
  [17 18 19 20]]

 [[ 9 10 11 12]
  [21 22 23 24]]]
perm=[1,0,2]参数将一个形状为2x3x4的张量根据数组形状中的元素进行转置,返回一个形状为3x2x4的张量。
_size = (2, 4, 3, 5)
randarray = np.random.randint(5, size=_size)

shape_idx = {i:_s for i, _s in enumerate(_size)}

randarray_t_func = tf.transpose(randarray, perm=[3,0,2,1]) 
with tf.Session() as sess:
    init = tf.initialize_all_variables()
    sess.run(init)
    tranposed_array = randarray_t_func.eval()
    print (tranposed_array.shape)

print (tuple(shape_idx[_s] for _s in [3,0,2,1]))

[out]:

(5, 2, 3, 4)
(5, 2, 3, 4)
2个回答

37

我认为perm是对维度进行重排。例如perm=[0,2,1]是指将dim_0改为dim_0,将dim_1改为dim_2,将dim_2改为dim_1。因此对于一个二维张量来说,perm=[1,0]就是矩阵的转置。这回答了你的问题吗?


我认为是这样,但我不确定。如果您可以链接到存储库中的特定代码行或更清晰的文档,那将非常有帮助!提前感谢! - alvas
我认为文档中的示例已经很好地说明了发生了什么。维度0是内部矩阵,它们不会受到置换的影响;维度1是内部矩阵的行,维度2是列,它们会被置换交换。因此,每个内部矩阵的第1行将转移到同一内部矩阵的第1列。这样说清楚了吗? - maxymoo
读起来有点混乱,但我通过尝试用更多类似于我发布的代码的示例来说服自己,最终明白了。 - alvas
我认为混淆的原因在于认为转置只是一个翻转(从M x N到N x M); 然而在这里它是排列(移动维度)。[2,6,8]与perm=[2,1,0] -> [8,6,2]和[1,3,5,7]与perm=[3,0,1,2] -> [7,1,3,5]。 - Kenan

6
A=[2,3,4] matrix, using perm(1,0,2) will get B=[3,2,4].

解释:

Index=(0,1,2)
A    =[2,3,4]
Perm =(1,0,2)
B    =(3,2,4)  --> Perm 1 from Index 1 (3), Perm 0 from Index 0 (2), Perm 2 from Index 2 (4) --> so get (3,2,4)

7
请添加一些解释。 - Mr Mush

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接