PyTorch 张量基础 #

什么是张量? #

张量(Tensor)是 PyTorch 中最基本的数据结构,可以理解为多维数组。它是深度学习中数据表示的核心。

text
┌─────────────────────────────────────────────────────────────┐
│                    张量的维度等级                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  标量(Scalar)- 0D Tensor                                  │
│  ┌───┐                                                      │
│  │ 5 │                                                      │
│  └───┘                                                      │
│  shape: []                                                  │
│                                                             │
│  向量(Vector)- 1D Tensor                                  │
│  ┌───┬───┬───┐                                             │
│  │ 1 │ 2 │ 3 │                                             │
│  └───┴───┴───┘                                             │
│  shape: [3]                                                 │
│                                                             │
│  矩阵(Matrix)- 2D Tensor                                  │
│  ┌───┬───┬───┐                                             │
│  │ 1 │ 2 │ 3 │                                             │
│  ├───┼───┼───┤                                             │
│  │ 4 │ 5 │ 6 │                                             │
│  └───┴───┴───┘                                             │
│  shape: [2, 3]                                              │
│                                                             │
│  3D Tensor                                                  │
│  shape: [深度, 高度, 宽度]                                   │
│  例:RGB 图像 [3, 224, 224]                                 │
│                                                             │
│  4D Tensor                                                  │
│  shape: [批次, 通道, 高度, 宽度]                             │
│  例:图像批次 [32, 3, 224, 224]                             │
│                                                             │
│  5D Tensor                                                  │
│  shape: [批次, 时间, 通道, 高度, 宽度]                       │
│  例:视频数据 [8, 16, 3, 224, 224]                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

张量创建 #

从 Python 列表创建 #

python
import torch

x = torch.tensor([1, 2, 3, 4, 5])
print(x)
print(x.dtype)

x = torch.tensor([1.0, 2.0, 3.0])
print(x)
print(x.dtype)

x = torch.tensor([[1, 2], [3, 4]])
print(x)
print(x.shape)

使用工厂函数创建 #

python
import torch

x = torch.zeros(3, 4)
print(x)

x = torch.ones(2, 3, 4)
print(x)

x = torch.empty(2, 3)
print(x)

x = torch.full((2, 3), fill_value=7)
print(x)

x = torch.eye(4)
print(x)

创建随机张量 #

python
import torch

x = torch.rand(2, 3)
print(x)

x = torch.randn(2, 3)
print(x)

x = torch.randint(0, 10, (2, 3))
print(x)

torch.manual_seed(42)
x = torch.rand(2, 3)
print(x)

创建序列张量 #

python
import torch

x = torch.arange(0, 10, 2)
print(x)

x = torch.linspace(0, 1, 5)
print(x)

x = torch.logspace(0, 1, 5)
print(x)

像 NumPy 一样创建 #

python
import torch
import numpy as np

x = torch.zeros_like(torch.rand(2, 3))
print(x)

x = torch.ones_like(torch.rand(2, 3))
print(x)

x = torch.rand_like(torch.zeros(2, 3))
print(x)

np_array = np.array([1, 2, 3])
x = torch.from_numpy(np_array)
print(x)

x = torch.tensor([1, 2, 3])
np_array = x.numpy()
print(np_array)

张量属性 #

python
import torch

x = torch.randn(2, 3, 4)

print(f"形状: {x.shape}")
print(f"维度: {x.dim()}")
print(f"元素总数: {x.numel()}")
print(f"数据类型: {x.dtype}")
print(f"设备: {x.device}")
print(f"存储: {x.storage()}")

数据类型 #

PyTorch 数据类型一览 #

text
┌─────────────────────────────────────────────────────────────┐
│                    PyTorch 数据类型                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  整数类型:                                                  │
│  ┌─────────────┬─────────────┬─────────────┐               │
│  │ 类型名       │ 对应 NumPy  │ 说明         │               │
│  ├─────────────┼─────────────┼─────────────┤               │
│  │ torch.int8  │ int8        │ 8位有符号    │               │
│  │ torch.int16 │ int16       │ 16位有符号   │               │
│  │ torch.int32 │ int32       │ 32位有符号   │               │
│  │ torch.int64 │ int64       │ 64位有符号   │               │
│  │ torch.uint8 │ uint8       │ 8位无符号    │               │
│  └─────────────┴─────────────┴─────────────┘               │
│                                                             │
│  浮点类型:                                                  │
│  ┌─────────────┬─────────────┬─────────────┐               │
│  │ 类型名       │ 对应 NumPy  │ 说明         │               │
│  ├─────────────┼─────────────┼─────────────┤               │
│  │ torch.float16│ float16    │ 半精度       │               │
│  │ torch.float32│ float32    │ 单精度(默认) │               │
│  │ torch.float64│ float64    │ 双精度       │               │
│  │ torch.bfloat16│ -         │ Brain浮点   │               │
│  └─────────────┴─────────────┴─────────────┘               │
│                                                             │
│  其他类型:                                                  │
│  ┌─────────────┬─────────────┬─────────────┐               │
│  │ 类型名       │ 说明         │ 使用场景     │               │
│  ├─────────────┼─────────────┼─────────────┤               │
│  │ torch.bool  │ 布尔类型     │ 掩码操作     │               │
│  │ torch.complex64│ 复数     │ 信号处理     │               │
│  └─────────────┴─────────────┴─────────────┘               │
│                                                             │
└─────────────────────────────────────────────────────────────┘

