2025-04-23 Python深度学习3——Tensor
文章目录
- 1 张量
- 1.1 数学定义
- 1.2 PyTorch中的张量
- 2 创建 Tensor
- 2.1 直接创建
- **`torch.tensor()`**
- **`torch.from_numpy()`**
- 2.2 依据数值创建
- **`torch.zeros() / torch.zeros_like()`**
- **`torch.ones() / torch.ones_like()`**
- **`torch.full() / torch.full_like()`**
- **`torch.arange() / torch.linspace`**
- **`torch.eye()`**
- 2.3 依概率分布创建张量
- **`torch.normal()`**
- **`torch.rand() / torch.rand_like()`**
- **`torch.randint() / torch.randint_like()`**
- **`torch.randperm()`**
- **`torch.bernoulli()`**
- 3 张量操作
- 3.1 拼接
- **`torch.cat()`**
- **`torch.stack()`**
- 3.2 切分
- **`torch.chunk()`**
- **`torch.split()`**
- 3.3 索引
- **`torch.index_select()`**
- **`torch.masked_select()`**
- 3.4 变换
- **`torch.reshape()`**
- **`torch.transpose()`**
- **`torch.t()`**
- **`torch.squeeze()`**
- **`torch.unsqueeze()`**
- 4 线性回归案例
本文环境:
- Pycharm 2025.1
- Python 3.12.9
- Pytorch 2.6.0+cu124
1 张量
1.1 数学定义
- 张量是多维数组的泛化形式,涵盖标量(0维)、向量(1维)、矩阵(2维)及更高维结构。
- 示例:
- RGB 图像用三维张量表示,维度为
(高度, 宽度, 通道数)
,其中通道对应红、绿、蓝三色。
- RGB 图像用三维张量表示,维度为

1.2 PyTorch中的张量
PyTorch 中的张量不仅是多维数组,还是自动求导(Autograd)的核心组件。PyTorch 0.4.0 之前,Variable
类型封装张量以实现自动求导;0.4.0后合并到Tensor
中,简化了API。
Variable
Variable 是 torch.autograd 中的数据类型,主要用于封装 Tensor,进行自动求导。
data
:被包装的 Tensor。grad
:data 的梯度。grad_fn
:创建 Tensor 的 Function,是自动求导的关键。requires_grad
:指示是否需要梯度。is leaf
:指示是否是叶子结点(张量)。

PyTorch0.4.0 版开始,Variable 并入 Tensor。
dtype
:张量的数据类型,如torch.FloatTensor
,torch.cuda.FloatTensor
。shape
:张量的形状,如 (64, 3, 224, 224)。device
:张量所在设备,GPU/CPU,是加速的关键。

数据类型分类
- 浮点型:
torch.float16
、torch.float32
(常用)、torch.float64
。 - 整型:
torch.int8
、torch.uint8
、torch.int16
、torch.int32
、torch.int64
(标签常用)。 - 布尔型:
torch.bool
。
2 创建 Tensor
2.1 直接创建
torch.tensor()

功能:直接创建张量。
data
:输入数据(列表或 NumPy 数组)。dtype
:数据类型(默认与输入一致)。device
:设备(如cuda:0
)。requires_grad
:是否需要梯度(默认False
)。pin_memory
:是否锁页内存(通常False
)。
import torch
import numpy as nparr = np.ones((3, 3))
t = torch.tensor(arr, device='cuda:0', requires_grad=True)t

torch.from_numpy()

功能:从 numpy 创建 tensor。
特点:与 NumPy 数组共享内存,修改一方会影响另一方。

arr = np.array([[1, 2, 3], [4, 5, 6]])
t = torch.from_numpy(arr)arr, t

修改 arr 中的数据后,t 中的数据也发生变化。
arr[0, 0] = -1arr, t

2.2 依据数值创建
torch.zeros() / torch.zeros_like()


