Concepts / Tensors and PyTorch Fundamentals

Tensors and PyTorch Fundamentals

torch.tensor() creates a PyTorch tensor from a Python value that you pass to it as an argument.

  • Programming

Why Tensor Creation Comes First

A tensor is the basic data container you will work with throughout PyTorch. Before you can compute anything with one, you need the first practical skill: creating one. In PyTorch that skill rests on a single function, torch.tensor(). You pass it a Python value, and it returns a tensor that you can assign to a name.

Everything you need to understand about creation is visible in a handful of short lines. The goal of this article is to read those lines carefully and understand why each one produces the tensor it does. Along the way you will form a rule you can apply to inputs you have never seen before.

What do you think happens?

You run tensor0d = torch.tensor(1). What kind of tensor do you get: zero-dimensional, one-dimensional, or something else?

  • Zero-dimensional tensor (a scalar)

  • One-dimensional tensor (a vector)

  • Two-dimensional tensor

Reveal answer
Answer:

A zero-dimensional tensor, also called a scalar.

A bare Python integer passed to torch.tensor() produces a zero-dimensional tensor. The integer has no brackets around it, so the tensor has no axes of its own.

Tracing Four Tensors from One Function

The source listing begins by importing the library and then makes four assignments. Each assignment follows the same pattern: a Python value is passed to torch.tensor(), and the returned tensor is stored under a name. The first two assignments are shown below exactly as they appear in the source.

python
Notes on the code
  • tensor0d: the input is a bare integer with no brackets
  • tensor1d: the input is a flat list with one level of square brackets

The source describes the first result as a zero-dimensional tensor, also called a scalar. A scalar holds one value and has no axes of its own. The second result is described as a one-dimensional tensor, or vector. Its three values sit side by side in a single row of data. Notice what changed between the two lines: only the input. Moving from a bare integer to a list is what moved the result from zero dimensions to one.

The third and fourth lines of the listing extend the same idea by nesting lists inside lists. A list of lists produces a two-dimensional tensor, and a list of lists of lists produces a three-dimensional tensor. The following lines are an original illustration of that pattern, using new values so you can see the structure without relying on the listing's exact numbers.

python
Notes on the code
  • tensor2d: a list of two lists, so two levels of brackets around the numbers
  • tensor3d: a list of two lists of lists, so three levels of brackets around the numbers

What torch.tensor() Does with Its Input

Every line in the listing follows the same path. You write a Python value, pass it to torch.tensor(), and assign the returned tensor to a name. The diagram below shows that path in order. The important point is that the shape of the resulting tensor is decided at the moment of creation, by the value you pass in. You do not reshape the tensor afterwards to get the dimensions you want; the structure of the input determines them.

Python valueinteger or nested listtorch.tensor()single function callTensor objectdimensions set at creationAssigned namee.g. tensor1dpassed as argumentreturnsassigned to
What happens to a Python value when it is passed to torch.tensor(), and where the tensor's dimensions get decided

Reading Dimensions from Brackets

The listing gives you a reliable way to predict dimensions. Count the levels of square brackets around the innermost numbers. A bare number has no brackets and yields a zero-dimensional tensor. One level of brackets, as in a flat list, yields a one-dimensional tensor. Two levels yield a two-dimensional tensor, and three levels yield a three-dimensional tensor. Each added pair of brackets adds one dimension.

The diagram below turns that counting rule into a map. Start at the root, count the bracket levels in your input, and follow the branch that matches. Every branch corresponds to one of the four tensors in the listing.

Count bracketlevels0 levels: 1bare integer0-dimensional tensorscalar1 level: [1, 2, 3]flat list1-dimensional tensorvector2 levels: [[1, 2, 3],[4, 5, 6]]list of lists2-dimensional tensor3 levels: [[[1, 2],[3, 4]], ...]list of lists of lists3-dimensional tensor
Which level of brackets in the Python value corresponds to which tensor dimension, and how each added pair of brackets adds one dimension
InputBracket levelsDimensionsName used in source
100Zero-dimensional tensor, or scalar
[1, 2, 3]11One-dimensional tensor, or vector
[[1, 2, 3], [4, 5, 6]]22Two-dimensional tensor
[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]33Three-dimensional tensor

