【深度学习】PyTorch框架(1):PyTorch基础

1.引言

PyTorch专辑的知识源于2023年阿姆斯特丹大学深度学习课程的PyTorch入门教程,旨在为程序员提供PyTorch基础的简洁介绍,并帮助您配置环境,以便编写自己的神经网络。PyTorch是一个开源的机器学习框架,它允许您自定义神经网络,并有效地进行优化。尽管PyTorch并非唯一的机器学习框架,但它有其独特的优势。其他类似的框架包括TensorFlow、JAX和Caffe。我们选择介绍PyTorch的相关知识,主要是因为它已经非常成熟,拥有庞大的开发者社群(最初由Facebook开发),并且因其灵活性和在研究领域的广泛应用而受到青睐。许多当前的研究论文都使用PyTorch进行代码发布,因此,熟悉PyTorch对您来说将是一个宝贵的技能。与此同时,TensorFlow(由Google开发)通常被认为是一个适合生产环境的深度学习库。然而,一旦您深入理解了一个机器学习框架,学习另一个框架就会变得相对容易,因为它们之间共享许多相同的概念和思想。例如,TensorFlow的第二版在很多方面都受到了PyTorch的启发,使得这两个框架在某些方面更加相似。

我们选择分享此专辑旨在为您提供特别为实践课程设计的基础知识,同时深入理解PyTorch的内部工作原理。在接下来的几周里,我们还将继续通过一系列关于深度学习的博文,探索PyTorch的新特性。

1.1.导入程序包

# 导入标准库  
import os  # 用于与操作系统交互,如文件路径操作  
import math  # 提供数学函数和常量  
import numpy as np  # NumPy库,提供大量的数学函数操作以及高性能的多维数组对象  
import time  # 提供时间相关的函数  
  
# 导入绘图库  
import matplotlib.pyplot as plt  # Matplotlib的pyplot模块,提供了类似于MATLAB的绘图系统  
%matplotlib inline  # 在Jupyter Notebook中使matplotlib绘制的图形能够内嵌显示  
from IPython.display import set_matplotlib_formats  # IPython的显示模块,用于设置图形的输出格式  
set_matplotlib_formats('svg', 'pdf')  # 设置图形输出的格式为SVG和PDF,便于导出和高质量打印  
from matplotlib.colors import to_rgba  # 用于颜色转换的函数,将颜色名称或颜色代码转换为RGBA格式  
import seaborn as sns  # Seaborn库,基于matplotlib的高级绘图库,提供了更多样化的绘图样式和调色板  
sns.set()  # 设置Seaborn的默认样式,使其绘制的图形更加美观  
  
# 导入进度条库  
from tqdm.notebook import tqdm  # tqdm的notebook版本,用于在Jupyter Notebook中显示进度条  
# 注意:tqdm中文注释本身是不必要的,因为tqdm本身就是一个进度条工具,这里的注释只是说明其用途  

2.Pytorch基础

我们将从回顾PyTorch的非常基础的概念开始。作为先决条件,我们建议您熟悉numpy包,因为大多数机器学习框架都基于非常相似的概念。如果您还不熟悉numpy,不用担心,后续章节将进行详细介绍。

那么,让我们从导入PyTorch开始。该包称为torch,基于其原始框架Torch。作为第一步,我们可以检查其版本:

import torch
print("Using torch", torch.__version__)
Using torch 2.1.0

在编写本文时,最新的版本是2.1。因此,您应该看到输出为"Using torch 2.1.0"或"Using torch 2.0.0",最终可能在Colab上有一些CUDA版本的扩展。如果您使用dl2023环境,您应该看到"Using torch 2.1.0"。通常,建议将PyTorch版本保持更新到最新版本。如果您看到的版本号低于2.0,请确保您已安装正确的环境。如果在本文发布之后,PyTorch 2.2或更新版本,你也不用担心,PyTorch版本之间的接口变化不大,因此所有代码也应该可以与新版本一起运行。

正如在每个机器学习框架中一样,PyTorch提供了诸如生成随机数等随机函数。然而,一个非常好的实践是设置您的代码,以便使用完全相同的随机数进行可重复性。这就是为什么我们在下面设置了一个种子。

torch.manual_seed(42) # 设置种子
<torch._C.Generator at 0x7fa327d6da90>

2.1.张量

张量是PyTorch对numpy数组的等价物,另外还支持GPU加速。名称“tensor”是对您已经知道的概念的概括。例如,向量是一维张量,矩阵是二维张量。在使用神经网络时,我们将使用各种形状和不同维度数量的张量。

您从numpy知道的大多数常用函数也可以在张量上使用。实际上,由于numpy数组与张量非常相似,我们可以将大多数张量转换为numpy数组(反之亦然),但我们不需要经常这样做。

2.1.1.初始化

让我们首先看看以不同方式创建张量。有许多可能的选项,最简单的是调用torch.Tensor并传递所需的形状作为输入参数:

x = torch.Tensor(2, 3, 4)
print(x)

该函数torch.Tensor为所需的张量分配内存,但会重用已经在内存中的任何值。要在初始化期间直接为张量分配值,有许多替代方案,包括:

  • torch.zeros: 创建一个填充零的张量
  • torch.ones: 创建一个填充一的张量
  • torch.rand: 创建一个在0和1之间均匀采样的随机值张量
  • torch.randn: 从均值为0,方差为1的正态分布中采样随机值的张量
  • torch.arange: 创建一个包含值 N , N + 1 , N + 2 , . . . , M N, N+1, N+2, ..., M N,N+1,N+2,...,M的张量
  • torch.Tensor (input list): 根据您提供的列表元素创建一个张量

从嵌套列表创建张量