功能:依 size 创建全 0 张量 / 依 input 形状创建全 0 张量。
-
torch.zeros()
-
size
:张量的形状,如(3,3)、(3, 224, 224)。 -
out
:将输出张量赋值给哪个张量。 -
layout
:内存中布局形式,有 strided,sparse_coo 等。
-
-
torch.zeros_like()
input
:创建与 input 同形状的全 0 张量。memory_format
:张量的内存格式,默认为torch.preserve_format
。
out_t = torch.tensor([1])
t = torch.zeros((3, 3), out=out_t) # out_t会被覆盖为全零t, out_t, id(t), id(out_t) # out_t和t内存一致

torch.ones() / torch.ones_like()
功能:依 size 创建全 1 张量 / 依 input 形状创建全 1 张量。
与 torch.zeros() / torch.zeros_like()
类似。
torch.full() / torch.full_like()

功能:依 size 创建全 fill_value 张量 / 依 input 形状创建全 fill_value 张量。
size
:张量的形状,如 (3, 3)。fill_value
:张量的值。
torch.arange() / torch.linspace


-
torch.arange
创建等差数列,区间为
[start, end)
,公差为step
。torch.arange(2, 10, 2)
-
torch.linspace
创建均分数列,区间为
[start, end]
,个数为steps
。torch.linspace(2, 10, 9)

torch.eye()

功能:创建单位对角矩阵(2维张量),默认为方阵。
n
:每阵行数。m
:矩阵列数。
torch.eye(3, 5)

2.3 依概率分布创建张量
torch.normal()

功能:生成正态分布(高斯分布)
mean
:均值。std
:标准差。
依据 mean
和 std
的类型,可分为四种模式:
-
mean
为标量,std
为标量(需指定size
)torch.normal(0, 1, size=(4, 1))
-
mean
为标量,std
为张量(输出形状与std
一致)mean = 1 std = torch.arange(1, 5, dtype=torch.float) t = torch.normal(mean, std)mean, std, t
-
mean
为张量,std
为标量(输出形状与mean
一致)mean = torch.arange(1, 5, dtype=torch.float) std = 1 t = torch.normal(mean, std)mean, std, t
-
mean
为张量,std
为张量(每个元素从不同分布采样)mean = torch.arange(1, 5, dtype=torch.float) std = torch.arange(1, 5, dtype=torch.float) t = torch.normal(mean, std)mean, std, t
torch.randn() / torch.randn_like()

功能:生成标准正态分布 / 依 input 形状生成标准正态分布(均值为 0,方差为 1)。
size
:张量的形状。generator
:用于采样的为随机数生成器。
torch.randn((3, 2))

torch.rand() / torch.rand_like()

功能:在区间 [0, 1) 上,生成均匀分布。
torch.rand((3, 2))

torch.randint() / torch.randint_like()

功能:区间 [low, high) 生成整数均匀分布。
-
low
:区间左值。 -
high
:区间右值。 -
size
:张量的形状。
torch.randint(0, 10, (3, 2))

torch.randperm()

功能:生成生成从 0 到 n-1 的随机排列。
n
:张量的长度。
torch.randperm(8)

torch.bernoulli()

功能:以 input 为概率,生成伯努力分布(0-1 分布,两点分布)
input
:表示概率值的张量。
t, torch.bernoulli(t)

3 张量操作
3.1 拼接
torch.cat()

功能:将张量按维度 dim 进行拼接,需要保证其他维度大小相同。
tensors
:张量序列。dim
:要拼接的维度。
t = torch.ones((2, 3))t_0 = torch.cat([t, t], dim=0)
t_1 = torch.cat([t, t], dim=1)t_0, t_1

torch.stack()

功能:在新创建的维度 dim 上进行堆叠,所有输入张量的形状必须一致。
tensors
:张量序列。dim
:要堆叠的维度。
t1 = torch.tensor([1, 2])
t2 = torch.tensor([3, 4])
t_stack = torch.stack([t1, t2], dim=0)
t_stack, t_stack.shape

3.2 切分
torch.chunk()

功能:将张量按维度 dim 进行平均切分。
返回值:张量列表。
注意事项:若不能整除,最后一份张量小于其他张量。
input
:要切分的张量。chunks
:要切分的份数。dim
:要切分的维度。
t = torch.ones((2, 5))
list_t = torch.chunk(t, 2, dim=1)
list_t

