使用 PyTorch 进行深度学习(9 天迷你课程)

深度学习是一个迷人的研究领域,其技术在一系列具有挑战性的机器学习问题中取得了世界级的成果。然而,深度学习入门可能很困难。
您应该使用哪个库,以及应该关注哪些技术?

在这个由 9 部分组成的速成课程中,您将使用易于使用且功能强大的 PyTorch 库发现 Python 中的应用深度学习。本迷你课程面向已经熟悉 Python 编程并了解机器学习基本概念的从业者。让我们开始吧。

这是一篇很长且很有用的文章。您可能希望将其打印出来。

让我们开始吧。

使用 PyTorch 进行深度学习(9 天迷你课程)
图片由 Cosmin Georgian 提供。保留部分权利。

本迷你课程适合谁?

在我们开始之前,让我们确保您处于正确的位置。下面的列表提供了一些关于本课程设计对象的通用指南。如果您不完全符合这些要点,请不要惊慌,您可能只需要在一个或另一个领域进行补充学习即可跟上。

  • 懂得编写少量代码的开发者。这意味着使用 Python 完成工作对您来说不是什么大问题,并且您知道如何在您的工作站上设置生态系统(一个先决条件)。这并不意味着您是编码向导,但这意味着您不害怕安装包和编写脚本。
  • 懂得少量机器学习知识的开发者。这意味着您了解机器学习的基础知识,如交叉验证、一些算法和偏差-方差权衡。这并不意味着您是机器学习博士,只是您知道这些标志性概念或知道在哪里查找它们。

本迷你课程不是一本关于深度学习的教科书。

它将带领您从一个懂少量 Python 机器学习的开发者,成长为一个能够取得成果并将深度学习的强大功能带入您自己项目的开发者。

迷你课程概述

本迷你课程分为 9 个部分。

每节课的设计时间约为普通开发人员 30 分钟。有些您可能会更快完成,有些您可能会选择深入研究并花费更多时间。
您可以随意地快速或缓慢地完成每个部分。一个舒适的时间表可能是每天完成一节课,持续九天。强烈推荐。

您将在接下来的 9 节课中涵盖的主题如下:

  • 第 1 课:PyTorch 简介。
  • 第 2 课:构建您的第一个多层感知器模型
  • 第 3 课:训练 PyTorch 模型
  • 第 4 课:使用 PyTorch 模型进行推断
  • 第 5 课:从 Torchvision 加载数据
  • 第 6 课:使用 PyTorch DataLoader
  • 第 7 课:卷积神经网络
  • 第 8 课:训练图像分类器
  • 第 9 课:使用 GPU 训练

这将非常有趣。

不过,您需要做一些工作,一点阅读,一点研究,还有一点编程。您想学习深度学习,对吗?

在评论中发布您的结果;我会为您加油!

坚持下去;不要放弃。

第 01 课:PyTorch 简介

PyTorch 是 Facebook 创建并发布的一个用于深度学习计算的 Python 库。它源于早期库 Torch 7,但已完全重写。

它是两种最流行的深度学习库之一。PyTorch 是一个完整的库,具有训练深度学习模型以及在推理模式下运行模型的能力,并支持使用 GPU 进行更快的训练和推理。这是一个我们不能忽视的平台。

在本课程中,您的目标是安装 PyTorch 并熟悉 PyTorch 程序中使用的符号表达式的语法。
例如,您可以使用 pip 安装 PyTorch。撰写本文时,PyTorch 的最新版本是 2.0。有针对 Windows、Linux 和 macOS 等每个平台的 PyTorch 预构建版本。在 Python 环境正常工作的情况下,pip 应该会为您处理好,为您提供您平台上的最新版本。

除了 PyTorch,还有一个 torchvision 库通常与 PyTorch 一起使用。它提供了许多有用的函数来帮助计算机视觉项目。

以下是一个 PyTorch 程序的简单示例,您可以将其用作起点:

PyTorch 主页上了解更多关于 PyTorch 的信息。

您的任务

重复上述代码以确保您已正确安装 PyTorch。您还可以通过运行以下 Python 代码行来检查您的 PyTorch 版本:

在下一课中,您将使用 PyTorch 构建一个神经网络模型。

第 02 课:构建您的第一个多层感知器模型

深度学习是关于构建大规模神经网络的。最简单的神经网络形式称为多层感知器模型。神经网络的构建块是人工神经元或感知器。这些是简单的计算单元,具有加权输入信号并使用激活函数产生输出信号。