类型转换 #

python
import torch

x = torch.tensor([1, 2, 3], dtype=torch.float32)
print(x.dtype)

y = x.to(torch.int64)
print(y.dtype)

y = x.int()
print(y.dtype)

y = x.long()
print(y.dtype)

y = x.float()
print(y.dtype)

y = x.double()
print(y.dtype)

y = x.half()
print(y.dtype)

y = x.to(dtype=torch.float16)
print(y.dtype)

类型推断 #

python
import torch

x = torch.tensor([1, 2, 3])
print(x.dtype)

x = torch.tensor([1.0, 2.0, 3.0])
print(x.dtype)

x = torch.tensor([1, 2.0, 3])
print(x.dtype)

x = torch.tensor([True, False, True])
print(x.dtype)

张量操作 #

索引和切片 #

python
import torch

x = torch.arange(12).reshape(3, 4)
print(x)

print(x[0])

print(x[0, 1])

print(x[:, 0])

print(x[0, :])

print(x[0:2, 1:3])

print(x[-1])

print(x[-2:, -2:])

高级索引 #

python
import torch

x = torch.arange(12).reshape(3, 4)

indices = torch.tensor([0, 2])
print(x[indices])

mask = x > 5
print(mask)
print(x[mask])

print(x[x % 2 == 0])

indices = torch.tensor([0, 2])
print(x[:, indices])

形状操作 #

python
import torch

x = torch.arange(12)

y = x.reshape(3, 4)
print(y.shape)

y = x.view(3, 4)
print(y.shape)

y = x.reshape(-1, 4)
print(y.shape)

y = x.reshape(3, -1)
print(y.shape)

x = torch.randn(2, 3)
y = x.reshape(3, 2)
print(y.is_contiguous())

y = x.reshape(3, 2).contiguous()

x = torch.randn(2, 3, 4)
y = x.permute(2, 0, 1)
print(y.shape)

x = torch.randn(2, 3)
y = x.t()
print(y.shape)

x = torch.randn(2, 3, 4)
y = x.transpose(0, 2)
print(y.shape)

x = torch.randn(2, 3)
y = x.unsqueeze(0)
print(y.shape)

y = x.unsqueeze(1)
print(y.shape)

y = x.unsqueeze(-1)
print(y.shape)

x = torch.randn(1, 3, 1, 4)
y = x.squeeze()
print(y.shape)

y = x.squeeze(0)
print(y.shape)

x = torch.randn(2, 3)
y = x.flatten()
print(y.shape)

y = x.flatten(start_dim=0)
print(y.shape)

张量拼接 #

python
import torch

x = torch.randn(2, 3)
y = torch.randn(2, 3)

z = torch.cat([x, y], dim=0)
print(z.shape)

z = torch.cat([x, y], dim=1)
print(z.shape)

x = torch.randn(2, 3)
y = torch.randn(2, 3)

z = torch.stack([x, y], dim=0)
print(z.shape)

z = torch.stack([x, y], dim=1)
print(z.shape)

张量拆分 #

python
import torch

x = torch.arange(12).reshape(4, 3)

chunks = torch.chunk(x, 2, dim=0)
for i, chunk in enumerate(chunks):
    print(f"Chunk {i}: {chunk.shape}")

splits = torch.split(x, 2, dim=0)
for i, split in enumerate(splits):
    print(f"Split {i}: {split.shape}")

splits = torch.split(x, [1, 2, 1], dim=0)
for i, split in enumerate(splits):
    print(f"Split {i}: {split.shape}")

数学运算 #

基本运算 #

python
import torch

x = torch.tensor([1.0, 2.0, 3.0])
y = torch.tensor([4.0, 5.0, 6.0])

print(x + y)
print(torch.add(x, y))

print(x - y)
print(torch.sub(x, y))

print(x * y)
print(torch.mul(x, y))

print(x / y)
print(torch.div(x, y))

print(x ** 2)
print(torch.pow(x, 2))

print(-x)
print(torch.neg(x))

矩阵运算 #

python
import torch

x = torch.randn(2, 3)
y = torch.randn(3, 4)

z = torch.matmul(x, y)
print(z.shape)

z = x @ y
print(z.shape)

x = torch.randn(2, 3)
y = torch.randn(2, 3)

z = x * y
print(z.shape)

z = torch.mul(x, y)
print(z.shape)

x = torch.randn(3, 4, 5)
y = torch.randn(3, 5, 6)

z = torch.bmm(x, y)
print(z.shape)

