目录
一、Tensor
1、Tensor简介
(1)张量(Tensor)的解析
理解张量(Tensor),就如同理解深度学习的 DNA。在数据科学和深度学习的世界中,张量(Tensor)犹如一把刀,功能强大,适应范围广泛。你可以将其想象为一个多维大礼盒竹,无论大礼盒内是一个还是多个数据元素,都可以被这个"大礼盒"完美包裹和处理。
(2)张量(Tensor)的类型
在这个数据包裹体系中,可以鲜明地区分出三种基础的类型:一是称为’标量’的O维张量,它就像一颗晶莹剔透的珍珠,孤独地存在于这个宇宙中。二是被名为’向量’的1维张量,它就像一条弯曲的小溪,顺流而下,信息从一个个元素中流淌过去。三是’矩阵’,一个2维张量,就像一张网,在每个交点上,都嵌入了一个数据元素。
(3)张量(Tensor)的维度延伸
张量(Tensor)的独特之处在于它的维度可以无限延伸,如3维张量,4维张量等等,这就好比在一个无尽的宇宙中,每个数据元素都是一个星球,而这些星球又被维度的线索以各种形式连接在一起。
(4)张量(Tensor)在深度学习中的应用
深度学习中对高维张量的处理就如同艺术家对颜色的运用,丰富且细致。比如一批色彩斑斓的图
像 可以被视为一个4维张量,每个维度象征着批
次大小、图像宽度、图像高度和颜色通道。
(5)张量(Tensor)的数学解读
在数学的领域,张量(Tensor)就像一台能同时在多个坐标系统中运行的普适机器。以向量为例,无论你从何种视角去观察,它的长度和方向始终保持恒定,永不改变。
(6)张量(Tensor)的综述
张量(Tensor),作为揭示多维数据的神秘面纱的钥匙,在科学、工程学等领域中都有广泛应
用。特别是在深入探索机器学习和深度学习的过程中,张量(Tensor)无疑是一把锐利的剑,为我们开启了通向知识宝库的大门。
2、Tensor对象及其运算
(1)Tensor的基本属性:
torch.dtype
: 表示Tensor的数据类型,例如torch.float32
、torch.int64
等。torch.device
: 指定Tensor存储的设备,可以是CPU或GPU,以及设备编号。torch.layout
: 描述Tensor的布局方式。
(2)Tensor的创建:
- 可以使用
torch.tensor()
从数据创建Tensor。 - 使用
torch.empty()
、torch.zeros()
、torch.ones()
等可以创建特定形状和类型的Tensor。
(3)Tensor的运算:
- 基本运算: 包括加法、减法、乘法、除法等,使用
+
、-
、*
、/
操作符。 - 逐元素运算: 如
torch.add()
、torch.subtract()
等,这些函数会对两个Tensor进行逐元素操作。 - 线性代数运算: 如矩阵乘法
torch.matmul()
、矩阵逆torch.inverse()
等。 - 索引与切片: 类似于Numpy,可以使用方括号
[]
进行索引和切片操作。 - 变形: 如
reshape
、squeeze
、unsqueeze
等,用于改变Tensor的形状。
(4)自动求导与梯度:
data
: Tensor的实际数据部分。grad
: 数据对应的梯度。grad_fn
: 创建Tensor的函数,是自动求导的关键。requires_grad
: 是否需要计算梯度的标志。
import torch
# 创建一个Tensor
x = torch.tensor([1.0, 2.0, 3.0], dtype=torch.float32)
# 显示Tensor的属性
print(x.dtype) # 输出: torch.float32
print(x.device) # 输出: cpu
print(x.requires_grad) # 输出: False
# Tensor的基本运算
y = torch.tensor([4.0, 5.0, 6.0], dtype=torch.float32)
z = x + y # 逐元素相加
# Tensor的变形
w = x.unsqueeze(0) # 在第0维上增加一个维度
# 自动求导示例
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
y = x * 2
z = y.sum()
z.backward() # 计算梯度
print(x.grad) # 输出: tensor([2., 4., 6.])
3、Tensor的索引和切片
(1)基本索引:
- 可以对一维Tensor使用整数索引访问单个元素。
- 对多维Tensor,需要提供索引列表,每个维度一个索引。
(2)切片:
- 使用
:
符号可以对Tensor进行切片操作,包括单个维度和多个维度的情况。 - 可以设置起始索引、结束索引和步长,默认步长为1。
(3)高级索引:
- 可以使用整数Tensor来进行索引,实现更复杂的索引操作。
- 支持使用布尔值Tensor进行条件选择。
(4)负数索引:
- Tensor支持负数索引,表示从末尾开始计数。
(5)视图与副本:
- 使用
.view()
方法可以改变Tensor的形状而不改变数据。 - 使用
.clone()
或.detach()
可以创建一个Tensor的副本。
import torch
# 创建一个二维Tensor
t = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 基本索引
print(t[0]) # 输出第一行:tensor([1, 2, 3])
# 多维索引
print(t[0, 1]) # 输出第一个元素的第二个维度的值:2
# 切片
print(t[:, 1:3]) # 输出第二列到第三列之间的所有行:
# tensor([[2, 3],
# [5, 6],
# [8, 9]])
# 高级索引
index_tensor = torch.tensor([0, 2])
print(t[index_tensor]) # 输出第1行和第3行:
# tensor([[1, 2, 3],
# [7, 8, 9]])
# 负数索引
print(t[-1]) # 输出最后一行:tensor([7, 8, 9])
# 视图与副本
v = t.view(1, -1) # 将t变为1行9列的二维Tensor
print(v) # 输出:
# tensor([[1, 2, 3, 4, 5, 6, 7, 8, 9]])
c = t.clone() # 或 c = t.detach()
print(id(t), id(c)) # 输出t和c的内存地址,不同地址表示是副本
4、Tensor的变换、拼接和拆分
(1)变换:
- 使用
reshape()
方法可以改变Tensor的形状。 - 使用
transpose()
方法可以交换Tensor的两个维度。 - 使用
permute()
方法可以重新排列Tensor的维度。
(2)拼接:
- 使用
torch.cat()
函数可以将多个Tensor沿着指定维度进行拼接。 - 使用
torch.stack()
函数可以将多个Tensor沿着新的维度进行堆叠。
(3)拆分:
- 使用
torch.split()
函数可以将一个Tensor沿着指定维度进行拆分。 - 使用
torch.chunk()
函数可以将一个Tensor沿着指定维度进行分块。
import torch
# 创建一个Tensor
x = torch.tensor([[1, 2], [3, 4]])
# 变换
y = x.reshape(1, -1) # 将x变为1行4列的二维Tensor
print(y) # 输出:tensor([[1, 2, 3, 4]])
z = x.transpose(0, 1) # 交换第0维和第1维
print(z) # 输出:tensor([[1, 3], [2, 4]])
p = x.permute(1, 0) # 重新排列维度,变为2行2列的二维Tensor
print(p) # 输出:tensor([[1, 3], [2, 4]])
# 拼接
a = torch.tensor([[5, 6]])
b = torch.cat((x, a), dim=0) # 在第0维上拼接x和a
print(b) # 输出:tensor([[1, 2], [3, 4], [5, 6]])
c = torch.stack((x, a), dim=0) # 在第0维上堆叠x和a
print(c) # 输出:tensor([[[1, 2], [3, 4]], [[5, 6], [0, 0]]])
# 拆分
d = torch.split(x, split_size_or_sections=1, dim=0) # 在第0维上拆分x为两个Tensor
print(d[0]) # 输出:tensor([[1, 2]])
print(d[1]) # 输出:tensor([[3, 4]])
e = torch.chunk(x, chunks=2, dim=0) # 在第0维上分块x为两个Tensor
print(e[0]) # 输出:tensor([[1, 2]])
print(e[1]) # 输出:tensor([[3, 4]])
二、PyTorch的Reduction操作
PyTorch的Reduction操作主要包括以下几种:
- 求和(sum):沿着指定维度对张量的元素求和。
- 平均值(mean):沿着指定维度对张量的元素求平均值。
- 最大值(max):沿着指定维度对张量的元素求最大值。
- 最小值(min):沿着指定维度对张量的元素求最小值。
- 乘积(prod):沿着指定维度对张量的元素求乘积。
import torch
# 创建一个张量
x = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)
# 求和
sum_x = x.sum(dim=0)
print("Sum:", sum_x)
# 平均值
mean_x = x.mean(dim=0)
print("Mean:", mean_x)
# 最大值
max_x = x.max(dim=0)
print("Max:", max_x)
# 最小值
min_x = x.min(dim=0)
print("Min:", min_x)
# 乘积
prod_x = x.prod(dim=0)
print("Prod:", prod_x)
输出结果:
>>>Sum: tensor([5., 7., 9.])
>>>Mean: tensor([2.5000, 3.5000, 4.5000])
>>>Max: (tensor([4, 5, 6]), tensor([1, 1, 1]))
>>>Min: (tensor([1, 2, 3]), tensor([0, 0, 0]))
>>>Prod: tensor([ 4., 60., 162.])
三、PyTorch的自动微分
1、自动微分的概念:
- 自动微分(Automatic Differentiation)是一种计算导数的技术,它能够自动计算复杂函数的导数。
- 在深度学习中,自动微分用于计算损失函数关于模型参数的梯度,这是反向传播算法的核心部分。
2、Tensor的属性:
- PyTorch中的Tensor有两个模式:
train
模式和eval
模式。在进行自动微分时,需要将Tensor设置为train
模式。 - 当Tensor执行了操作后,它会记住这些操作的历史,以便之后进行梯度计算。
3、梯度计算:
torch.autograd
能够自动计算任何计算图的梯度。它使用动态图的方式来记录操作历史,这使得调试变得简单。- 在计算梯度时,首先需要调用
.backward()
方法来开始反向传播过程。
4、梯度清零:
- 在每次梯度计算之后,通常需要调用
.zero_()
方法来清零梯度,以便进行下一轮的梯度计算
import torch
# 创建张量并设置requires_grad=True以跟踪计算
x = torch.ones(2, 2, requires_grad=True)
print(x)
# 输出:
# tensor([[1., 1.],
# [1., 1.]], requires_grad=True)
# 简单的运算
y = x + 2
print(y)
# 输出:
# tensor([[3., 3.],
# [3., 3.]], grad_fn=<AddBackward0>)
# 计算梯度
y.backward(torch.tensor([1., 1.], dtype=torch.float32))
print(x.grad)
# 输出:
# tensor([[1., 1.],
# [1., 1.]])
# 清零梯度
x.grad.zero_()
print(x.grad)
# 输出:
# tensor([[0., 0.],
# [0., 0.]])
标签:tensor,torch,张量,学习,维度,PyTorch,深度,print,Tensor
From: https://blog.csdn.net/2201_76007274/article/details/136996128