感知器被排列成网络。一排感知器称为一层,一个网络可以有多个层。网络中感知器的架构通常称为网络拓扑。一旦配置好,神经网络需要根据您的数据集进行训练。用于神经网络的经典且仍然首选的训练算法称为随机梯度下降。

Model of a Simple Neuron

简单神经元模型

PyTorch 允许您用很少的代码行开发和评估深度学习模型。

接下来,您的目标是使用 PyTorch 开发您的第一个神经网络。使用来自 UCI 机器学习存储库的标准二元(两类)分类数据集,例如 Pima 印第安人数据集

为简单起见,网络模型只是几层全连接感知器。在这个特定模型中,数据集有 12 个输入或预测器,输出是 0 或 1 的单个值。因此,网络模型应该有 12 个输入(在第一层)和 1 个输出(在最后一层)。您的第一个模型将按以下方式构建:

这是一个包含 3 个全连接层的网络。每个层在 PyTorch 中使用 nn.Linear(x, y) 语法创建,其中第一个参数是层的输入数量,第二个参数是输出数量。每个层之间都使用修正线性激活,但在输出处应用 Sigmoid 激活,使输出值介于 0 和 1 之间。这是一个典型的网络。深度学习模型通常包含许多这样的层。

您的任务

重复上述代码并观察打印的模型输出。尝试在第一个 Linear 层之后添加另一个输出 20 个值的层。您应该如何更改 nn.Linear(12, 8) 这一行以适应这个新增内容?

在下一课中,您将看到如何训练这个模型。

第 03 课:训练 PyTorch 模型

在 PyTorch 中构建神经网络并不能说明您应该如何训练模型来完成特定任务。事实上,正如超参数所描述的,这方面有很多变体。在 PyTorch 或所有深度学习模型中,您通常需要决定如何训练模型:

  • 数据集是什么,特别是输入和目标是什么样子
  • 什么是损失函数,用于评估模型与数据的拟合优度
  • 什么是优化算法来训练模型,以及优化算法的参数,例如学习率和训练迭代次数
    迭代次数

在上一课中,使用了 Pima 印第安人数据集,所有输入都是数字。这将是最简单的情况,因为您不需要对数据进行任何预处理,因为神经网络可以轻松处理数字。

由于这是一个二元分类问题,损失函数应该使用二元交叉熵。这意味着模型输出的目标是 0 或 1 作为分类结果。但实际上,模型可能会输出介于两者之间的任何值。越接近目标值越好(即损失越低)。

梯度下降是优化神经网络的算法。梯度下降有很多变体,Adam 是最常用的变体之一。

结合上一课中构建的模型,以下是所有上述训练过程的代码:

上面的 for 循环是为了获取批次数据并将其输入模型。然后观察模型的输出并计算损失函数。基于损失函数,优化器将对模型进行一步微调,使其更好地匹配训练数据。经过多次更新步骤后,模型应该足够接近训练数据,从而能够以高精度预测目标。

您的任务

运行上述训练循环,观察随着训练循环的进行,损失如何下降。

在下一课中,您将看到如何使用训练好的模型。

第 04 课:使用 PyTorch 模型进行推断

一个训练好的神经网络模型是一个记住了输入和目标之间关系的模型。然后,这个模型可以根据另一个输入预测目标。

在 PyTorch 中,一个训练好的模型可以像一个函数一样运行。假设您已经训练了上一课中的模型,您可以简单地按如下方式使用它:

但事实上,更好的推理运行方式如下:

有些模型在训练和推理之间行为不同。model.eval() 这一行是向模型发出信号,表示目的是运行模型进行推理。with torch.no_grad() 这一行是创建一个运行模型的上下文,以便 PyTorch 知道不需要计算梯度。这可以消耗更少的资源。

这也是您评估模型的方式。模型输出一个 sigmoid 值,介于 0 和 1 之间。您可以通过将该值四舍五入到最接近的整数(即布尔标签)来解释该值。比较四舍五入后的预测与目标的匹配频率,您可以为模型分配一个准确率百分比,如下所示:

您的任务

运行上述代码,看看您得到的准确率是多少。您应该能达到大约 75%。

在下一课中,您将学习 torchvision。

第 05 课:从 Torchvision 加载数据

Torchvision 是 PyTorch 的姐妹库。在这个库中,有专门用于图像和计算机视觉的函数。正如您所料,有一些函数可以帮助您读取图像或调整对比度。但可能最重要的是提供一个简单的界面来获取一些图像数据集。

