Tensor Reshaping
Reshaping changes how a fixed sequence of values is grouped into rows and columns; the total number of elements must stay the same and the values keep their order.
Predicting What a Reshape Does
Tensors are the basic data containers used in PyTorch, and most of the work done with them involves changing how their values are arranged. This article follows one short program in which a single small tensor is created, inspected, reshaped, transposed, and multiplied by its own transpose. Each operation is simple on its own. The reason to study them together is that one wrong assumption early in the program, such as a shape you did not expect, carries forward into every later line and can look like a failure somewhere else entirely.
What do you think happens?
You have six numbers arranged as two rows of three. If you reshape them into three rows of two, what happens to the numbers themselves?
Reveal answer
The numbers are unchanged and keep their sequence, only regrouped into different rows and columns.
Reshaping changes how a fixed sequence of values is grouped into rows and columns. The total number of elements must stay the same and the values keep their order. Nothing is shuffled, recalculated, or dropped.
Tracing a Six-Value Tensor Through a Program
The starting tensor is built from a list of two inner lists, each holding three numbers. PyTorch reads that nested structure and creates a two-dimensional tensor. Its shape attribute reports how many entries lie along each dimension, which is the first thing to check whenever a later operation behaves strangely. The program below runs the full sequence. As you read it, predict the printed result of each line before you look at the output.
import torch
x = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(x.shape)
reshaped = x.reshape(3, 2)
print(reshaped)
t = x.T
print(t)
product = x.matmul(x.T)
print(product)- 1Line 3 creates the tensor. Its shape should be 2 by 3, so check that first.
- 2Line 5 prints the shape. If this is not 2 by 3, every later line will differ from the output shown here.
- 3Line 7 reshapes the tensor. Six values must still account for exactly six entries, and they appear in the same order.
- 4Line 10 applies the transpose attribute. No parentheses are used because .T is an attribute, not a method.
- 5Line 13 multiplies the tensor by its own transpose. The inner dimensions agree (3 and 3), so the product exists and is 2 by 2.
torch.tensor()reads the nested lists and builds a two-dimensional tensor- x.shape reports the size along each dimension: 2 rows and 3 columns
x.reshape(3, 2)returns a new view of the same six values arranged as 3 rows of 2- x.T flips rows and columns, giving a 3 by 2 tensor
x.matmul(x.T)multiplies the 2 by 3 tensor by its 3 by 2 transpose
torch.Size([2, 3])
tensor([[1, 2],
[3, 4],
[5, 6]])
tensor([[1, 4],
[2, 5],
[3, 6]])
tensor([[14, 32],
[32, 77]])Reshape Regroups Without Reordering
The reshape method takes a new shape and returns a tensor with that shape. The starting tensor holds six values, so any new shape must also account for exactly six entries. Asking for a shape with a different total count cannot succeed. Reshaping does not shuffle or recalculate anything. The six values keep their sequence, and the new shape decides where each row begins and ends. Reading the same six values in order into three rows of two produces a different grouping of the same numbers, as the first grid below shows.
Under the grids, the values are stored as one linear sequence, and the shape only tells the library how to index into that sequence. Reshape keeps that sequence intact and changes the indexing rule, which is why the values stay the same. The source's reshaped result is three rows of two: the pairs 1 and 2, 3 and 4, and 5 and 6. Those are the same six numbers in the same order as the original, regrouped.
Transpose Swaps Rows and Columns
The transpose attribute, written .T with no parentheses, flips a two-dimensional tensor so that its rows become its columns and its columns become its rows. The first row of the original becomes the first column of the result, and the same pattern continues for every row. Transposing changes the shape from 2 by 3 to 3 by 2. In the diagram below, each element is labeled with its new position, and the elements that moved are marked.
Reading the first column of the transpose
Using x = [[1, 2, 3], [4, 5, 6]], what is the first column of x.T, and how does it relate to the original tensor?
- 1Identify the first row of x
The first row of x is 1, 2, 3.
- 2Turn that row into a column
Transposing makes the first row the first column, so the first column of x.T is 1, 2, 3 read top to bottom.
- 3Check against the printed transpose
The source output for the transposed tensor begins with the rows 1 and 4, then 2 and 5, then 3 and 6. Reading down the first two entries of each row gives the first two columns of the original, which confirms the pattern.
The first row of the original becomes the first column of x.T. The printed transpose has rows 1 and 4, 2 and 5, 3 and 6, so the old rows now run down the columns.
Matrix Multiplication and Inner Dimensions
The matmul method multiplies two tensors as matrices. In the program above, the tensor is multiplied by its own transpose. The original is 2 by 3 and the transpose is 3 by 2. The inner dimensions, the 3 at the end of the first shape and the 3 at the start of the second, agree, so the product is defined. The outer dimensions, the 2 and the 2, give the shape of the result. Before running matmul, check that the inner dimensions match. If they do not, the operation cannot succeed.
- 1The first tensor has 2 rows and 3 columns, so its shape is $2 \times 3$.
- 2The second tensor is the transpose, with 3 rows and 2 columns, so its shape is $3 \times 2$.
- 3The inner values 3 and 3 agree, so the multiplication is defined.
- 4The outer values 2 and 2 give the shape of the product, which is $2 \times 2$.
Each output entry combines one row of the first tensor with one column of the second. The source prints the product with rows 14 and 32 in the first row and 32 and 77 in the second. To check the top-left entry by hand, multiply the first row by the first column and add the products: 1 times 1, plus 2 times 2, plus 3 times 3, which equals 14. Checking a single entry this way is a fast test when a result looks wrong, because it takes only a few multiplications.
3 3
torch.Size([2, 2])- x.shape[1] is the inner size of the first tensor
- x.T.shape[0] is the inner size of the second tensor
- Equal values mean the multiplication is defined
Mistakes That Hide Shape Errors
Shape problems are the most common source of confusing tensor results. The mistakes below are easy to make because each one looks reasonable until the printed shape or values are compared with what was expected.
Common mistake Expecting reshape to reorder or recalculate the values
What it looks likeReshaping 2 by 3 into 3 by 2 and expecting the numbers to come out shuffled or multiplied.
Why it failsReshaping keeps the six values in their sequence and only changes where each row begins and ends.
Do this insteadRead the output as the same numbers regrouped. Treat any reordering as a signal to check the input.
Common mistake Choosing a reshape whose total count does not match
What it looks likeAsking for a shape that holds eight entries from a tensor of six values.
Why it failsAny new shape must account for exactly as many entries as the original tensor holds.
Do this insteadMultiply the dimensions of the requested shape and confirm the product equals the original element count.
Common mistake Using .T with parentheses
What it looks likeWriting x.T() instead of x.T.Why it failsThe transpose is an attribute, written without parentheses.
Do this insteadWrite x.T and check the printed shape afterward.
Common mistake Multiplying tensors without checking inner dimensions
What it looks likeCalling matmul on a 2 by 3 tensor and a 2 by 3 tensor directly.
Why it failsThe inner dimensions 3 and 2 do not agree, so the product is not defined.
Do this insteadCompare the last dimension of the first tensor with the first dimension of the second, or transpose one tensor so they agree.
Common mistake Debugging the last line instead of the first divergence
What it looks likeSeeing a wrong final matrix and rewriting the matmul call while the reshape earlier in the program was already producing a different shape.
Why it failsA single wrong assumption early on carries forward and can look like a failure later.
Do this insteadMove forward one line at a time, checking shape and values after each step. The first line where the observed result departs from your prediction is the failure location.
Print the shape immediately after creating a tensor and again after every reshape, transpose, or matmul. The shape is the first thing to check whenever a later operation behaves strangely, and it costs one line of code per step.
Finding Where a Result First Diverges
When an output differs from what you expected, the efficient approach is to move forward through the program one operation at a time. Predict the shape and values after each line, compare them with what is printed, and stop at the first mismatch. That line is the failure location. Later lines may be consequences of it rather than separate causes.
- 1Print x.shape after creating x and confirm it is 2 by 3.
- 2Predict the shape after
x.reshape(3, 2)and check the printed shape. - 3Predict the values after reshape and confirm the six numbers keep their order.
- 4Predict the shape of x.T and check it against the printed transpose.
- 5Check the inner dimensions of the matmul call before reading its result.
- 6Verify one entry of the product by multiplying a row by a column.
A program creates a tensor y with shape 3 by 4, then calls y.reshape(2, 6) and y.T, and finally y.matmul(y.T). Before running it, predict the shape after each line. At which line would you expect a shape error, and why?
Hints
- Reshape must keep the total number of entries, which is 12 for a 3 by 4 tensor.
- The transpose of a 3 by 4 tensor is 4 by 3.
- Check whether the inner dimensions of y and y.T agree: 4 and 3 do not match.
Key Takeaways
- Reshaping regroups a fixed sequence of values into new rows and columns. The total number of elements must stay the same, and the values keep their order.
- Transposing with .T, written without parentheses, swaps rows and columns, so a 2 by 3 tensor becomes 3 by 2 and the first row becomes the first column.
- Matrix multiplication with .matmul() requires the inner dimensions to agree. The result takes its shape from the outer dimensions, and each entry combines one row of the first tensor with one column of the second.
- When results look wrong, print the shape and check values line by line, stopping at the first line where the output departs from your prediction.