PyTorch 知识点总结 -- 第 1 节

第 1 节 PyTorch Fundamentals

本节主要讲解 PyTorch 中的基本单位 Tensor(也称为张量),及一系列与 Tensor 有关的函数。


Tensor、维度与形状

函数作用举例输出结果结果描述
torch.tensor()创建一个 Tensor 对象- torch.tensor(7)
- torch.tensor([7, 7])
- tensor(7)
- tensor([7, 7])
将数值 7 和一维数组 [7, 7] 转换为 Tensor 对象
torch.tensor().item()将 Tensor 对象转换为 Python 数据类型- torch.tensor(7).item()
- torch.tensor([7, 7]).item()
- 7
- ERROR
只能转换单个值,不能转换数组
torch.tensor().ndim获取 Tensor 对象的维度- torch.tensor(7).ndim
- torch.tensor([7, 7]).ndim
- torch.tensor([7, 8], [9, 10]).ndim
- 0
- 1
- 2
ndim 函数的作用可以看作计算有几对 嵌套 大括号(平级大括号不计入)
torch.tensor().shape获取 Tensor 对象的形状- torch.tensor(7).shape
- torch.tensor([7, 7]).shape
- torch.tensor([[1, 2, 3], [4, 5, 6]]).shape
- torch.tensor([
[[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]]
]).shape
- torch.Size([])
- torch.Size([2])
- torch.Size([2, 3])
- torch.Size([1, 4, 3]) # 表示第 1 维长度为 1,第 2 维长度为 4,第 3 维长度为 3。此处第 1 维长度为 1 的原因是最外层的大括号只包含 1 个元素即 [[...]]
shape 实际上是一个长度等于 Tensor 维度数的元组,第 i 个元素表示第 i+1 维的大小
如果 Tensor 对象只包含一个数值而非数组,则没有任何维度, shape 值为空;
如果 Tensor 对象包含一个一维数组,则包含 1 个维度, shape 值为该维度的长度,也就是数组的列数;
如果 Tensor 对象包含一个二维数组,则包含 2 个维度, shape 长度为 2,shape[0] 为该数组的行数,shape[1] 为该数组的列数;
如果 Tensor 对象包含一个多维数组,则包含 N 个维度,shape 长度为 N

随机 Tensor、随机数种子、全 0 和全 1 Tensor

神经网络的学习方法通常是随机生成一些初始 Tensors,然后对其进行拟合,使其更准确地描述数据。

