Concepts / Matrix Multiplication with Tensors

Matrix Multiplication with Tensors

The starting tensor is built from a list of two inner lists, each holding three numbers.

  • Programming

Predicting Before Printing

This article follows a short PyTorch program in which one small tensor is created, inspected, reshaped, transposed, and multiplied by its own transpose. Each step is simple on its own. The habit this article builds is predicting the result of each line before reading the output, then checking the prediction against what actually printed. A single 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.

Before reading any further, try this prediction. The starting tensor has two rows of three numbers. If you apply the transpose attribute to it, what shape do you expect the result to have? Commit to an answer, then keep reading.

What do you think happens?

A starting tensor has shape (2, 3). What is the shape after applying .T to it?

  • (2, 3)

  • (3, 2)

  • (6,)

  • (2, 2)

Reveal answer
Answer:

(3, 2)

The transpose swaps the two dimensions. Two rows of three become three rows of two, so the rows of the original become the columns of the result.

Tracing the Starting Tensor

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. The shape attribute reports how many entries lie along each dimension. It is the first thing to check whenever a later operation behaves strangely, because almost every error in this kind of program traces back to a shape that was not what you assumed.

python
Output (expected)
torch.Size([2, 3])
tensor([[1, 2, 3],
        [4, 5, 6]])
Notes on the code
  • The outer list holds two inner lists, so PyTorch creates two rows.
  • Each inner list holds three numbers, so each row has three entries.
  • shape reports the number of entries along each dimension, in row-then-column order.

The six values in this tensor form one fixed sequence: 1, 2, 3, 4, 5, 6. Every operation in the program either regroups that sequence, flips it, or combines it arithmetically. Reading the shape first tells you how those six values are currently grouped.

Reshape Regroups the Same Six Values

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, because there is no way to place seven values into six slots or five values into six slots.

The important point is the order of the values. Reshaping does not shuffle or recalculate anything. The six values keep their sequence, and the new shape determines 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. The diagram below shows this: each position in the flat sequence maps to exactly one cell in the new layout.

position 01row 0, col 01position 12row 0, col 12position 23row 1, col 03position 34row 1, col 14position 45row 2, col 05position 56row 2, col 16same ordersame ordersame ordersame ordersame ordersame order
Which value lands in which row and column when the flat sequence of six values is reshaped to (3, 2), and why the sequence order is preserved.
python
Output (expected)
torch.Size([3, 2])
tensor([[1, 2],
        [3, 4],
        [5, 6]])
Notes on the code
  • The requested shape (3, 2) has 3 times 2 = 6 entries, matching the original count.
  • The printed rows are the pairs 1 and 2, 3 and 4, and 5 and 6, read in the original order.
Worked example

Predicting a reshape before running it

A tensor holds the six values 1, 2, 3, 4, 5, 6 in that order. Predict the reshape to (2, 3) and the reshape to (4, 2), and decide which one can succeed.

  1. 1
    Count the entries

    The tensor has 6 entries, so the new shape must multiply to 6.

  2. 2
    Check (2, 3)

    2 times 3 equals 6, so this shape is valid. Fill the first row with 1, 2, 3 and the second with 4, 5, 6.

  3. 3
    Check (4, 2)

    4 times 2 equals 8, which is not 6. The requested shape needs eight entries that do not exist, so this reshape cannot succeed.

  4. 4
    Confirm order

    For the valid shape, the sequence 1 through 6 is kept. Only the row boundaries change.

Result

The reshape to (2, 3) succeeds and gives rows 1 2 3 and 4 5 6. The reshape to (4, 2) cannot succeed because its total count does not match six.

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. Because the two dimensions trade places, a tensor of shape (2, 3) becomes a tensor of shape (3, 2).

1row 0, col 04row 1, col 01row 0, col 02row 1, col 03row 2, col 02row 0, col 15row 1, col 14row 0, col 15row 1, col 16row 2, col 13row 0, col 26row 1, col 2transposetransposetransposetransposetransposetranspose
Where each element moves when a two-by-three tensor is transposed. Elements marked as changed have a new position; the element 5 keeps the same row and column index.
python
Output (expected)
torch.Size([3, 2])
tensor([[1, 4],
        [2, 5],
        [3, 6]])
Notes on the code
  • The shape changes from (2, 3) to (3, 2), confirming the prediction from the opening.
  • The first printed row, 1 and 4, is the first column of the original tensor.
  • The second printed row, 2 and 5, is the second column of the original tensor.

Notice how the earlier prediction is checked here. If you predicted (3, 2) and the printed shape is torch.Size([3, 2]), the prediction held. If the shape had come back as (2, 3), the transpose would not have run as expected, and the mistake would be in the input or in which attribute was called, not in the matrix arithmetic that comes next.

Matmul Needs Matching Inner Dimensions

The matmul method multiplies two tensors as matrices. In this program the tensor is multiplied by its own transpose. The original is two by three and the transpose is three by two. The inner dimensions must agree: the three in the first tensor and the three in the second tensor. When they agree, they drop out of the result, and the outer dimensions form the shape of the product.

Formula, step by step
  1. 1
    The first tensor has m rows and n columns.
  2. 2
    The second tensor must have n rows, so its row count matches the first tensor's column count.
  3. 3
    The inner n drops out, and the product has m rows and p columns.
