Reshape and reduce tensors
PyTorch stores numbers in tensors. A tensor is a block of numbers with a shape: a list of 6 numbers has the shape 6, and a table of 2 rows and 3 columns has the shape 2 by 3. The same 6 numbers can be viewed either way without copying or reordering them. Most of the work in PyTorch code is keeping track of shapes, so this lesson practises the two moves you will use most: changing a shape, and adding along one direction.
Learn it
Words to know
- tensor
- PyTorch's block of numbers. It can be one number, a list, a table, or have more dimensions.
- shape
- The size of a tensor along each dimension. A table of 2 rows and 3 columns has shape
[2, 3]. - dimension
- One direction of a tensor. In a table, dimension 0 runs down the rows and dimension 1 across the columns.
How it works
torch.tensor(flat, dtype=torch.float64)turns a Python list into a tensor of shape[6]..reshape(rows, cols)reads the same numbers in the same order, filling one row after another..sum(dim=1)adds along dimension 1, which runs across the columns. Each row collapses to one number.dim=0would add down the rows and give one number per column..tolist()turns the result back into a Python list.
Worked example
Input flat = [1, 2, 3, 4, 5, 6] rows = 2 cols = 3 Output [6, 15]
| Step | Result | Shape |
|---|---|---|
| torch.tensor(flat) | [1, 2, 3, 4, 5, 6] | [6] |
| .reshape(2, 3) | [[1, 2, 3], [4, 5, 6]] | [2, 3] |
| .sum(dim=1) | [6, 15] | [2] |
| col 0 | col 1 | col 2 | sum | |
|---|---|---|---|---|
| row 0 | 1 | 2 | 3 | 6 |
| row 1 | 4 | 5 | 6 | 15 |
sum(dim=1) adds the three cells of each colour into one total.The dimension you name in sum is the one that disappears: shape [2, 3] summed over dimension 1 leaves shape [2].
Why it matters
Every later PyTorch lesson is a chain of shape changes like this one. Reading a shape off each line is the fastest way to find a bug in model code.
Your turn
Using PyTorch, lay a flat list out as a table and add up each row.
flat- a list of
rows * colsnumbers rows- the number of rows; 1 or more
cols- the number of columns; 1 or more
- Returns
- A Python list with the sum of each row, top to bottom.
This lesson needs PyTorch, which does not run in the browser. The app gives you the exercise as a file with its tests, to run on your own computer.
Example 1
Input flat = [1, 2, 3, 4, 5, 6] rows = 2 cols = 3 Output [6, 15]
The rows are [1, 2, 3] and [4, 5, 6], which add up to 6 and 15.
Example 2
Input flat = [1, 2, 3, 4] rows = 2 cols = 2 Output [3, 7]
The rows are [1, 2] and [3, 4]: 3 and 7.
Example 3
Input flat = [-1, 1] rows = 1 cols = 2 Output [0]
One row, [-1, 1], which adds up to 0.
Hints
Each hint gives away a little more. Open one only when you need it.
Hint 1: Where to start
It is one chain of four calls: make a tensor, reshape it, sum it, turn it back into a list.
Hint 2: The key step
Sum along dimension 1 to get one number per row. Dimension 0 would give one number per column.
Hint 3: The outline
Return
torch.tensor(flat, dtype=torch.float64).reshape(rows, cols).sum(dim=1).tolist().
Solution
From here on the page gives the method away. If you are still solving, go back to the hints.
Step by step
- A tensor of shape [rows * cols].
float64matches Python's own numbers, so the results agree with the expected values to many digits. - The same numbers as a table of shape [rows, cols]. Reshape never changes the order or the count. It fills the first row, then the second, and so on.
- Add along dimension 1: one total per row. Dimension 1 is the one that is removed. What is left has one entry per row.
The same numbered steps are the comments in the solution.
Python
import torch
def solve(flat, rows, cols):
# 1. A tensor of shape [rows * cols]
numbers = torch.tensor(flat, dtype=torch.float64)
# 2. The same numbers as a table of shape [rows, cols]
table = numbers.reshape(rows, cols)
# 3. Add along dimension 1: one total per row
totals = table.sum(dim=1)
return totals.tolist()Watch out
sum(dim=0)adds down each column and returnscolsnumbers. For the first example it would give[5, 7, 9].- Return a Python list. A tensor is not equal to a list, so the checks would fail without
.tolist().
Check yourself
After summing a tensor of shape [2, 3] along dimension 1, what shape is left?
[2]. The dimension named in the sum is the one that goes away.
Does reshape change the order of the numbers?
No. It keeps the same numbers in the same order and only changes where the rows break.