函数作用举例输出结果结果描述
torch.rand(row, col)创建形状为 (row, col) 的随机 Tensortorch.rand(3, 4) tensor([
[0.9251, 0.0865, 0.0187, 0.7156],
[0.2475, 0.8762, 0.2020, 0.9959],
[0.6348, 0.5955, 0.9724, 0.3047]
])
每次的输出结果是随机的
torch.rand(size=(width, height, channel))创建形状为 (width, height, channel) 的随机 Tensortorch.rand(size=(224, 224, 3)) tensor([[
[0.4218, 0.1902, 0.3915],
[0.2171, 0.5964, 0.5715],
[0.2390, 0.2073, 0.2960], …,
size 参数可以隐性传入。该函数通常用于处理图像,channel 是图像的颜色通道,设置为 3 表示 RGB。channel 也可以置于参数第一位,即 size=(3, 224, 224)
torch.zeros(size=(row, col))创建形状为 (row, col) 的全 0 Tensortorch.zeros(size=(3, 4)) tensor([
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]
])
size 参数可以隐性传入。torch.ones() 函数同理创建形状为 (row, col) 的全 1 Tensor
torch.manual_seed(int)设置随机数种子torch.manual_seed(42)
torch.rand(3, 4)
tensor([
[0.8823, 0.9150, 0.3829, 0.9593],
[0.3904, 0.6009, 0.2566, 0.7936],
[0.9408, 0.1332, 0.9346, 0.5936]
])
每次生成随机 Tensor 前都需要声明一次该函数

Tensor 数据类型与运算

PyTorch 中的 Tensor 对于整型数组默认使用 torch.int64 类型,对于浮点型数组默认使用 torch.float32 类型,而 Numpy 的数组默认使用 float64 类型,在互相转换时默认类型以转换源为准。

机器学习和深度学习中,使用 Tensor 时有三大易错点:

  1. Tensor 数据类型错误,可使用 tensor.dtype 查看;
  2. Tensor 形状错误,可使用 tensor.shapetensor.size() 查看;
  3. Tensor 设备错误,可使用 tensor.device 查看。
函数作用举例输出结果结果描述
torch.tensor(data, dtype, device, requires_grad=False)创建一个 Tensor 对象 torch.tensor([3.0, 6.0, 9.0],
dtype = None,
device = None,
requires_grad = False)
tensor([3., 6., 9.])dtype 参数指定 Tensor 的数据类型,如 float32float16
device 参数指定处理 Tensor 使用的设备,如 cpucuda
requires_grad 参数设定是否使用该 Tensor 进行梯度跟踪,默认为 False
torch.tensor().type()设置 Tensor 对象的数据类型torch.tensor([1., 2., 3.]).type(torch.float16)tensor([1., 2., 3.], dtype=torch.float16)浮点型 Tensor 可与整型 Tensor 相互运算,最终结果为浮点型
tensor.matmul(tensorA, tensorB)
tensor.mm(tensorA, tensorB)
tensorA @ tensorB
对两个 Tensor 进行矩阵乘法运算tensor = torch.tensor([1, 2, 3])
torch.matmul(tensor, tensor)
tensor([14])矩阵乘法详细描述见表后

矩阵乘法涉及到维度至少为 1 的两个 Tensor,同时需要满足两个条件。设 TensorA = torch.tensor([A1, A2])TensorB = torch.tensor([B1, B2])。使用 torch.tensor().T 可以转置 Tensor 的维度。

  1. 两个 Tensor 的内部维度必须相同。在上述条件中, A2B1 为内部维度,即需要满足 A2 = B1
  2. 结果矩阵的 shape 等于两个 Tensor 的外部维度。在上述条件中,A1B2 为外部维度,则结果矩阵的 shape = (A1, B2)

对于两个一维 Tensor,结果矩阵就是对应项相乘的和;

对于两个二维及以上多维 Tensor,可视化举例如下说明。

tensorA = torch.tensor([[1, 2],
                        [3, 4],
                        [5, 6]])
tensorB = torch.tensor([[7, 8],
                        [9, 10],
                        [11, 12]])
# tensorA.shape = torch.Size([3, 2]), tensorB.shape = torch.Size([3, 2])

# 两个 Tensor 的内部维度不同,不能运算。此时需要对其中一个 Tensor 转置,如 tensorB.T。

tensorB = tensorB.T	# tensorB = torch.tensor([[7, 8, 9],
				  #						 [10, 11, 12]])
				  # tensorB.shape = [2, 3]
        
# 现在做 tensor.matmul(tensorA, tensorB) 运算。可将 tensorB 先逆时针旋转 90° 并置于 tensorA 上方,得到:
# [9, 12] -> tensorB 第一行
# [8, 11] -> tensorB 第二行
# [7, 10] -> tensorB 第三行
# -------
# [1, 2] -> tensorA 第一行
# [3, 4] -> tensorA 第二行
# [5, 6] -> tensorA 第三行

# 第一步,将 tensorB 向下移动一次,使第三行与 tensorA 的第一行相乘,得到 1*7+2*10=27,放入结果矩阵的 [0, 0] 处
# 第二步,将 tensorB 向下移动一次,使第三行与 tensorA 的第二行相乘,得到 3*7+4*10=61,放入结果矩阵的 [1, 0] 处;同时,第二行与 tensorA 的第一行相乘,得到 1*8+2*11=30,放入结果矩阵的 [0, 1] 处
# 第三步,将 tensorB 向下移动一次,使第三行与 tensorA 的第三行相乘,得到 5*7+6*10=95,放入结果矩阵的 [2, 0]处;同时,第二行与 tensorA 的第二行相乘,得到 3*8+4*11=68,放入结果矩阵的 [1, 1] 处;第一行与 tensorA 的第一行相乘,得到 1*9+2*12=33,放入结果矩阵的 [0, 2]处
# 第四步,将 tensorB 向下移动一次,使第二行与 tensorA 的第三行相乘,得到 5*8+6*11=106,放入结果矩阵的 [2, 1]处;同时,第一行与 tensorA 的第二行相乘,得到 3*9+4*12=75,放入结果矩阵的 [1, 2] 处
# 第五步,将 tensorB 向下移动一次,使第一行与 tensorA 的第三行相乘,得到 5*9+6*12=117,放入结果矩阵的 [2, 2] 处
结果矩阵可视化步骤如下:

[ - - - ]    [ 27 - - ]    [ 27 30 - ]    [ 27 30 33 ]    [ 27 30 33 ]    [ 27  30  33 ]
[ - - - ] -> [ - - -  ] -> [ 61 - -  ] -> [ 61 68 -  ] -> [ 61 68 75 ] -> [ 61  68  75 ]
[ - - - ]    [ - - -  ]    [ - - -   ]    [ 95 - -   ]    [ 95 106 - ]    [ 95 106 117 ]

Tensor 最小值、最大值及其索引、平均值、和

函数作用举例输出结果结果描述
torch.arange(start, end, step)step 为步长创建 [start, end) 序列torch.arange(0, 100, 10)tensor([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])结果包括 start 端点,不包括 end 端点
torch.min()获取一个 Tensor 序列中的最小值torch.min(torch.arange(0, 100, 10))tensor(0)也可使用 torch.arange().min() 的形式,torch.max()同理
torch.mean()获取一个 Tensor 序列中所有值的平均值torch.mean(torch.arange(0, 100, 10).type(torch.float32))tensor(45.)也可使用类似于 torch.arange(int).type(torch.float32).mean()的形式,该函数的参数只能是浮点数类型或复数类型
torch.sum()获取一个 Tensor 序列中所有值的和torch.sum(torch.arange(0, 100, 10))tensor(450)也可使用 torch.arange().sum() 的形式
argmin()获取 Tensor 最小值的索引torch.arange(0, 100, 10).argmin()tensor(0)
argmax()获取 Tensor 最大值的索引torch.arange(0, 100, 10).argmax()tensor(9)

Reshape, View, Stack, Squeeze, Unsqueeze 和 Permute

  • Reshape:将一个 Tensor 重塑到定义的 shape,重塑后的 Tensor 与原 Tensor 各自独立。
  • View:返回一个特定形状的 Tensor 的副本,和原 Tensor 共用内存。修改该副本会修改原 Tensor 的值。
  • Stack:将多个 Tensor 拼接,类型包括 vstackhstack。使用 dim 参数指定新维度拼接的位置
  • Squeeze:移除 Tensor 中所有维数为 1 的维度。
  • Unsqueeze:添加一个维数为 1 的维度到指定 Tensor 中,使用 dim 参数指定添加的位置。
  • Permute:返回一个输入 Tensor 的副本,与原 Tensor 共用内存,其中维度以特定方式排列。

示例见如下代码块:

x = torch.arange(1., 10.) 
# -> x = tensor([1., 2., 3., 4., 5., 6., 7., 8., 9.]), x.shape = torch.Size([9]), x.ndim = 1

# Reshape
x_reshaped = x.reshape(1, 9) # 将 x 重塑为一个 size=(1, 9) 的二维张量
# -> x_reshaped = tensor([[1., 2., 3., 4., 5., 6., 7., 8., 9.]]), x_reshaped.shape = torch.Size([1, 9])

# View
z = x.view(1, 9) # -> z = tensor([1., 2., 3., 4., 5., 6., 7., 8., 9.])
z[:, 0] = 5 # 将 z 中所有行第 1 列的值设置为 5
# -> z = tensor([5., 2., 3., 4., 5., 6., 7., 8., 9.]), x = tensor([5., 2., 3., 4., 5., 6., 7., 8., 9.])

# Stack
x_stacked = torch.stack([x, x, x, x], dim=0) # torch.stack 的作用是把一组形状相同的张量沿着一个新的维度拼起来,dim 就是用来指定这个“新维度”要放在哪个位置。此处的 x.shape = [9],将 dim 置 0 等价于 x.unsqueeze(0),x.shape 变为 [1, 9],再将 4 个 x 在第 0 维拼起来,得到 x_stacked.shape = torch.Size([4, 9]);如果置 1,则等价于 x.unsqueeze(1),x.shape 变为 [9, 1],最终结果为 x_stacked.shape = torch.Size([9, 4])。对于一维张量,dim 只能置 0 或 1,更高维度的张量才能使用更大的 dim 值
# -> x_stacked = tensor([[5., 2., 3., 4., 5., 6., 7., 8., 9.],
#                        [5., 2., 3., 4., 5., 6., 7., 8., 9.],
#                        [5., 2., 3., 4., 5., 6., 7., 8., 9.],
#                        [5., 2., 3., 4., 5., 6., 7., 8., 9.]]), x_squeezed.ndim = 2

# Squeeze
x_squeezed = x_reshaped.squeeze()
# -> x_squeezed = tensor([5., 2., 3., 4., 5., 6., 7., 8., 9.]), x_squeezed.shape = torch.Size([9])

# Unsqueeze
x_unsqueezed = x_squeezed.unsqueeze(dim=1) # 此处 dim 的作用与 torch.stack 中的 dim 相同
# -> x_unsqueezed = tensor([[5.],
#                           [2.],
#                           [3.],
#                           [4.],
#                           [5.],
#                           [6.],
#                           [7.],
#                           [8.],
#                           [9.]]), x_unsqueezed.shape = torch.Size([9, 1])

# Permute
x_original = torch.rand(size=(224, 224, 3))
x_permuted = x_original.permute(2, 0, 1) # 将 x_original 的第 0 位,即第 1 个 224 放入置 0 的位,以此类推
# -> x_original.shape = torch.Size([224, 224, 3]), x_permuted = torch.Size([3, 224, 224])

PyTorch 和 Numpy

函数作用举例输出结果结果描述
torch.from_numpy(ndarray)将 Numpy 数据转换到 Tensortorch.from_numpy(np.arange(1.0, 8.0))tensor([1., 2., 3., 4., 5., 6., 7.], dtype=torch.float64)Numpy 数组的默认数据类型为 float64,转换为 Tensor 保留类型为 torch.float64
torch.Tensor.numpy()将 Tensor 转换到 Numpy 数据torch.ones(7).numpy()array([1., 1., 1., 1., 1., 1.], dtype=float32)Tensor 默认数据类型为 torch.float32,转换为 Numpy 数组保留类型为 float32

CPU 和 GPU

函数作用举例输出结果结果描述
torch.cuda.is_available() # bool返回 CUDA 是否可用device = “cuda” if torch.cuda.is_available() else “cpu”
device
'cuda'如果环境中 CUDA 可用则输出 cuda,否则输出 cpu
torch.cuda.device_count()返回当前可用的 CUDA 设备数量torch.cuda.device_count()1
torch.tensor().to(device)将 Tensor 放入 GPU 处理tensor_on_gpu = torch.tensor([1, 2, 3]).to(device)
tensor_on_gpu
tensor([1, 2, 3], device='cuda:0')
torch.tensor().to(device).cpu()将工作在 GPU 上的 Tensor 放入 CPU 处理tensor_on_gpu.cpu().numpy()array([1, 2, 3])Numpy 工作在 CPU 上,TensorFlow 和 PyTorch 工作在 GPU 上,转换为 Numpy 需要首先将 GPU 中的 Tensor 放回 CPU
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值