pytorch(一):张量

什么是张量(Tensor)?

在 PyTorch 中,张量(Tensor)是最核心的数据结构,可以理解为:

张量 = 多维数组(NumPy ndarray 的增强版) + GPU支持 + 自动求导能力

不同维度的张量对应关系:

阶数 名称 示例
0维 标量 3
1维 向量 [1,2,3]
2维 矩阵 [[1,2],[3,4]]
3维+ 高维张量 图像/视频数据

例如,一张 RGB 图片通常表示为:

bash 复制代码
[3, H, W]

张量的创建

1. 直接创建

python 复制代码
import torch

# 标量
a = torch.tensor(5)

# 向量
b = torch.tensor([1, 2, 3])

# 矩阵
c = torch.tensor([[1, 2], [3, 4]])

2. 常用初始化方法

python 复制代码
# 全0
zeros = torch.zeros(2, 3)

# 全1
ones = torch.ones(2, 3)

# 随机数(0~1)
rand = torch.rand(2, 3)

# 正态分布
randn = torch.randn(2, 3)

# 单位矩阵
eye = torch.eye(3)

3. 指定数据类型

python 复制代码
x = torch.tensor([1,2,3], dtype=torch.float32)

常见类型:

  • torch.float32
  • torch.int64
  • torch.bool

4. 从 NumPy 转换

python 复制代码
import numpy as np

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

注意:共享内存!

python 复制代码
np_array[0] = 100
print(tensor)  # 会变化

张量的基本属性

python 复制代码
x = torch.randn(3, 4)
属性 说明
x.shape 形状
x.size() 同shape
x.dtype 数据类型
x.device 所在设备
x.ndim 维度数

示例:

python 复制代码
print(x.shape)   # (3,4)
print(x.ndim)    # 2

张量运算

1. 基本运算

python 复制代码
a = torch.tensor([1,2,3])
b = torch.tensor([4,5,6])

print(a + b)
print(a - b)
print(a * b)
print(a / b)

2. 矩阵运算

python 复制代码
A = torch.randn(2, 3)
B = torch.randn(3, 4)

# 矩阵乘法
C = torch.matmul(A, B)
# 或
C = A @ B

3. 广播机制(Broadcasting)

当两个形状不同的张量进行运算时,自动把较小的张量"扩展"为相同形状,然后逐元素计算。

python 复制代码
a = torch.tensor([[1,2,3],
                  [4,5,6]])

b = torch.tensor([1,2,3])

print(a + b)

自动扩展为:

python 复制代码
[1,2,3]
→
[[1,2,3],
 [1,2,3]]

4. 常见函数

python 复制代码
x = torch.randn(3,3)

torch.sum(x)
torch.mean(x)
torch.max(x)
torch.min(x)

索引与切片

复制代码
x = torch.tensor([[1,2,3],
                  [4,5,6]])
print(x[0])      # 第一行
print(x[:,1])    # 第二列
print(x[0,1])    # 单个元素

高级索引

复制代码
x = torch.arange(10)

idx = torch.tensor([1,3,5])
print(x[idx])

形状操作

1. reshape

python 复制代码
x = torch.arange(6)

y = x.reshape(2,3)

2. view(共享内存)

python 复制代码
y = x.view(2,3)

区别:

  • reshape:可能复制
  • view:必须连续内存

3. transpose / permute

python 复制代码
x = torch.randn(2,3)

# 转置
x.t()

# 高维交换
x = torch.randn(2,3,4)
x = x.permute(1,0,2)

4. squeeze / unsqueeze

python 复制代码
x = torch.randn(1,3,1)

x.squeeze()      # 去掉1维
x.unsqueeze(0)   # 增加维度

设备(CPU/GPU)

复制代码
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

x = torch.tensor([1,2,3]).to(device)

或:

复制代码
x = x.cuda()
x = x.cpu()

自动求导(Autograd)

这是 PyTorch 最核心的能力。

1. requires_grad

python 复制代码
x = torch.tensor(2.0, requires_grad=True)

y = x * x + 3*x

y.backward()