在下一课中,您将构建一个深度学习模型来分类小图像。这是一个允许您的计算机查看图像上内容的模型。正如您在之前的课程中看到的,拥有数据集来训练模型非常重要。您将要使用的数据集是 CIFAR-10。这是一个包含 10 种不同对象的数据集。还有一个更大的数据集叫 CIFAR-100。

CIFAR-10 数据集可以从互联网下载。但是如果您安装了 torchvision,您只需执行以下操作:

torchvision.datasets.CIFAR10 函数帮助您将 CIFAR-10 数据集下载到本地目录。该数据集分为训练集和测试集。因此,上面两行代码是为了获取这两个数据集。然后,您将绘制下载数据集中前 24 张图像。数据集中的每张图像都是 32x32 像素的图片,包含以下对象之一:飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船或卡车。

您的任务

根据上述代码,您能找到一种方法来分别计算训练集和测试集中的图像总数吗?

在下一课中,您将学习如何使用 PyTorch DataLoader。

第 06 课:使用 PyTorch DataLoader

上一课中的 CIFAR-10 图像确实是 numpy 数组格式。但是为了被 PyTorch 模型消费,它需要是 PyTorch 张量。将 numpy 数组转换为 PyTorch 张量并不困难,但在训练循环中,您仍然需要将数据集分成批次。PyTorch DataLoader 可以帮助您使这个过程更顺畅。

回到上一课中加载的 CIFAR-10 数据集,您可以执行以下操作以达到相同的效果:

在这段代码中,trainsettransform 参数创建,以便在提取数据时将其转换为 PyTorch 张量。这在随后的 DataLoader 行中执行。DataLoader 对象是一个 Python 可迭代对象,您可以从中提取输入(即图像)和目标(即整数类标签)。在这种情况下,您将批次大小设置为 24 并迭代第一个批次。然后您显示批次中的每张图像。

您的任务

运行上述代码并与您在上一课中生成的 matplotlib 输出进行比较。您应该会看到输出不同。为什么? DataLoader 行中的一个参数导致了这种差异。您能识别出是哪个参数吗?

在下一课中,您将学习如何构建一个深度学习模型来对 CIFAR-10 数据集中的图像进行分类。

第 07 课:卷积神经网络

图像是二维结构。您可以很容易地通过将其展平来将其转换为一维向量,并构建一个神经网络模型来对其进行分类。但是众所周知,保留二维结构更合适,因为分类是关于图像中的内容,这具有平移不变性

图像处理神经网络的标准方法是使用卷积层。使用卷积层的神经网络称为卷积神经网络。例如:

在上述代码中,我们多次使用了 Conv2d 层和 ReLU 激活函数。卷积层用于学习和提取图像中的特征。您添加的卷积层越多,网络就能学习到更高级的特征。最终,您将使用池化层(上例中的 MaxPool2d)对提取的特征进行分组,将其展平为向量,然后将其传递给多层感知器网络进行最终分类。这是图像分类模型常见的结构。

您的任务

运行上述代码以确保您可以正确创建模型。您没有在模型中指定输入图像大小,但实际上它固定为 RGB 格式的 32x32 像素(即 3 个颜色通道)。这在网络的哪个部分是固定的?

在下一课中,您将使用上一课中的 DataLoader 来训练上述模型。

第 08 课:训练图像分类器

结合为 CIFAR-10 数据集创建的 DataLoader,您可以使用以下训练循环训练上一课中的卷积神经网络:

这将需要一段时间才能运行,您应该会看到模型能够达到不低于 70% 的准确率。

这个模型是一个多类分类网络。输出不是一个,而是许多分数,每个类一个。我们认为分数越高,模型就越有信心图像属于该类。因此,使用的损失函数是交叉熵,它是二元交叉熵的多类版本。

在上述训练循环中,您应该会看到许多您在前面课程中学到的元素。包括在模型的训练模式和推理模式之间切换,使用 torch.no_grad() 上下文,以及准确率的计算。

您的任务

阅读上述代码,确保您理解其功能。运行此代码,观察准确率如何随训练进行而提高。您最终实现了多少准确率?

在下一课中,您将学习如何使用 GPU 加速相同模型的训练。

第 09 课:使用 GPU 训练

您在上一课中进行的模型训练应该会花费一段时间。如果您有受支持的 GPU,您可以大大加快训练速度。

在 PyTorch 中使用 GPU 的方法是在执行之前将模型和数据发送到 GPU。然后,您可以选择将结果从 GPU 发送回来,或直接在 GPU 中执行评估。

修改上一课中的代码以使用 GPU 并不困难。以下是应该怎么做:

