Manipulating the shape of a tensor is common in the PyTorch, since the required shape of a tensor can change between neurons in a given neural network, it is good to have a low-level understanding of reshaping tensor in deep learning. 

PyTorch view() function allows us to restructure tensors so that we maintain the same data but organize it as a different number of rows and columns.

import torch

x=torch.tensor([7,9,4,3,1,6,8,5,2,4,5,8],dtype=torch.int)

y = x.view(3, 4)
print(x.size()) #torch.Size([12])
print(y.size()) #torch.Size([3, 4])

The only requirement is that the shape of the original and new matrix contains the same number of elements (i.e., are the same size).

One useful argument in view() is -1, which effectively means “as many as needed,” so view(1, -1) means one row and as many columns as needed: 

z=y.view(1,-1)
print(z.shape) #torch.Size([1, 12])

view(1, -1) keeps only one channel and merges all the remaining dimensions into one, figuring out the appropriate size. Here our 3 × 4 tensor is transformed into a 1 × 12 vector.

-1 is a special parameter to view() which means “make this axis as big as necessary to fit all the data”. You can use -1 as a placeholder for “however many indexes are left, given the other dimensions and the original number of elements.” 

PyTorch allows us to give one(either row or column) of the new shape parameters as -1 (eg: (4,-1) or (-1,4) but not (-1, -1)). -1 means it is an unknown dimension and PyTorch needs to figure it out. It will calculate by looking at the ‘length of the array and remaining dimensions’.

Example

Now see the example:

x = torch.tensor([[1, 2, 3],
                  [4, 5, 6],
                  [7, 8, 9],
                  [10, 11, 12]])

print(x.shape) #torch.Size([4, 3])

Now trying to reshape with (-1) . The result new shape is (12,) and is compatible with the original shape (4,3)

x.view(-1)

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

Now trying to reshape with (-1, 6). We have provided column as 6 but rows as unknown . So we get the result new shape as (2, 6) again compatible with the original shape(4,3).

x.view(-1,6)

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

Now trying to keep the column as unknown. New shape as (3,-1). i.e., the row is 3, column unknown. We get results in new shapes as (3, 4).

x.view(3,-1)

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

Finally, if we try to provide both dimensions as unknown i.e. new shape as (-1,-1). It will throw an error.

x.view(-1,-1)

#RuntimeError: only one dimension can be inferred

Related Post

What does tensor.view() do in PyTorch?

What does Unsqueeze do in PyTorch?

How to reshape tensor in PyTorch?

PyTorch Difference Between View and Reshape.