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)

五大重点:

  • 创建与初始化
  • 运算与广播
  • 形状变换
  • 设备管理
  • 自动求导
相关推荐
OneThingAI2 分钟前
网心算力云上线 DeepSeek-V4-Pro
人工智能·aigc·deepseek·onethingai
2501_927283587 分钟前
荣联汇智助力天津艺虹打造“软硬一体”智慧工厂,全流程自动化引领印刷包装行业数智变革
大数据·运维·数据仓库·人工智能·低代码·自动化
小程故事多_807 分钟前
[大模型面试系列] 多轮对话 Agent 设计实战(含窗口优化 + 工具调用精髓)
人工智能·面试·职场和发展
victory043113 分钟前
论文设计和撰写1
人工智能·深度学习·机器学习
2401_8323655238 分钟前
JavaScript中rest参数(...args)取代arguments的优势
jvm·数据库·python
Sirius.z40 分钟前
第J3周:DenseNet121算法详解
python
2301_779622411 小时前
Go语言怎么用信号量控制并发_Go语言semaphore信号量教程【入门】
jvm·数据库·python
love530love1 小时前
精简版|Claude-HUD 插件介绍 + 一键安装教程
人工智能·windows·笔记
2301_766283441 小时前
c++如何将控制台输出保存到文件_cout重定向到txt【详解】
jvm·数据库·python
冬奇Lab1 小时前
RAG 系列(四):文档处理——从原始文件到高质量 Chunk
人工智能·llm·源码