Resizing tensors is one of the most common operations in deep learning. Whether you're preparing input data for a neural network, reshaping feature maps between layers, or adjusting tensor dimensions for matrix operations, you'll need to change tensor shapes frequently. PyTorch provides several methods to resize tensors, each suited for different scenarios.
In this guide, you'll learn four methods to resize tensors in PyTorch - view(), reshape(), resize_(), and unsqueeze() - understand when to use each one, and avoid common pitfalls.
Key Rule: Total Elements Must Match
Before resizing, remember this fundamental rule: the total number of elements must remain the same before and after resizing (except with resize_(), which can add or discard elements).
For example, a tensor with 12 elements can be reshaped to (2, 6), (3, 4), (6, 2), (2, 2, 3), etc. - but not to (2, 5) because 2 × 5 = 10 ≠ 12.
Method 1: Using view()
The view() method returns a new tensor with the same underlying data but a different shape. It's the most commonly used reshaping method in PyTorch.
torch.Tensor.view(*shape)Resizing a 1D Tensor to 2D
import torch
tens = torch.Tensor([10, 20, 30, 40, 50, 60])
print("Original:", tens)
print("Shape: ", tens.shape)
result = tens.view(2, 3)
print("\nResized to 2×3:")
print(result)Output:
Original: tensor([10., 20., 30., 40., 50., 60.])
Shape: torch.Size([6])
Resized to 2×3:
tensor([[10., 20., 30.],
[40., 50., 60.]])Using -1 to Infer a Dimension
You can pass -1 for one dimension, and PyTorch will automatically calculate its size based on the total number of elements:
import torch
tens = torch.Tensor([10, 20, 30, 40, 50, 60])
result_a = tens.view(2, -1) # Infers 3 columns → (2, 3)
result_b = tens.view(-1, 2) # Infers 3 rows → (3, 2)
result_c = tens.view(-1, 3) # Infers 2 rows → (2, 3)
print("view(2, -1):", result_a.shape)
print("view(-1, 2):", result_b.shape)
print("view(-1, 3):", result_c.shape)Output:
view(2, -1): torch.Size([2, 3])
view(-1, 2): torch.Size([3, 2])
view(-1, 3): torch.Size([2, 3])Resizing a 2D Tensor
import torch
tens = torch.Tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]])
print("Original shape:", tens.shape)
result_a = tens.view(2, 6)
result_b = tens.view(6, 2)
result_c = tens.view(3, 4)
print("\n2×6:")
print(result_a)
print("\n6×2:")
print(result_b)
print("\n3×4:")
print(result_c)Output:
Original shape: torch.Size([4, 3])
2×6:
tensor([[ 1., 2., 3., 4., 5., 6.],
[ 7., 8., 9., 10., 11., 12.]])
6×2:
tensor([[ 1., 2.],
[ 3., 4.],
[ 5., 6.],
[ 7., 8.],
[ 9., 10.],
[11., 12.]])
3×4:
tensor([[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[ 9., 10., 11., 12.]])Method 2: Using reshape()
The reshape() method works similarly to view() but is more flexible - it can handle both contiguous and non-contiguous tensors:
import torch
tens = torch.tensor([10, 20, 30, 40, 50, 60, 70, 80])
print("Original:", tens)
result_a = tens.reshape(2, 4)
print("\n2×4:")
print(result_a)
result_b = tens.reshape(4, 2)
print("\n4×2:")
print(result_b)
result_c = tens.reshape(2, 2, 2)
print("\n2×2×2:")
print(result_c)Output:
Original: tensor([10, 20, 30, 40, 50, 60, 70, 80])
2×4:
tensor([[10, 20, 30, 40],
[50, 60, 70, 80]])
4×2:
tensor([[10, 20],
[30, 40],
[50, 60],
[70, 80]])
2×2×2:
tensor([[[10, 20],
[30, 40]],
[[50, 60],
[70, 80]]])view() vs reshape() - When Does It Matter?
import torch
tens = torch.tensor([[1, 2, 3],
[4, 5, 6]])
transposed = tens.t()
print("Is contiguous:", transposed.is_contiguous())
try:
result = transposed.view(6)
except RuntimeError as e:
print(f"view() error: {e}")
result = transposed.reshape(6)
print("reshape() result:", result)Output:
Is contiguous: False
view() error: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
reshape() result: tensor([1, 4, 2, 5, 3, 6])Method 3: Using resize_() (In-Place, Use with Caution)
The resize_() method is an in-place operation that can change both the shape and the total number of elements. If the new size is larger, the additional values are uninitialized (contain arbitrary data). If smaller, excess elements are discarded.
import torch
tens = torch.tensor([1, 2, 3, 4, 5, 6])
print("Original:", tens)
tens.resize_(2, 3)
print("\nResized to 2×3:")
print(tens)Output:
Original: tensor([1, 2, 3, 4, 5, 6])
Resized to 2×3:
tensor([[1, 2, 3],
[4, 5, 6]])Method 4: Using unsqueeze() and squeeze()
These methods add or remove dimensions of size 1, which is essential for broadcasting and matching tensor dimensions in neural networks.
unsqueeze() - Add a Dimension
import torch
tens = torch.tensor([10, 20, 30, 40, 50])
print("Original shape:", tens.shape)
result_0 = tens.unsqueeze(0)
print("\nunsqueeze(0):", result_0.shape)
print(result_0)
result_1 = tens.unsqueeze(1)
print("\nunsqueeze(1):", result_1.shape)
print(result_1)Output:
Original shape: torch.Size([5])
unsqueeze(0): torch.Size([1, 5])
tensor([[10, 20, 30, 40, 50]])
unsqueeze(1): torch.Size([5, 1])
tensor([[10],
[20],
[30],
[40],
[50]])squeeze() - Remove Dimensions of Size 1
import torch
tens = torch.tensor([[[1, 2, 3]]])
print("Original shape:", tens.shape)
result = tens.squeeze()
print("After squeeze():", result.shape)
print(result)Output:
Original shape: torch.Size([1, 1, 3])
After squeeze(): torch.Size([3])
tensor([1, 2, 3])Practical Example: Reshaping for a Neural Network
A common use case is reshaping image tensors before feeding them into fully connected layers:
import torch
images = torch.randn(4, 1, 28, 28)
print("Original shape:", images.shape)
flat = images.view(4, -1)
print("Flattened shape:", flat.shape)
flat_alt = images.reshape(images.size(0), -1)
print("Flattened (reshape):", flat_alt.shape)Output:
Original shape: torch.Size([4, 1, 28, 28])
Flattened shape: torch.Size([4, 784])
Flattened (reshape): torch.Size([4, 784])Common Mistake: Element Count Mismatch
Trying to reshape a tensor into a shape with a different total number of elements raises an error:
import torch
tens = torch.tensor([1, 2, 3, 4, 5])
try:
result = tens.view(2, 3)
except RuntimeError as e:
print(f"Error: {e}")Output:
Error: shape '[2, 3]' is invalid for input of size 5Fix: Ensure the product of the new dimensions equals the total number of elements:
result = tens.view(1, 5)
print(result)Comparison of Methods
| Method | In-Place | Requires Contiguous | Preserves Element Count | Best For |
|---|---|---|---|---|
view() |
❌ | ✅ | ✅ (enforced) | Fast reshaping, guaranteed no copy |
reshape() |
❌ | ❌ | ✅ (enforced) | General reshaping (most flexible) |
resize_() |
✅ | ❌ | ❌ (can change) | Low-level memory manipulation (use rarely) |
unsqueeze() |
❌ | ❌ | ✅ | Adding a single dimension |
squeeze() |
❌ | ❌ | ✅ | Removing size-1 dimensions |
Summary
To resize tensors in PyTorch:
- Use
reshape()as your default choice - it's the most flexible and handles both contiguous and non-contiguous tensors. - Use
view()when you want to guarantee no data is copied and the tensor is contiguous in memory. - Use
unsqueeze()andsqueeze()to add or remove dimensions of size 1, which is essential for broadcasting and layer compatibility. - Avoid
resize_()unless you have a specific low-level need - it can create tensors with uninitialized garbage data. - Use
-1in any dimension to let PyTorch calculate the size automatically.