Tensors & Devices#
Use this page to quickly reference how to create and inspect tensors, change their shape or dtype, convert between NumPy and PyTorch, and move tensors and models between devices.
Tensor Basics#
Creating Tensors#
Use torch.tensor to construct a tensor from existing Python data.
x = torch.tensor([1.0, 2.0, 3.0])
x = torch.tensor([[1, 2],
[3, 4]], dtype=torch.float32)
Common constructors create tensors from a requested shape or numerical sequence.
Constructor |
Returns |
|---|---|
|
Tensor of zeros |
|
Tensor of ones |
|
Tensor of integers from |
|
Tensor of random numbers from a standard normal distribution |
Inspecting Tensors#
The most useful tensor properties are available directly on the tensor.
Property |
Returns |
|---|---|
|
Size of each dimension |
|
Number of dimensions |
|
Total number of elements |
|
Data type |
|
Device containing the tensor |
Dtypes#
The course mainly uses three tensor dtypes.
Typical use |
dtype |
|---|---|
Features, activations, parameters |
|
Multiclass target indices |
|
Boolean masks |
|
Convert a tensor with .to(...):
x = x.to(torch.float32)
targets = targets.to(torch.int64)
Convenience methods are also available:
x = x.float()
targets = targets.long()
Warning
For multiclass classification, nn.CrossEntropyLoss expects targets to be integer class indices.
NumPy and PyTorch#
Convert a NumPy array to a tensor with torch.from_numpy.
import numpy as np
array = np.array([1.0, 2.0, 3.0], dtype=np.float32)
x = torch.from_numpy(array)
Convert a CPU tensor to a NumPy array with .numpy().
array = x.numpy()
torch.from_numpy shares memory with the NumPy array, so changing one can change the other.
For a tensor produced during model computation, a useful conversion pattern is:
array = tensor.detach().cpu().numpy()
Selecting and Reshaping#
Indexing and Slicing#
PyTorch tensors use NumPy-like indexing.
x[0] # first element along dimension 0
x[:, 0] # first column
x[2:5] # elements 2, 3, and 4
x[..., 0] # index 0 along the final dimension
For a batch of images:
images.shape # → (N, C, H, W)
first_image = images[0] # → (C, H, W)
first_channel = images[:, 0] # → (N, H, W)
Boolean tensors can be used as masks.
mask = targets == 3
selected = features[mask]
reshape#
reshape changes the dimensions of a tensor without changing its number of elements.
x = torch.arange(12)
y = x.reshape(3, 4)
# y.shape → (3, 4)
Use -1 to let PyTorch infer one dimension.
x = torch.randn(32, 1, 28, 28)
flattened = x.reshape(x.shape[0], -1)
# flattened.shape → (32, 784)
Warning
The new shape must contain the same total number of elements as the original tensor.
flatten#
flatten combines several dimensions into one.
x = torch.randn(2, 3, 4)
y = x.flatten()
# y.shape → (24, )
For batched data, preserve the batch dimension with start_dim=1.
images = torch.randn(64, 1, 28, 28)
features = images.flatten(start_dim=1)
# features.shape → (64, 784)
Warning
Calling flatten() without start_dim=1 also flattens the batch dimension.
unsqueeze and squeeze#
unsqueeze inserts a dimension of size one.
image = torch.randn(3, 28, 28)
batch = image.unsqueeze(0)
# batch.shape → (1, 3, 28, 28)
squeeze removes a dimension of size one.
image = batch.squeeze(0)
# image.shape → (3, 28, 28)
Specify the dimension when its position is known.
x = x.squeeze(1)
Warning
Calling squeeze() without a dimension removes every dimension whose size is one, which can unintentionally remove a batch dimension when the batch contains one example.
Devices#
Selecting a Device#
Use an available accelerator when possible and fall back to the CPU.
if torch.cuda.is_available():
device = torch.device("cuda")
elif torch.backends.mps.is_available():
device = torch.device("mps")
else:
device = torch.device("cpu")
Moving Tensors and Models#
Move the model and the tensors involved in the same computation to the selected device.
model = model.to(device)
inputs = inputs.to(device)
targets = targets.to(device)
Warning
Moving the model does not automatically move the input batch.
Inspecting Device Placement#
Inspect a tensor directly:
inputs.device
For a model, inspect one of its parameters:
next(model.parameters()).device
A useful consistency check is:
assert inputs.device == next(model.parameters()).device