客至汲泉烹茶, 抚琴听者知音

【译】PyTorch官方教程第一章:深度学习入门与PyTorch库

这份官方教程在7月初发布的,等到现在好像也没有汉化版,所以直接上手学了,顺便把我翻译的章节放上来。

[scode type="yellow"]本人深度学习小白,英文水平极其有限,大部分地方都借助了翻译软件,仅作为学习过程的记录,大家学的话还是直接看原文或者等其他人翻译。另:有删减。[/scode]

深度学习革命

为了领会这种深度学习方法所带来的范式转变,让我们回过头来看一看。直到过去十年,机器学习严重依赖于特征工程(feature engineering)。特征是对输入数据的转换,便于下游算法(如分类器)在新数据上产生正确的结果。特征工程包括提出正确的变换,以便下游算法能够解决一个任务。例如,为了区分手写数字图像中的1和0,我们会想出一组滤波器来估计图像上的边缘方向,然后训练一个分类器来预测给定边缘方向分布的正确数字。另一个有用的特征可能是封闭的孔的数量,如0、8。

深度学习则从原始数据中自动找到这样的表征,以成功执行任务。在1与0的例子中,过滤器会在训练过程中通过反复观察成对的例子和目标标签来完善。这并不是说深度学习中没有特征工程,我们经常需要在学习系统中注入某种形式的先验知识。然而,神经网络能够摄取数据,并在例子的基础上提取有用的表征,这就是深度学习的强大之处。深度学习从业者的关注点并不在于手动制作这些表征,而是在数学实体上进行操作,使其从训练数据中自主发现表征。通常情况下,这些自动创建的特征比那些手动制作的特征更好!与许多颠覆性技术一样,这一事实导致了观念的改变。

在图1.1的左侧,我们看到一个从业者正在忙着定义工程特征,并将其输入到学习算法中;任务的结果将和从业者的工程特征一样好。右边是深度学习,原始数据被输入到算法中,算法自动提取分层特征,在算法的引导下,优化自己的任务表现;结果将和从业者的表现一样好,以驱动算法向目标前进。

图1.1:由于数据的增长和计算需求,深度学习从手动提取特征中解脱出来

从图1.1的右侧,我们已经可以窥见成功执行深度学习所需要的条件:

  • 我们需要有办法提取我们手头的任何数据。
  • 我们需要以某种方式定义深度学习机器。
  • 我们必须有一种自动化的方式,训练,以获得有用的表征,并使机器产生期望的输出。

这就需要我们仔细研究一下我们一直在说的训练这件事。在训练过程中,我们使用一个标准,一个闹喊模型输出和参考数据的实值函数,为我们模型的期望输出和实际输出之间的差异打分(按照惯例,分数越低越好)。 训练包括通过逐步修改我们的深度学习机器来推动标准向更低的分数发展,直到它达到低分数。

PyTorch

为什么选PyTorch?

  • 它简单易用,足够Pythonic,任何python编程老手都会感到熟悉。具体来说,PyTorch提供了一种数据类型:张量(Tensor),用于存放数字、向量、矩阵、数组等,并提供了相应的函数。如果你熟悉numpy库的话,应该会更容易上手。
  • PyTorch提供了GPU加速计算,这比CPU快了50倍。另外,PyTorch在数据运算方面进行了优化。这两个特性对于任何科学计算都是有用的,因此不打算深度学习的老哥也可以尝试学习。

PyTorch的一个设计驱动因素是表达能力,它允许开发人员实现复杂的模型,而不会因为库(它不是一个框架)过于复杂而受到影响。基于这个原因,PyTorch在研究中得到了广泛的采用,国际会议上的高引用率就证明了这一点

PyTorch配置了C++,这使得它可以在脱离python的环境中运行,这个特性增强了其灵活性。

为了更好学习本书,你需要以下两个条件:

  • 有一定的Python编程经验。我们不打算在教授python上花费时间;你需要了解 Python 数据类型、类、浮点数字等。
  • 愿意深入研究并动手操作。我们将从基础开始,积累我们的工作知识,如果你跟着我们一起学习,你会学得更轻松。

