Torch - Repeat Tensor Like Numpy Repeat

Torch - Repeat Tensor Like Numpy Repeat

I am trying to repeat a tensor in torch in two ways. For example repeating the tensor {1,2,3,4} 3 times both ways to yield;

{1,2,3,4,1,2,3,4,1,2,3,4}
{1,1,1,2,2,2,3,3,3,4,4,4}

There is a built in torch:repeatTensor function which will generate the first of the two (like numpy.tile()) but I can't find one for the latter (like numpy.repeat()). I'm sure that I could call sort on the first to give the second but I think this might be computationally expensive for larger arrays?

Thanks.

1

6 Answers

Try torch.repeat_interleave() method:

>>> x = torch.tensor([1, 2, 3])
>>> x.repeat_interleave(2)
tensor([1, 1, 2, 2, 3, 3])
1

Quoting -

z = torch.FloatTensor([[1,2,3],[4,5,6],[7,8,9]])
1 2 3
4 5 6
7 8 9
z.transpose(0,1).repeat(1,3).view(-1, 3).transpose(0,1)
1 1 1 2 2 2 3 3 3
4 4 4 5 5 5 6 6 6
7 7 7 8 8 8 9 9 9

This will give you a intuitive feel of how it works.

a = torch.Tensor([1,2,3,4])

To get [1., 2., 3., 4., 1., 2., 3., 4., 1., 2., 3., 4.] we repeat the tensor thrice in the 1st dimension:

a.repeat(3)

To get [1,1,1,2,2,2,3,3,3,4,4,4] we add a dimension to the tensor and repeat it thrice in the 2nd dimension to get a 4 x 3 tensor, which we can flatten.

b = a.reshape(4,1).repeat(1,3).flatten()

or

b = a.reshape(4,1).repeat(1,3).view(-1)
4

Here's a generic function that repeats elements in tensors.

def repeat(tensor, dims):
    if len(dims) != len(tensor.shape):
        raise ValueError("The length of the second argument must equal the number of dimensions of the first.")
    for index, dim in enumerate(dims):
        repetition_vector = [1]*(len(dims)+1)
        repetition_vector[index+1] = dim
        new_tensor_shape = list(tensor.shape)
        new_tensor_shape[index] *= dim
        tensor = tensor.unsqueeze(index+1).repeat(repetition_vector).reshape(new_tensor_shape)
    return tensor

If you have

foo = tensor([[1, 2],
              [3, 4]])

By calling repeat(foo, [2,1]) you get

tensor([[1, 2],
        [1, 2],
        [3, 4],
        [3, 4]])

So you duplicated every element along dimension 0 and left elements as they are on dimension 1.

Use einops:

from einops import repeat

repeat(x, 'i -> (repeat i)', repeat=3)
# like {1,2,3,4,1,2,3,4,1,2,3,4}

repeat(x, 'i -> (i repeat)', repeat=3)
# like {1,1,1,2,2,2,3,3,3,4,4,4}

This code works identically for any framework (numpy, torch, tf, etc.)

Can you try something like:

import torch as pt

#1 work as numpy tile

b = pt.arange(10)
print(b.repeat(3))

#2 work as numpy tile

b = pt.tensor(1).repeat(10).reshape(2,-1)
print(b)

#3 work as numpy repeat

t = pt.tensor([1,2,3])
t.repeat(2).reshape(2,-1).transpose(1,0).reshape(-1)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Sarah Jenkins
Author

Sarah Jenkins

Sarah Jenkins is a veteran tech journalist with over 12 years of experience covering artificial intelligence, mobile innovations, and digital ethics. Her insights have appeared in leading technology publications worldwide.