Permute elements of a tensor along a dimension
Hi, I am trying to permute the feature map dimension in a tensor. As a very simplified case, One possible way I found was to do a index_select followed by cat. But, in case of a larger tensor, a lot of intermediate tensors will have to be created. Is there a better way to achieve this?
Nabarun_Goswami
apaszke
OK, so this is what I tried: <SCODE>>>> n = np.arange(480).reshape((5,4,4,6))
>>> a = torch.from_numpy(n)
>>> perm = torch.LongTensor([0,2,1,3])
>>> a[:, perm, :, :]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: indexing a tensor with an object of type LongTensor. The only supported types are integers, slices, numpy scalars and torch.LongTensor or torch.ByteTensor as the only argument.
<ECODE> Shouldn’t perm be a torch.LongTensor? Am I missing something here?
Nabarun_Goswami
apaszke
Getting the same error even when I remove the trailing :, :.
Nabarun_Goswami
I can probably do a dimension permute to bring the required dimension to dim0 and do the permutation and dimension permute back to original order. Seems like a hacky way to do it though.
Nabarun_Goswami
Ah yes, you’re right. We should have full indexing implemented soon.
apaszke
harpone
This answer is a bit late but I stumbled upon this thread while trying to create a permutation matrix from permutation indexes so I’ll just share what I found works. <SCODE>permutation_indices = ...
size = permutation_indices.size(0)
permutation_matrix = torch.zeros(size, size)
permutation_matrix[torch.arange(size).long(), permutation_indices] = 1
<ECODE>
tetratrio
Not quite what I (or the OP) was looking for but thanks for the effort!
harpone
Oh yea thats an even simpler approach. Why didnt think of that. Thanks!
tetratrio
Yeah as above, permutations can be achieved via matrix multiplication.  [a b] * [0 1; 1 0] => [b a], for example.
Tim_Oleskiw
I do like this:
cuixing158_1
Regarding how to permute vectors in PyTorch: there seems to be a function pytorch.permute(), but I can’t find any documentation for it, and when I try it doesn’t seem to work as I might expect (seems to be a no-op).
Daniel_Povey
<SCODE>x = torch.randn(1, 2, 3)
print(x.shape)
> torch.Size([1, 2, 3])
x = x.permute(1, 2, 0)
> torch.Size([2, 3, 1])
<ECODE> print(x.shape)
ptrblck
Did you want something like this? <SCODE>>>> import torch
>>> x = torch.randn(100, 57, 2)
>>> idx = torch.randint(57, size=(100, 57))
>>> permutated_x = x.gather(dim=1, index=idx.unsqueeze(-1).expand(x.shape))
>>> torch.all(x[0][idx[0]] == permutated_x[0])
tensor(True)
>>> torch.all(x[28][idx[28]] == permutated_x[28])
tensor(True)
<ECODE>
Yuheng_Zhi