龙空技术网

【AI 和机器学习】PyTorch BASIC 基础知识:节5 —— 自动微分

产品工作坊 11

前言:

如今你们对“雅可比迭代矩阵求法例题解析”大概比较关切,你们都想要了解一些“雅可比迭代矩阵求法例题解析”的相关知识。那么小编也在网上汇集了一些对于“雅可比迭代矩阵求法例题解析””的相关资讯,希望咱们能喜欢,看官们一起来学习一下吧!

【AI 和机器学习】PyTorch BASIC 基础知识:节5

—— 自动微分(Autograd)

前言

—— 哪个更适合初学者?

想要学习并掌握 AI,最直接的办法就是自己动手进行实操。有一些流行的来源可供练习 AI 技能,例如:

Kaggle:一个托管各种数据集和机器学习竞赛的平台。UCI 机器学习存储库:用于机器学习研究的数据集集合。TensorFlow 教程:TensorFlow 团队提供的教程和示例。PyTorch 教程:PyTorch 团队提供的教程和示例。

其中PyTorch和TensorFlow的AI教程资源非常丰富。但对于初学者来说,哪个更合适,可能还得取决于您的特定目标(研究与生产)以及您的偏好等:

PyTorch 因其简单、易读和易于调试而通常被认为更适合初学者。PyTorch 的动态特性使新手可以学习概念而不会被复杂的语法所困扰。TensorFlow 随着 TensorFlow 2.x 和 Keras 的推出变得更加适合初学者,但它仍可能对初学者构成挑战。

本文先选择PyTorch来和大家一起学习,学习它的一些基础内容。其中所有素材均取自其教程。对于每一节内容,我们都将先给出摘要,然后把译文稍作整理后附在后面,供参考。

目录

【续前文】

本节摘要

本节介绍了PyTorch的torch.autograd模块,以及将该模块用于神经网络自动微分的方法。

首先说明了反向传播算法中梯度的计算对于优化模型权重的重要性,然后介绍了torch.autograd如何支持任何计算图的梯度自动计算。接着通过单层神经网络的例子,详细说明了如何设置张量的requires_grad属性来计算损失函数相对于参数的梯度,并解释了计算图中Function对象的作用。此外,文章还讨论了如何计算梯度、获取叶节点的grad属性,以及在需要多次向后调用时如何处理。文中还介绍了如何禁用梯度跟踪来加快前向计算的速度,并提供了torch.no_grad()块和detach()两种实现方式。最后,文章介绍了autograd在有向无环图(DAG)中保存数据和操作记录的概念,以及如何使用链式法则自动计算梯度,提到了PyTorch允许计算雅可比积而不是完整的雅可比矩阵的特殊情况,指出了在多次调用backward()时需要将梯度归零,以避免累积梯度的问题。本节正文

用 torch.autograd 进行自动微分

在训练神经网络时,最常用的算法是反向传播。在此算法中,参数(模型权重)是根据损失函数相对于给定参数的梯度进行调整的。

为了计算这些梯度,PyTorch 有一个名为 torch.autograd 的内置微分引擎。它支持任何计算图的梯度自动计算。

考虑最简单的单层神经网络,其中包含输入 x、参数 w 和 b 以及一些损失函数。可以在 PyTorch 中按以下方式定义它:

张量、函数和计算图

此代码定义以下计算图:

在这个网络中,w 和 b 是我们需要优化的参数。因此,我们需要能够计算损失函数相对于这些变量的梯度。为此,我们设置了这些张量的 requires_grad 属性。

注:您可以在创建张量时设置 requires_grad 的值,也可以稍后使用 x.requires_grad_(True) 方法设置该值。

我们用于张量的一个构建计算图的函数实际上是 Function 类的对象。这个对象知道如何在正向方向上计算函数,也知道如何在向后传播步骤中计算其导数。对向后传播函数的引用存储在张量的 grad_fn 属性中。您可以在相关文档中找到有关 Function 的更多信息。

输出:

计算梯度

为了优化神经网络中参数的权重,我们需要计算损失函数相对于参数的导数,即我们需要在 x 和 y 的一些固定值下的

。为了计算这些导数,我们调用 loss.backward(),然后从 w.grad 和 b.grad 中取值:

输出:

注:

我们只能获取计算图的叶节点的 grad 属性,这些节点的 requires_grad 属性设置为 True。对于图中的所有其他节点,梯度将不可用。

出于性能原因,我们只能在给定的图形上使用 backward 一次执行梯度计算。如果我们需要在同一个图上执行多次向后调用,则需要将 retain_graph=True 传递给向后调用。

禁用梯度跟踪

默认情况下,所有 requires_grad=True 的张量都在跟踪其计算历史,并支持梯度计算。但是,在某些情况下我们不需要这样做,例如,当我们训练了模型,并只想将其应用于一些输入数据时,即我们只想通过网络进行前向计算。我们可以通过将计算代码用 torch.no_grad() 块括起来停止跟踪计算:

输出:

实现相同结果的另一种方法是对张量使用 detach() 方法:

输出:

出于多种原因,您可能希望禁用梯度跟踪:

将神经网络中的某些参数标记为冻结参数。在仅执行前向传递时加快计算速度,因为在不跟踪梯度的张量上进行计算会更高效。有关计算图的更多信息

从概念上讲,autograd 在由 Function 对象组成的有向无环图 (DAG) 中保存数据(张量)和所有已执行操作(以及生成的新张量)的记录。在这个 DAG 中,叶子是输入张量,根是输出张量。通过从根到叶跟踪此图,您可以使用链式法则自动计算梯度。

在前向传递中,autograd 同时执行两件事:

运行请求的操作来计算生成的张量在 DAG 中保持操作的梯度函数。

在 DAG 根上调用 .backward() 时,将启动向后传递。autograd 中,则:

计算每个.grad_fn的梯度,将它们累积到相应张量的 .grad 属性中使用链式法则,一直传播到叶子张量。

注:

DAG 在 PyTorch 中的DAG是动态的,需要注意的重要一点是,图形是从头开始重新创建的;每次调用 .backward() 后,autograd 都会开始填充新图形。这正是允许您在模型中使用控制流语句的原因;如果需要,您可以在每次迭代时更改形状、大小和操作。

可选阅读材料:张量梯度和雅可比积

在许多情况下,我们有一个标量损失函数,我们需要计算一些参数的梯度。但是,在某些情况下,输出函数是任意张量。在这种情况下,PyTorch 允许您计算所谓的雅可比积,而不是实际的梯度。

对于向量函数

,其中

,则

相对于

的梯度由雅可比矩阵给出:

PyTorch 允许您计算雅可比积

,而不是计算雅可比矩阵本身,对于给定的输入向量

。这是通过将

作为参数调用 backward 来实现的。

的大小应与原始张量的大小相同,我们要根据原始张量计算乘积:

输出:

请注意,当我们使用相同的参数第二次调用 backward 时,gradient 的值是不同的。发生这种情况是因为在进行反向传播时,PyTorch 会累积梯度,即计算出的梯度值被添加到计算图的所有叶节点的 grad 属性中。如果你想计算正确的梯度,你需要先将 grad 属性归零。在实际训练中,优化器可以帮助我们做到这一点。

注:

以前我们调用的是不带参数的 backward()函数。这本质上等同于调用 backward(torch.tensor(1.0)),这是在标量值函数的情况下计算梯度的有用方法,例如神经网络训练期间的损失。

延伸阅读:Autograd 机制

【未完待续】

农历甲辰十月廿八

2024.11.28

【部分图片来源网络,侵删】

标签: #雅可比迭代矩阵求法例题解析