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)

五大重点:

  • 创建与初始化
  • 运算与广播
  • 形状变换
  • 设备管理
  • 自动求导
相关推荐
冬奇Lab8 分钟前
Agent 系列(21):Harness 测试工程——45 个测试怎么设计,以及它发现了什么 bug
人工智能·llm·agent
冬奇Lab17 分钟前
每日一个开源项目(第133篇):EchoBird - 把 AI 工具的安装和部署做成傻瓜操作
人工智能·开源·资讯
程序员龙叔31 分钟前
编写高质量 Skill 系列 -- 如何设计需求分析与用例生成的 SKILL
自动化测试·软件测试·python·软件测试工程师·接口测试·性能测试·skill·ai测试
IT_陈寒2 小时前
Redis的SETNX并发问题让我加了三天班
前端·人工智能·后端
用户5191495848453 小时前
Windows 渗透测试载荷加载器 POC 工具集
人工智能·aigc
大树883 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
用户8356290780513 小时前
使用 Python 操作 Word 内容控件
后端·python
通信小呆呆3 小时前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
程序猿追3 小时前
那个右下角的小数字怎么“卡”住我打字——我用 HarmonyOS 自己写了一个字数限制输入框
pytorch·华为·harmonyos
施小赞3 小时前
普通 RAG vs GraphRAG 核心对比
人工智能·ai