row 0 of A1 2 3result entry 0, 014column 0 of Atransposed1 2 3result entry 0, 132column 1 of Atransposed4 5 6multiply pairwise, then addmatching positionsmultiply pairwise, then addmatching positions
Each entry of the product combines one row of the first tensor with one column of the second, multiplying matching positions and adding the results. The top-left entry is 14.
python
Output (expected)
torch.Size([2, 2])
tensor([[14, 32],
        [32, 77]])
Notes on the code
  • A has shape (2, 3) and A.T has shape (3, 2); the inner dimensions 3 and 3 agree.
  • The result has the outer dimensions, 2 and 2, so its shape is (2, 2).
  • The top-left entry 14 combines row 0 of A with column 0 of A.T.

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. The entry at position (0, 1) is 1 times 4, plus 2 times 5, plus 3 times 6, which equals 32. Checking one entry this way is a fast test when a result looks wrong, because it isolates a single cell from the rest of the program.

Worked example

Checking the inner dimensions before multiplying

A has shape (2, 3) and B has shape (3, 4). Decide whether A.matmul(B) is defined, and if so, what shape it returns.

  1. 1
    Read the inner dimensions

    The columns of A are 3 and the rows of B are 3. These are the inner dimensions.

  2. 2
    Compare them

    3 equals 3, so the inner dimensions agree and the product is defined.

  3. 3
    Drop the inner dimension

    The inner 3 drops out of the result.

  4. 4
    Read the outer dimensions

    The rows of A are 2 and the columns of B are 4, so the result has shape (2, 4).

Result

A.matmul(B) is defined and returns a tensor of shape (2, 4).

Mistakes Beginners Make with Shapes

  • Common mistake

    Assuming reshape reorders or recalculates the values

    What it looks like

    Expecting A.reshape(3, 2) to print 1 4 / 2 5 / 3 6 because it looks like a transpose.

    Why it fails

    Reshape does not shuffle values. The six values keep their sequence and only the row boundaries change.

    Do this instead

    Read the new rows as consecutive runs of the original sequence: 1 2, then 3 4, then 5 6.

  • Common mistake

    Choosing a reshape whose total count does not match

    What it looks like

    Calling A.reshape(4, 2) on a tensor with six entries.

    Why it fails

    4 times 2 is 8, and the tensor has only 6 entries, so there is no valid placement.

    Do this instead

    Multiply the requested dimensions first and confirm the product equals the original element count.

  • Common mistake

    Confusing .T with a reshape

    What it looks like

    Expecting A.T to keep the shape (2, 3).

    Why it fails

    Transpose swaps the two dimensions, so a (2, 3) tensor becomes (3, 2).

    Do this instead

    After transposing, read .shape again and expect the two numbers in reverse order.

  • Common mistake

    Multiplying tensors whose inner dimensions disagree

    What it looks like

    Calling A.matmul(A) where A has shape (2, 3). The inner dimensions are 3 and 2.

    Why it fails

    The columns of the first tensor must match the rows of the second, and 3 does not equal 2.

    Do this instead

    Use A.matmul(A.T) instead, where the inner dimensions are 3 and 3.

  • Common mistake

    Ignoring .shape when a later operation fails, and instead editing the arithmetic

Finding the First Wrong Line

When an output differs from what you expected, the most efficient approach is to move forward through the program one operation at a time and check the shape and values after each. The first line where the observed result departs from your prediction is the failure location. Everything after that point may be a consequence of that line rather than a separate cause.

MEDIUM

A colleague runs this program and reports that the final line fails. Study the lines in order and identify the first line where the result differs from what the code should produce. Lines: (1) A = torch.tensor([[1, 2, 3], [4, 5, 6]]); (2) print(A.shape); (3) B = A.reshape(3, 2); (4) C = A.T; (5) D = A.matmul(A). Which line is the first failure, and why?

Hints
  • Start at line 1 and predict the shape of A before reading the output of later lines.
  • Check the inner dimensions of the call on line 5 by comparing the columns of A with the rows of A.
  • Lines 3 and 4 are valid: 3 times 2 equals 6, and transposing swaps the dimensions. Line 5 is the candidate.
MEDIUM

Without running the code, write down the shape of A.reshape(2, 3).T and the shape of A.matmul(A.T.reshape(3, 2)) for the starting tensor A of shape (2, 3). Then run the code and compare your predictions with the printed shapes.

Hints
  • A.reshape(2, 3) keeps the shape (2, 3) because the requested total is six.
  • Transposing a (2, 3) tensor gives (3, 2).
  • Check whether the inner dimensions of the final product agree before predicting its shape.

Summary of Reshape, Transpose, and Matmul

  1. 1
    Reshape regroups a fixed sequence of values into a new shape; the total element count must stay the same and the value order is kept.
  2. 2
    Transpose with .T swaps the two dimensions of a two-dimensional tensor, so rows become columns and columns become rows.
  3. 3
    Matmul with .matmul() requires the inner dimensions to agree, and each output entry combines one row of the first tensor with one column of the second.
  4. 4
    Check .shape after each line, and treat the first line whose result departs from your prediction as the failure location.

At a glance

  • Reshape regroups a fixed sequence of six values into a new shape without reordering or recalculating them, and the total element count must match.
  • Transpose with .T swaps the two dimensions, turning a (2, 3) tensor into a (3, 2) tensor whose rows are the original columns.
  • Matmul requires the inner dimensions to agree; for A of shape (2, 3) and A.T of shape (3, 2), the product has shape (2, 2) with entries 14, 32, 32, and 77.
  • When output is unexpected, check the shape and values after each line; the first departure from your prediction marks where the problem begins.

Related concepts

More concepts starting with M