本书专注于实用的PyTorch,目的是覆盖足够的领域,让你能够用深度学习解决现实世界的机器学习问题,比如在视觉领域,或者探索研究文献中出现的新模型。与深度学习研究相关的大部分文献都可以在https://arxiv.org中找到。

PyTorch如何支持深度学习项目

让我们通过研究深度学习项目需要从pytoch中获得什么,来更好地了解PyTorch的构成。

首先,PyTorch的 "Py "如同Python中的 "Py",但其中有很多非Python代码。其实出于性能考虑,PyTorch的大部分代码都是用C++和CUDA(www.geforce. com/hardware/technology/cud)编写的,CUDA是NVIDIA公司的一种类似C++的语言,编译后可以在GPU上大规模并行运行。有一些方法可以直接从C++语言中运行PyTorch,我们将在第15章中讨论这些方法。这个功能的动机之一是为在生产中部署模型提供一个可靠的策略。然而,大多数情况下,我们会从Python中与PyTorch交互,构建模型,训练模型,并使用训练好的模型来解决实际问题。事实上,PyTorch 在可用性和与更广泛的 Python 生态系统集成方面的优势在于 Python API。

正如我们已经提到的,PyTorch 的核心是一个提供多维数组的库,也就是 PyTorch 中的 tensors(我们将在第 3 章中详细介绍),以及 PyTorch 模块提供的大量操作库。在PyTorch中,将计算从CPU转移到GPU上,只需要一两个额外的函数调用即可。PyTorch 提供的第二项核心功能是,张量跟踪对其执行的操作,并分析计算输出相对于任何输入的导数,这是用于数值优化的。

通过拥有 tensors 和支持 autograd 的张量标准库,PyTorch 可用于物理、渲染、优化、模拟、建模等,我们很有可能看到 PyTorch 以创造性的方式应用于各种科学应用中。但 PyTorch 首先是一个深度学习库,因此它提供了构建神经网络并对其进行训练所需的所有构件。图1.2显示了一个标准设置,它加载数据、训练模型,然后将该模型部署到生产中。

图1.2:PyTorch项目结构示意图,包括加载数据、训练与应用

用于构建神经网络的PyTorch核心模块位于torch.nn中,它提供了常见的神经网络层和其他架构组件。全连接层、卷积层、激活函数和损失函数都可以在这里找到(我们将在本书的其他部分详细介绍这些内容)。 这些组件可以用来构建和初始化我们在图 1.2 中看到的未训练模型。为了训练我们的模型,我们需要一些额外的东西:一个训练数据的来源,一个使模型适应训练数据的优化器,以及一个将模型和数据送到硬件的方法,这些硬件将实际执行训练模型所需的计算。

在图 1.2 左侧,我们可以看到,在训练数据到达我们的模型之前,需要进行相当多的数据处理。首先,我们需要获取数据。然后,我们需要将数据中的每个样本转换为PyTorch能够实际处理的东西:tensors。在自定义数据(无论其格式如何)和标准化的 PyTorch tensors之间的桥梁就是 torch.utils.data 中 提供的 Dataset 类。由于这个过程在不同的问题上有很大的不同,所以我们必须自己实现这个数据源。我们将在第 4 章中详细研究如何将我们可能要处理的各种类型的数据表示为 tensors。

由于数据存储往往很慢,特别是由于访问延迟,我们希望能并行化数据加载。但是由于Python的许多优点并不包括简单、高效、并行处理,因此我们需要多个进程来加载数据,以便将它们组合成批处理:包含多个样本的 tensors。这一点比较复杂,但由于它也比较通用,PyTorch在Dataloader类中提供了所有这些神奇的功能。它的实例可以在后台生成子进程来加载数据集的数据,这样,只要训练循环可以使用它,它就可以准备好并等待训练循环。我们将在第7章认识和使用Dataset和DataLoader。

有了获取批量样本的机制,我们可以转向图1.2中心的训练循环本身。通常情况下,训练循环是作为一个标准的Python for循环来实现的。在最简单的情况下,模型在本地CPU或单个GPU上运行所需的计算,一旦训练循环有了数据,就可以立即开始计算。这有可能也是你的基本设置,我们在本书中也会假设这样的设置。