The four inputs from the listing family, read from the outside in

Locating Where Dimensions Diverge

Sometimes an input looks like it should produce one dimension count, but its brackets say otherwise. The useful habit is to read the brackets rather than the numbers. Count the opening brackets from the outside in, then check whether each level of brackets actually wraps something. The first level that does not match your expectation is where the tensor's dimensions differ from what you thought.

[outer pair opens[1, 2, 3]row one, inner pair[4, 5, 6]row two, inner pair]outer pair closes
Given a nested Python list, which bracket pairs define the tensor's structure and what each pair contributes
Worked example

An input that is deeper than it looks

Predict the dimensionality of torch.tensor([[[1, 2], [3, 4]]]). A reader might expect a two-dimensional tensor because there are two rows of numbers.

  1. 1
    Count the opening brackets from the outside

    The input starts with three square brackets before the first number: [[[ . That is three levels of brackets.

  2. 2
    Check each level for wrapping

    The outermost level wraps one item, [[1, 2], [3, 4]]. The middle level wraps the two rows [1, 2] and [3, 4]. The innermost level wraps the numbers in each row.

  3. 3
    Map the level count to a dimension

    Three levels of brackets yield a three-dimensional tensor, so the extra outer pair is what changes the answer. The two rows of numbers are not the whole story.

  4. 4
    Locate the divergence

    The point of difference is the outermost bracket pair. It adds the third dimension even though the visible numbers form only two rows.

Result

The tensor is three-dimensional, with one outer item containing two rows of two numbers each.

Mistakes Beginners Make with Dimensions

  • Common mistake

    Counting the numbers instead of the brackets

    What it looks like

    Looking at [[[1, 2], [3, 4]]] and deciding it is two-dimensional because it contains four numbers in two rows.

    Why it fails

    The number of values does not set the dimension count. The number of bracket levels around them does.

    Do this instead

    Count the levels of square brackets from the outside in. This input has three levels, so it is three-dimensional.

  • Common mistake

    Treating a bare integer as a list

    What it looks like

    Writing torch.tensor(1) and expecting a one-dimensional tensor with a single element.

    Why it fails

    A bare number has no brackets, so the source describes it as a zero-dimensional tensor, also called a scalar.

    Do this instead

    Use torch.tensor([1]) if you want a one-dimensional tensor with one element. Keep torch.tensor(1) for a scalar.

  • Common mistake

    Assuming each added pair of brackets adds a number

    What it looks like

    Expecting [[1, 2, 3]] to behave like [1, 2, 3] with a few extra characters.

    Why it fails

    Each added pair of brackets raises the dimension count by one, so the extra pair changes the result.

    Do this instead

    Compare the bracket count of each input before you run the code. [1, 2, 3] has one level; [[1, 2, 3]] has two.

  • Common mistake

    Forgetting that the shape is decided at creation, so trying to fix dimensions only after the tensor exists instead of changing the input

Predicting Dimensions Before You Run the Code

EASY

For each input below, predict the number of dimensions before you run torch.tensor(). Inputs: (a) 7, (b) [7, 8], (c) [[7, 8], [9, 10]], (d) [[[7]]]. Then state the first bracket level where your expectation could go wrong.

Hints
  • Count the square bracket levels around the innermost numbers, not the numbers themselves.
  • A bare integer has zero levels. A flat list has one level.
  • For (d), the input has three opening brackets before the 7, even though it contains only one number.

Summary of Tensor Creation

At a glance

  • torch.tensor() creates a PyTorch tensor from a Python value passed to it as an argument, and the tensor's dimensions are set by that input at the moment of creation.
  • A bare Python integer produces a zero-dimensional tensor, also called a scalar.
  • A flat Python list produces a one-dimensional tensor, or vector, and each added level of nested lists raises the dimension count by one.
  • To predict dimensions, count the levels of square brackets around the innermost values before running the code, and locate the outermost level that changes your expectation.

Related concepts

More concepts starting with T