Реплицировать субтеноры в PyTorch - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть тензор image_features, имеющий форму torch.Size([100, 1024, 14, 14]). Мне нужно скопировать каждый субтенор (1024, 14, 14) 10 раз, получив тензор, имеющий форму torch.Size([1000, 1024, 14, 14]).

По сути, первые десять строк результирующего тензора должны соответствовать первой строке исходного, следующие десять строк результирующего тензора должны соответствовать второй строке исходного и т. Д. Если возможно, я не хочу создавать копию (каждый реплицированный субтензор может делить память с тензорным узлом, из которого он реплицируется), но это нормально для создания копии, если нет другого способа.

Как я могу это сделать?

Большое спасибо.

Ответы [ 2 ]

1 голос
/ 19 апреля 2019

Другой подход, который решит вашу проблему:

orig_shape = (100, 1024, 14, 14)
new_shape = (100, 10, 1024, 14, 14)
input = torch.randn(orig_shape) # [100, 1024, 14, 14]
input = input.unsqueeze(1) # [100, 1, 1024, 14, 14]
input = input.expand(*new_shape) # [100, 10, 1024, 14, 14]
input = input.transpose(0, 1).contiguous() # [10, 100, 1024, 14, 14]
input = input.view(-1, *orig_shape[1:]) # [1000, 1024, 14, 14]

Мы можем это проверить.

orig_shape = (2, 3, 4)
new_shape = (2, 5, 3, 4)
input = torch.randn(orig_shape)
print(input)
input = input.unsqueeze(1)
input = input.expand(*new_shape)
input = input.transpose(0, 1).contiguous()
input = input.view(-1, *orig_shape[1:])
print(input)

Фрагмент кода приводит к:

tensor([[[-1.1728,  1.0421, -1.0716,  0.6456],
     [-1.2214,  1.1484, -0.1436,  1.2353],
     [-0.4395, -0.9473, -0.1382, -0.9357]],

    [[-0.4735, -1.4329, -0.0025, -0.6384],
     [ 0.5102,  0.7813,  1.2810, -0.6013],
     [ 0.6152,  1.1734, -0.4591, -1.7447]]])

tensor([[[-1.1728,  1.0421, -1.0716,  0.6456],
     [-1.2214,  1.1484, -0.1436,  1.2353],
     [-0.4395, -0.9473, -0.1382, -0.9357]],

    [[-0.4735, -1.4329, -0.0025, -0.6384],
     [ 0.5102,  0.7813,  1.2810, -0.6013],
     [ 0.6152,  1.1734, -0.4591, -1.7447]],

    [[-1.1728,  1.0421, -1.0716,  0.6456],
     [-1.2214,  1.1484, -0.1436,  1.2353],
     [-0.4395, -0.9473, -0.1382, -0.9357]],

    [[-0.4735, -1.4329, -0.0025, -0.6384],
     [ 0.5102,  0.7813,  1.2810, -0.6013],
     [ 0.6152,  1.1734, -0.4591, -1.7447]]])
0 голосов
/ 19 апреля 2019

Вот один подход, использующий tensor.repeat(), который включает копирование данных:

# sample tensor for us to work with
In [89]: shp = (100, 1024, 14, 14)
In [90]: t = torch.randn(shp)

# number of desired repetitions
In [91]: reps = 10

# all the magic happens here
# 10 -> we wish to repeat the entries `reps` times along first dimension
# 1 -> we don't want to repeat along the rest of the dimensions
In [92]: rep_tensor = t.repeat(reps, 1, 1, 1).view(-1, *shp[1:])

In [93]: rep_tensor.shape
Out[93]: torch.Size([1000, 1024, 14, 14])

Вот простой пример проверки работоспособности:

In [109]: shp = (1, 3, 2)
In [110]: t = torch.randn(shp)

In [111]: t
Out[111]: 
tensor([[[-0.8974,  0.7790],
         [-0.0637, -1.0532],
         [-0.1682, -0.1921]]])

# repeat 3 times along axis 0
In [112]: rep_tensor = t.repeat(3, 1, 1).view(-1, *shp[1:])

In [113]: rep_tensor
Out[113]: 
tensor([[[-0.8974,  0.7790],
         [-0.0637, -1.0532],
         [-0.1682, -0.1921]],

        [[-0.8974,  0.7790],
         [-0.0637, -1.0532],
         [-0.1682, -0.1921]],

        [[-0.8974,  0.7790],
         [-0.0637, -1.0532],
         [-0.1682, -0.1921]]])
...