所做的更改如下:您检查 GPU 是否可用并相应地设置 device。然后将模型发送到设备。当输入(即一批图像)传递给模型时,应首先将其发送到相应的设备。由于模型输出也将在那里,因此损失计算或准确度计算也应首先将目标发送到 GPU。

您的任务

您会发现 PyTorch 在 CPU 和 GPU 中运行基本相同。如果您可以使用 GPU,请尝试比较两者。您能观察到多大的加速?

这是最后一课。

结束!(看看你已经走了多远

您做到了。干得好!

花点时间回顾一下您已经走了多远。

  • 您发现 PyTorch 是一个用于 Python 的深度学习库
  • 您使用 PyTorch 构建了您的第一个神经网络,并学习了如何使用神经网络进行分类
  • 您学习了深度学习的关键组成部分,包括损失函数、优化器、训练循环和评估
  • 最后,您迈出了下一步,学习并开发了用于计算机视觉任务的卷积神经网络

总结

您对这个迷你课程的学习情况如何?
您喜欢这个速成课程吗?

您有任何问题吗?有没有遇到什么难点?
告诉我。在下面留言。

开始使用PyTorch进行深度学习!

Deep Learning with PyTorch

学习如何构建深度学习模型

...使用新发布的PyTorch 2.0库

在我的新电子书中探索如何实现
使用 PyTorch进行深度学习

它提供了包含数百个可用代码自学教程,让你从新手变成专家。它将使你掌握:
张量操作训练评估超参数优化等等...

通过动手练习开启你的深度学习之旅


查看内容

使用 PyTorch 进行深度学习(9 天迷你课程) 的 17 条回复

  1. ayush 2023 年 4 月 10 日 下午 8:02 #

    感谢您在博客上提供宝贵信息。
    我不是博客写作专家,但我正在稍微阅读您的内容,这增加了我对如何正确提供信息的信心。您的展示也很好,我很容易理解信息。

    • James Carmichael 2023 年 4 月 11 日 上午 6:08 #

      非常欢迎您,ayush!我们非常感谢您的反馈和支持!

  2. Aashi Goel 2023 年 5 月 5 日 下午 2:58 #

    我正在寻找这样的东西!非常感谢这个迷你课程,我迫不及待地想开始学习。

  3. Jamina A 2023 年 5 月 5 日 下午 4:29 #

    你好,谢谢你的帖子。

    在第 2 课中,您提到了 12 个输入,但第 4 行的代码是

    nn.Linear(8, 12)

    由于第一个参数是输入,它应该是
    nn.Linear(12,8) 吗?

    谢谢

    • James Carmichael 2023 年 5 月 6 日 上午 10:26 #

      你好 Jamina……你说得对!感谢您的反馈!

  4. Chase He 2023 年 5 月 22 日 上午 11:30 #

    很棒的课程!你能评论一下如何提高准确性吗?比如改变学习率?增加模型层或改变层大小?

  5. Chase He 2023 年 5 月 22 日 上午 11:31 #

    很棒的课程!你能评论一下如何提高准确性吗?比如改变学习率?增加模型层或改变层大小?

  6. AmerAther 2023 年 10 月 24 日 上午 7:17 #

    在第二课中,我收到错误

    回溯(最近一次调用)
    文件“./lesson2.py”,第 14 行,在
    optimizer = optim.Adam(model.parameters(), lr=0.001)
    NameError: 名称 'model' 未定义”

    • James Carmichael 2023 年 10 月 24 日 上午 10:08 #

      你好 AmerAther……您是自己输入代码还是复制粘贴的?

  7. AmerAther 2023 年 10 月 24 日 上午 7:23 #

    我发现了问题。请忽略。

  8. Jay 2023 年 12 月 30 日 上午 2:27 #

    你好,
    运行第 2 天的代码后,只给出以下输出。理想情况下它应该给出详细信息。这是设置问题还是?请帮助。

    Sequential(
    (0): Linear(in_features=8, out_features=12, bias=True)
    (1): ReLU()
    (2): Linear(in_features=12, out_features=8, bias=True)
    (3): ReLU()
    (4): Linear(in_features=8, out_features=1, bias=True)
    (5): Sigmoid()
    )

    • James Carmichael 2023 年 12 月 30 日 上午 9:32 #

      你好 Jay……请详细说明您遇到的具体错误措辞,以便我们更好地帮助您。

  9. Esteban 2024 年 7 月 6 日 上午 8:25 #

    在 CNN 示例中,您能解释一下 "nn.Linear(8192, 512)" 的以下参数吗?8192 是从哪里来的?谢谢。

    • James Carmichael 2024 年 7 月 7 日 上午 7:29 #

      你好 Esteban……这是一个笔误。你可以删除它。

  10. Martin 2025 年 1 月 4 日 上午 1:52 #

    嗨 James,

    第 3 课,我运行了不止一次,得到了(显然)不同的结果。
    完成第 98 轮,最新损失 0.4395795464515686
    完成第 99 轮,最新损失 0.4365136921405792

    完成第 98 轮,最新损失 0.3080378472805023
    完成第 99 轮,最新损失 0.3099350035190582

    完成第 98 轮,最新损失 0.32353270053863525
    完成第 99 轮,最新损失 0.3243427872657776

    现在,这意味着什么?在现实生活中,我是否必须保留每个模型并选择损失较小的那个?但我怎么知道损失是好是坏呢?

    • James Carmichael 2025 年 1 月 4 日 上午 9:48 #

      你好 Martin……您关于 PyTorch 深度学习迷你课程中不同运行之间损失变化的观察是有效的,并且反映了神经网络训练的性质。让我们分解并回答您的问题:

      ### **为什么每次都会看到不同的结果?**
      1. **权重的随机初始化**
      – 每次运行代码时,模型的权重都会随机初始化,这导致训练期间的优化路径略有不同。

      2. **训练的随机性**
      – 随机梯度下降 (SGD) 等训练算法涉及选择小批量的随机性,这进一步导致了可变性。

      3. **硬件中的非确定性**
      – 在某些系统(例如 GPU)上,非确定性操作可能导致细微的差异。

      ### **这意味着什么?**
      1. **可变性是正常的**
      – 跨运行的损失小差异是预期的,并不一定表示问题。

      2. **收敛**
      – 您示例中的损失相对接近。这表明您的模型正在收敛到损失景观中相似的区域,这是好的。

      ### **应该保留损失最低的模型吗?**
      – **在实践中**
      – 您不需要每次都多次运行模型并选择损失最低的那个。相反,目标是调整模型的超参数以最小化可变性并提高一致性。

      – **如何评估“好坏”**
      – 在验证集测试集上评估模型的性能。训练集上的低损失不能保证良好的性能;重要的是验证/测试性能。

      – **模型选择**
      – 在训练期间保存具有最佳验证性能的模型(例如,最低的验证损失或最高的验证准确率)。

      ### **如何判断损失是好是坏?**
      1. **上下文特定**
      – 损失的解释取决于您使用的具体损失函数。
      – 例如
      – 对于一个问题,大约 0.3 的 **MSE 损失**(均方误差)可能很好,但对于另一个问题则太高,这取决于目标变量的规模。
      – **分类交叉熵损失**接近 0 表示模型对其预测具有高度信心。

      2. **基线比较**
      – 将您的模型性能与基线模型(例如,随机预测或简单的启发式方法)进行比较。
      – 示例:对于回归问题,将您的模型的 MSE 与目标变量的方差进行比较。如果您的模型的 MSE 显著降低,则表示其表现良好。

      3. **学习曲线**
      – 监控训练期间损失的下降情况。一个好的模型应该在训练集和验证集上显示稳定的收敛。

      4. **业务或应用目标**
      – 根据具体的应用定义可接受性能的阈值。例如
      – 在医疗诊断中,即使损失略低也可能显著影响结果。
      – 在不那么关键的应用中,更高的损失可能仍然可以接受。

      ### **如何处理可变性**
      1. **设置随机种子**
      – 使用固定随机种子以确保跨运行的可重现性
      python
      import torch
      import numpy as np
      import random

      random.seed(42)
      np.random.seed(42)
      torch.manual_seed(42)
      if torch.cuda.is_available():
      torch.cuda.manual_seed(42)
      torch.cuda.manual_seed_all(42)

      2. **使用交叉验证**
      – 在多个数据划分上评估您的模型,以获得更可靠的性能估计。

      3. **监控验证性能**
      – 使用验证集来决定何时停止训练(例如,提前停止)并选择最佳模型。

      4. **保存和记录结果**
      – 保存每个训练好的模型及其验证/测试性能以进行比较
      python
      torch.save(model.state_dict(), "model_best.pth")

      ### **主要收获**
      – 运行之间的可变性是正常的;不必过于担心。
      – 专注于验证/测试性能来判断模型是否良好。
      – 需要时设置随机种子以确保可重现性。
      – 根据您的应用程序需求定义“良好”的损失或性能。

      如果您需要进一步的说明或帮助,请告诉我!😊

发表评论

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。