在训练循环的每一步,我们都会对我们从数据加载器中得到的样本评估我们的模型。然后,我们使用一些准则或损失函数将模型的输出与期望的输出(目标)进行比较。正如它提供了用于构建模型的组件一样,PyTorch 也提供了各种损失函数供我们使用。它们也在 torch.nn 中提供。当我们用损失函数将实际输出与理想值进行比较后,我们需要稍微推动模型,使其输出更接近目标值。如前所述,这就是 PyTorch autograd 引擎的作用;但我们还需要一个优化器来进行更新,这就是 torch.optim 中提供的优化器。我们将在第 5 章中开始研究使用损失函数和优化器的训练循环,然后在第 6 章到第 8 章中磨练我们的技能,然后开始我们的大项目,即第二部分。

使用更复杂的硬件,如多个GPU或多台机器,为训练一个大型模型贡献自己的资源,越来越常见,如图1.2底部中心所示。在这些情况下,torch.nn. parallel。DistributedDataParallel和torch.distributed子模块可以被用来使用额外的硬件。

训练循环可能是深度学习项目中最不精彩却最耗时的部分。在它结束时,我们得到了一个模型,它的参数已经在我们的任务上进行了优化:图中训练环路右侧描绘的训练模型。有一个模型来解决任务是很好的,但为了让它有用,我们必须把它放在需要工作的地方。如图1.2所示,这个部署部分可能涉及到将模型放在服务器上,或者将其导出加载到云引擎上,如图所示。或者我们可能会将它与一个更大的应用集成,或者在手机上运行。

部署工作的一个特殊步骤可以是导出模型。如前所述,PyTorch默认为即时执行模式(eager mode)。每当Python解释器执行一条涉及PyTorch的指令时,相应的操作就会立即由底层的C++或CUDA实现执行。随着对 tensors 进行操作的指令增多,后端实现会执行更多的操作。

PyTorch还提供了一种通过TorchScript提前编译模型的方法。使用TorchScript,PyTorch可以将模型序列化为一组指令,这些指令可以独立于Python:比如说,从C++程序或移动设备上调用。我们可以将其视为一个虚拟机,它有一个有限的指令集,特定于张量运算。这使得我们可以导出我们的模型,既可以作为TorchScript与PyTorch运行时一起使用,也可以以一种叫做ONNX的标准格式导出。这些功能是 PyTorch 生产部署能力的基础。我们将在第 15 章中介绍。

硬件与软件要求

本书需要对涉及大量数值计算的任务进行编码和运行,如大量矩阵的乘法。事实证明,在新的数据上运行一个预先训练好的网络,是任何一台最近的笔记本电脑或个人计算机都能做到的。即使是把一个预训练的网络,重新训练一小部分,使其在新的数据集上专业化,也不一定需要专门的硬件。你可以使用标准的个人计算机或笔记本电脑来跟进我们在本书部分内容中所做的一切。

然而,我们预计,完成第2部分中更高级的例子的完整训练运行将需要支持CUDA的GPU。第二部分中使用的默认参数假定GPU的内存为8GB(我们建议使用NVIDIA GTX 1070或更高),但如果你的硬件的可用内存较少,这些参数可以调整。如果你愿意等待的话,这样的硬件不是必须的,但是在GPU上运行可以将训练时间缩短至少一个数量级(通常会快40-50倍)。 单独来看,计算参数更新所需的操作在现代硬件上是很快的(从几分之一秒到几秒),比如典型的笔记本电脑CPU。问题是,训练需要反复运行这些操作,很多很多次,逐步更新网络参数,以减少训练误差。

最后一个考虑因素是操作系统(OS)。 PyTorch从第一个版本开始就支持Linux和macOS,并在2018年支持Windows。由于目前的苹果笔记本电脑不包含支持CUDA的GPU,因此PyTorch的macOS预编译包只支持CPU。在本书中,我们将尽量避免假设您正在运行特定的操作系统,尽管第2部分中的一些脚本显示为在Linux下从Bash提示符运行。这些脚本的命令行应该很容易转换为与Windows兼容的形式。为了方便起见,在可能的情况下,代码会以在Jupyter Notebook上运行的方式列出。

添加新评论