pytorch(一):张量

什么是张量(Tensor)?

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

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

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

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

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

[3, H, W]

张量的创建

1. 直接创建

import torch

# 标量
a = torch.tensor(5)

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

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

2. 常用初始化方法

# 全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. 指定数据类型

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

常见类型:

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

4. 从 NumPy 转换

import numpy as np

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

注意:共享内存!

np_array[0] = 100
print(tensor)  # 会变化

张量的基本属性

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

示例:

print(x.shape)   # (3,4)
print(x.ndim)    # 2

张量运算

1. 基本运算

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. 矩阵运算

A = torch.randn(2, 3)
B = torch.randn(3, 4)

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

3. 广播机制(Broadcasting)

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

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

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

print(a + b)

自动扩展为:

[1,2,3][[1,2,3],
 [1,2,3]]

4. 常见函数

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

x = torch.arange(6)

y = x.reshape(2,3)

2. view(共享内存)

y = x.view(2,3)

区别:

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

3. transpose / permute

x = torch.randn(2,3)

# 转置
x.t()

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

4. squeeze / unsqueeze

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

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 会自动构建:

x → y → loss

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

3. 梯度清零

optimizer.zero_grad()

否则梯度会累加!

4. 禁用梯度

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()   # 断开计算图

实际案例:简单线性回归

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

举个例子:

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

示例

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)

五大重点:

  • 创建与初始化
  • 运算与广播
  • 形状变换
  • 设备管理
  • 自动求导
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值