x = torch.Tensor([[1, 2], [3, 4]])
print(x)
tensor([[1., 2.],
        [3., 4.]])

创建一个形状为[2, 3, 4]的0到1之间的随机值张量

x = torch.rand(2, 3, 4)
print(x)

您可以像在numpy中一样(x.shape)获取张量的形状,或者使用.size方法:

shape = x.shape
print("Shape:", x.shape)

size = x.size()
print("Size:", size)

dim1, dim2, dim3 = x.size()
print("Size:", dim1, dim2, dim3)
Shape: torch.Size([2, 3, 4])
Size: torch.Size([2, 3, 4])
Size: 2 3 4
2.1.2.张量与Numpy数组的转换

张量可以转换为Numpy数组,反之亦然。要将Numpy数组转换为张量,我们可以使用torch.from_numpy函数:

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

print("Numpy 数组:", np_arr)
print("PyTorch 张量:", tensor)
Numpy 数组: [[1 2]
 [3 4]]
PyTorch 张量: tensor([[1, 2],
        [3, 4]])

要将PyTorch张量转换回Numpy数组,我们可以在张量上使用.numpy()方法:

tensor = torch.arange(4)
np_arr = tensor.numpy()

print("PyTorch 张量:", tensor)
print("Numpy 数组:", np_arr)
PyTorch 张量: tensor([0, 1, 2, 3])
Numpy 数组: [0 1 2 3]

将张量转换为Numpy需要确保张量位于CPU上,而不是GPU上(关于GPU支持的更多信息将在后面的部分介绍)。如果您有一个在GPU上的张量,您需要先调用.cpu()方法。因此,您会看到类似np_arr = tensor.cpu().numpy()的代码行。

2.1.3.操作

大多数在numpy中存在的操作,在PyTorch中也同样存在。可以在PyTorch文档中找到操作的完整列表,但我们将在这里回顾最重要的一些操作。

最简单的操作是将两个张量相加:

x1 = torch.rand(2, 3)
x2 = torch.rand(2, 3)
y = x1 + x2

print("X1", x1)
print("X2", x2)
print("Y", y)
X1 tensor([[0.1053, 0.2695, 0.3588],
        [0.1994, 0.5472, 0.0062]])
X2 tensor([[0.9516, 0.0753, 0.8860],
        [0.5832, 0.3376, 0.8090]])
Y tensor([[1.0569, 0.3448, 1.2448],
        [0.7826, 0.8848, 0.8151]])

调用x1 + x2会创建一个新的张量,包含两个输入的和。然而,我们也可以进行就地操作,这些操作直接在张量的内存上应用。因此,我们可以在操作前改变x2的值,而没有机会重新访问操作前x2的值。下面展示了一个例子:

x1 = torch.rand(2, 3)
x2 = torch.rand(2, 3)
print("X1(之前)", x1)
print("X2(之前)", x2)
x2.add_(x1)
print("X1(之后)", x1)
print("X2(之后)", x2)
X1(之前) tensor([[0.5779, 0.9040, 0.5547],
        [0.3423, 0.6343, 0.3644]])
X2(之前) tensor([[0.7104, 0.9464, 0.7890],
        [0.2814, 0.7886, 0.5895]])
X1(之后) tensor([[0.5779, 0.9040, 0.5547],
        [0.3423, 0.6343, 0.3644]])
X2(之后) tensor([[1.2884, 1.8504, 1.3437],
        [0.6237, 1.4230, 0.9539]])

就地操作通常以下划线后缀标记(例如,使用add_而不是add)。

另一个常见操作是改变张量的形状。大小为(2,3)的张量可以重新组织为任何其他具有相同元素数量的形状(例如,大小为(6)或(3,2)等)。在PyTorch中,这个操作称为view

x = torch.arange(6)
print("X", x)
X tensor([0, 1, 2, 3, 4, 5])
x = x.view(2, 3)
print("X", x)
X tensor([[0, 1, 2],
        [3, 4, 5]])
x = x.permute(1, 0) # 交换第0维和第1维
print("X", x)
X tensor([[0, 3],
        [1, 4],
        [2, 5]])

在神经网络的构建中,矩阵乘法是一项不可或缺的操作。想象一下,我们手头有一个输入向量 x \mathbf{x} x,它通过一个训练得到的权重矩阵 W \mathbf{W} W 被转换。实现矩阵乘法有多种方法和函数,以下是一些常用的方法:

  • torch.matmul:对两个张量执行矩阵乘积操作,其行为依据张量的维度而定。若两个输入均为矩阵(即二维张量),它将执行标准的矩阵乘法。对于更高维度的张量,该函数支持广播机制(详见官方文档)。此外,也可以使用 a @ b 的形式,与numpy中的操作类似。
  • torch.mm:对两个矩阵执行矩阵乘法,但不提供广播支持(更多信息见官方文档)。
  • torch.bmm:支持批次(batch)维度的矩阵乘法。假设第一个张量 T T T 的形状为 ( b × n × m ) (b \times n \times m) (b×n×m),第二个张量 R R R 的形状为 ( b × m × p ) (b \times m \times p) (b×m×p),则输出 O O O 的形状为 ( b × n × p ) (b \times n \times p) (b×n×p),它是通过对 T T T R R R 的子矩阵执行 b b b 次矩阵乘法来计算的: O i = T i @ R i O_i = T_i @ R_i Oi=Ti@Ri
  • torch.einsum:使用爱因斯坦求和约定执行矩阵乘法及其他操作(例如乘积的和)。关于爱因斯坦求和的详细解释可以在作业1中找到。

通常情况下,我们会选择使用 torch.matmul 或者 torch.bmm。下面我们将通过 torch.matmul 来演示一次矩阵乘法。

首先,我们创

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MUKAMO

你的鼓励是我们创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值