Векторизованный способ перетасовки заданного тензора с помощью pytorch - PullRequest
1 голос
/ 11 марта 2020

У меня есть тензор A формы (1,12,2,2) следующим образом:

  ([[[[1., 3.],
      [9., 11.],

     [[ 2.,  4.],
      [10., 12.]],

     [[ 5.,  7.],
      [13., 15.]],

     [[ 6.,  8.],
      [14., 16.]],

     [[17., 19.],
      [25., 27.]],

     [[18., 20.],
      [26., 28.]],

     [[21., 23.],
      [29., 31.]],

     [[22., 24.],
      [30., 32.]],

     [[33., 35.],
      [41., 43.]],

     [[34., 36.],
      [42., 44.]],

     [[37., 39.],
      [45., 47.]],

     [[38., 40.],
      [46., 48.]]]])

Я хочу перетасовать его, используя pytorch, чтобы получить следующий тензор B формы (1,3 , 4,4):

tensor([[[[ 1.,  6.,  3.,  8.],
          [21., 34., 23., 36.],
          [ 9., 14., 11., 16.],
          [29., 42., 31., 44.]],

         [[ 2., 17.,  4., 19.],
          [22., 37., 24., 39.],
          [10., 25., 12., 27.],
          [30., 45., 32., 47.]],

         [[ 5., 18.,  7., 20.],
          [33., 38., 35., 40.],
          [13., 26., 15., 28.],
          [41., 46., 43., 48.]]]])

Я реализовал это, используя два цикла for следующим образом:

B = torch.zeros(1,3,4,4, dtype=torch.float)
ctr = 0
for i in range(2):
    for j in range(2):
        B[:,:,i:4:2,j:4:2] = A[:,ctr:ctr+3,:,:]
        ctr = ctr+3

Я ищу любой способ реализовать это в векторизованном виде в Pytorch без этих петель. Может быть, использовать такие функции, как .permute(), et c.

Ответы [ 2 ]

4 голосов
/ 11 марта 2020

Это сделает трюк

B = A.reshape(2,2,3,2,2).permute(2,3,0,4,1).reshape(1,3,4,4)
1 голос
/ 12 марта 2020

Просто обобщение вышеприведенного решения для любого фактора повышающей дискретизации 'r', как в пиксельной случайной последовательности.

B = A.reshape(-1,r,3,s,s).permute(2,3,0,4,1).reshape(1,3,rs,rs)

Здесь 's' - это пространственное разрешение каждого канала в 'A', а 'r' - это фактор повышения дискретизации. Для частного случая r = 2 и s = 2. Это решение должно работать для произвольных значений 'r' с соответствующим размером 'A'.

Так что для проблемы в руке s = 2, r = 2, и поэтому решение идет как

B = A.reshape(-1,2,3,2,2).permute(2,3,0,4,1).reshape(1,3,4,4)

, как отправлено @ ddoGas

Аналогично, если 'A' был размером (1, 192, 356, 532) и желал повысить частоту с помощью r = 8 до

B = A.reshape(-1,8,3,356,532).permute(2,3,0,4,1).reshape(1,3,2848,4256)
...