torch.split()

功能:将张量按维度 dim 进行切分。
返回值:张量列表。
tensor
:要切分的张量。split_size_or_sections
:- 为 int 时,表示每一份的长度;
- 为 list 时,list 中每个元素表示切割的长度,list 中元素之和与维度不等时报错。
dim
:要切分的维度。
t = torch.ones((2, 5))
list_t = torch.split(t, 2, dim=1)
list_t

3.3 索引
torch.index_select()

功能:在维度 dim 上,按 index 索引数据。
返回值:依 index 索引数据拼接的张量。
input
:要索引的张量。dim
:要索引的维度。index
:要索引数据的序号,类型需要为 long。
t = torch.randint(0, 9, size=(3, 3))
t_index = torch.tensor([0, 2])
t_select = torch.index_select(t, dim=1, index=t_index)t, t_select

torch.masked_select()

功能:按 mask 中的 True 进行索引。
返回值:一维张量。
input
:要索引的张量。mask
:与 input 同形状的布尔类型张量。
t = torch.randint(0, 9, size=(3, 3))
t_mask = t.ge(5) # ge is mean greater than or equal
t_select = torch.masked_select(t, mask=t_mask)t_mask, t_select

3.4 变换
torch.reshape()

功能:变换张量形状。
注意事项:当张量在内存中是连续时,新张量与 input 共享数据内存。
input
:要变换的张量。shape
:新张量的形状。
t = torch.randperm(8)t, t.reshape((2, -1)) # -1 表示自动计算,(2, -1) 等价于 (2, 4)

torch.transpose()

功能:交换张量的两个维度。
input
:要变换的张量。dim0
:要交换的维度。dim1
:要交换的维度。
t = torch.rand((2, 3, 4))
t_transpose = torch.transpose(t, dim0=1, dim1=2)t, t_transpose

torch.t()

功能:2 维张量转置,对矩阵而言,等价于 torch.transpose(input, 0, 1)
。
torch.squeeze()

功能:压缩长度为 1 的维度(轴)
dim
- 若为 None,移除所有长度为 1 的轴;
- 若指定维度,当且仅当该轴长度为 1 时,可以被移除。
t = torch.rand((1, 2, 3, 1))
t_sq = torch.squeeze(t)
t_sq0 = torch.squeeze(t, dim=0)
t_sq1 = torch.squeeze(t, dim=1)t.shape, t_sq.shape, t_sq0.shape, t_sq1.shape

torch.unsqueeze()

功能:依据 dim 扩展维度。
dim
:扩展的维度。
4 线性回归案例
import torch
import matplotlib.pyplot as plt# 生成随机数据点,x为0-10之间的随机数
x = torch.rand(20) * 10
# y基于x线性生成,并添加一些噪声
y = 2 * x + torch.randn(20) * 3# 初始化权重w和偏置b,requires_grad=True表示它们在后续计算中需要梯度
w = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)# 定义学习率
lr = 0.01# 迭代200次进行梯度下降
for i in range(200):# 计算预测值y_pred = w * x + b# 计算损失,均方误差的一半loss = torch.mean(0.5 * (y_pred - y) ** 2) / len(x)# 反向传播计算梯度loss.backward()# 更新权重w和偏置b,注意使用.no_grad()确保更新操作不被跟踪w.data -= lr * w.gradb.data -= lr * b.grad# 清零梯度,为下一次迭代做准备w.grad.zero_()b.grad.zero_()# 每20次迭代显示一次当前的数据分布和拟合直线if (i + 1) % 20 == 0:plt.rcParams['figure.figsize'] = (2.0, 1.6)# 绘制散点图plt.scatter(x.numpy(), y.numpy(), s=3)# 绘制当前拟合的直线plt.plot(x.numpy(), y_pred.detach().numpy(), 'r-', lw=0.5)# 显示当前的损失plt.text(2, 15, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 8, 'color': 'red'})plt.title('Iteration: {:d}'.format(i + 1))# 暂停0.5秒,以便观察变化plt.pause(0.5)