聚合运算 #

python
import torch

x = torch.randn(2, 3, 4)

print(x.sum())
print(x.sum(dim=0).shape)
print(x.sum(dim=1).shape)
print(x.sum(dim=2).shape)

print(x.mean())
print(x.mean(dim=0).shape)

print(x.max())
print(x.max(dim=1))

print(x.min())
print(x.min(dim=1))

print(x.prod())

print(x.std())
print(x.var())

values, indices = x.sort(dim=-1, descending=True)
print(values.shape, indices.shape)

print(x.argmax())
print(x.argmax(dim=1))

print(x.argmin())
print(x.argmin(dim=1))

比较运算 #

python
import torch

x = torch.tensor([1.0, 2.0, 3.0])
y = torch.tensor([1.0, 2.5, 3.0])

print(x == y)
print(torch.eq(x, y))

print(x != y)
print(torch.ne(x, y))

print(x > y)
print(torch.gt(x, y))

print(x >= y)
print(torch.ge(x, y))

print(x < y)
print(torch.lt(x, y))

print(x <= y)
print(torch.le(x, y))

print(torch.equal(x, y))

广播机制 #

text
┌─────────────────────────────────────────────────────────────┐
│                    广播机制原理                               │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  规则:                                                      │
│  1. 从右向左比较维度                                         │
│  2. 维度相等或其中一个为1                                    │
│  3. 缺失的维度视为1                                          │
│                                                             │
│  示例:                                                      │
│                                                             │
│  A: [3, 1]                                                  │
│  B: [1, 4]                                                  │
│  ─────────                                                  │
│  C: [3, 4]                                                  │
│                                                             │
│  A 扩展为: [3, 4] (复制列)                                   │
│  B 扩展为: [3, 4] (复制行)                                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
python
import torch

x = torch.randn(3, 1)
y = torch.randn(1, 4)

z = x + y
print(z.shape)

x = torch.randn(3, 4)
y = torch.randn(4)

z = x + y
print(z.shape)

x = torch.randn(2, 3, 4)
y = torch.randn(4)

z = x + y
print(z.shape)

x = torch.randn(2, 3, 4)
y = torch.randn(3, 1)

z = x + y
print(z.shape)

GPU 加速 #

设备管理 #

python
import torch

print(torch.cuda.is_available())

print(torch.cuda.device_count())

print(torch.cuda.current_device())

print(torch.cuda.get_device_name(0))

print(torch.cuda.get_device_properties(0))

张量设备转移 #

python
import torch

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)

x = torch.randn(2, 3)

x_gpu = x.to(device)
print(x_gpu.device)

x_cpu = x_gpu.to("cpu")
print(x_cpu.device)

x_gpu = x.cuda()
x_cpu = x_gpu.cpu()

x = torch.randn(2, 3, device="cuda")
print(x.device)

x = torch.randn(2, 3, device="cuda:0")
print(x.device)

GPU 内存管理 #

python
import torch

print(torch.cuda.memory_allocated() / 1024**2, "MB")
print(torch.cuda.memory_reserved() / 1024**2, "MB")

x = torch.randn(1000, 1000, device="cuda")
print(torch.cuda.memory_allocated() / 1024**2, "MB")

del x
torch.cuda.empty_cache()
print(torch.cuda.memory_allocated() / 1024**2, "MB")

with torch.no_grad():
    y = torch.randn(100, 100, device="cuda")

张量与梯度 #

python
import torch

x = torch.tensor([2.0, 3.0], requires_grad=True)
print(x.requires_grad)

y = x ** 2
print(y.requires_grad)

z = y.sum()
z.backward()
print(x.grad)

x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = x.detach()
print(y.requires_grad)

x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
with torch.no_grad():
    y = x * 2
print(y.requires_grad)

实用技巧 #

张量复制 #

python
import torch

x = torch.randn(2, 3)

y = x.clone()
print(y is x)
y[0, 0] = 100
print(x[0, 0])

y = x.copy_()
print(y is x)

y = x.detach().clone()
print(y.requires_grad)

内存共享 #

python
import torch

x = torch.randn(2, 3)
y = x.view(3, 2)
print(y.data_ptr() == x.data_ptr())

y[0, 0] = 100
print(x[0, 0])

x = torch.randn(2, 3)
y = x.reshape(3, 2)
print(y.data_ptr() == x.data_ptr())

x = torch.randn(2, 3)
y = x.clone()
print(y.data_ptr() == x.data_ptr())

张量打印设置 #

python
import torch

x = torch.randn(100, 100)

torch.set_printoptions(threshold=10)
print(x)

torch.set_printoptions(threshold=1000, edgeitems=2)
print(x)

torch.set_printoptions(precision=4, sci_mode=False)
x = torch.tensor([0.123456789])
print(x)

下一步 #

现在你已经掌握了 PyTorch 张量的基本操作,接下来学习 自动求导,理解深度学习的核心机制!

最后更新:2026-03-29