print(x.grad)  # dy/dx = 2x + 3

输出:

复制代码
7

2. 计算图

PyTorch 会自动构建:

python 复制代码
x → y → loss

并通过反向传播计算梯度。

3. 梯度清零

python 复制代码
optimizer.zero_grad()

否则梯度会累加!

4. 禁用梯度

python 复制代码
with torch.no_grad():
    y = x * 2

用于:

  • 推理
  • 提升性能

内存与性能

1. inplace操作

复制代码
x += 1

优点:

  • 节省内存

缺点:

  • 可能破坏计算图

2. contiguous

复制代码
x = x.contiguous()

view() 前常用。

3. clone vs detach

复制代码
y = x.clone()    # 拷贝
z = x.detach()   # 断开计算图

实际案例:简单线性回归

python 复制代码
import torch

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

# 参数
w = torch.randn(1, requires_grad=True)

# 训练
for i in range(100):
    y_pred = x * w
    loss = ((y_pred - y)**2).mean()

    loss.backward()

    with torch.no_grad():
        w -= 0.1 * w.grad

    w.grad.zero_()

print(w)

Tensor 内存布局与 Stride 原理

Tensor 的本质

很多人以为 Tensor 是"多维数组",其实不是。

Tensor 本质 = 一维连续内存 + shape + stride

举个例子:

python 复制代码
import torch

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

逻辑结构:

复制代码
[[1,2,3],
 [4,5,6]]

真实内存:

复制代码
[1,2,3,4,5,6]

多维结构只是"解释方式"。

什么是 stride?

核心定义

stride 表示:在某一维上移动1步,需要跳过多少个内存元素

示例

复制代码
x = torch.tensor([[1,2,3],
                  [4,5,6]])

print(x.stride())

输出:

复制代码
(3, 1)

含义:

维度 stride 含义
3 跳到下一行需要跨3个元素
1 相邻元素间隔1

地址计算公式(重点)

对于元素 x[i][j]

复制代码
内存位置 = base + i*3 + j*1

为什么 view 会报错?

经典错误:

复制代码
RuntimeError: view size is not compatible

示例

python 复制代码
x = torch.randn(2,3)
y = x.t()

y.view(6)   # 报错

原因

view() 要求 Tensor 在内存中是连续的(contiguous)

而 transpose 之后:

复制代码
stride = (1,3)

已经不是连续布局。

contiguous 是什么?

定义

contiguous = 内存按行优先连续排列

解决方法

复制代码
y = y.contiguous()
y.view(6)

本质

复制代码
contiguous() = 重新拷贝一份连续内存

总结

PyTorch 张量的核心可以概括为:

三大能力:

  1. 多维数据表示(类似 NumPy)
  2. GPU 加速
  3. 自动求导(Autograd)

五大重点:

  • 创建与初始化
  • 运算与广播
  • 形状变换
  • 设备管理
  • 自动求导
相关推荐
STRUGGLE_xlf2 小时前
产品经理的 Claude Code 免费教程——模块 3:Nano Banana(AI 图像生成)
人工智能·产品经理
光电的一只菜鸡2 小时前
地平线x5 ISP 图像效果调试
深度学习
搞科研的小刘选手2 小时前
【高届数人文社科会议】第十二届人文学科和社会科学研究国际学术会议(ICHSSR 2026)
大数据·人工智能·电子信息·电子工程·学术会议·信息工程·电路工程
0xDevNull2 小时前
现代AI系统架构全景解析
人工智能·系统架构
华清远见IT开放实验室2 小时前
AI 算法核心知识清单(深度实战版1)
人工智能·python·深度学习·学习·算法·机器学习·ai
亚远景aspice2 小时前
亚远景推出国内首款汽车研发合规AI全栈产品 填补和引领行业AI应用
大数据·人工智能
大囚长2 小时前
大模型知识与逻辑推理能力的关系
人工智能
世优科技虚拟人2 小时前
重庆合川发布陶行知AI数字人,世优科技提供数字人全栈技术支持
人工智能·科技·数字人·智能交互
百结2142 小时前
Python网络编程
网络·python