Torch Auto grad Variable

11 Jun 2025 | 6 分钟阅读

引言

PyTorch 是当今最强大、应用最广泛的深度学习库之一。它提供了一个通用且用户友好的神经网络构建和训练接口。它在众多库中独树一帜,部分原因在于其动态计算图,它允许在正向传播过程中进行实时修改。其自动微分引擎 Autograd 模块就是为此而设计的。该模块的核心组件是 torch.autograd。在反向传播过程中,Variable 至关重要。本文将全面介绍其自动梯度和变量,概述它们的功能、实际应用以及在现代深度学习系统中的地位。

什么是 Autograd?

Autograd 是 PyTorch 的一项主要功能,代表“自动微分”,可在 反向传播期间自动计算张量的梯度。梯度对于神经网络训练至关重要,因为它们指示了如何更改模型的权重以最小化损失函数。深度学习中的正向传播计算预测,而反向传播计算梯度。它通过动态构建计算图来实现实时更新和调整。由于可以轻松尝试各种设计,因此特别适合研究。本质上,Autograd 会在计算图中记录所有与张量相关的操作的历史,并捕获所有与张量相关的操作。为了高效地计算梯度,在反向传播时会向后遍历此图。

理解 PyTorch 中的张量

在深入探讨 autograd.Variable 之前,理解张量至关重要,因为张量是 PyTorch 中的基本数据结构。张量是 GPU 加速的数组,类似于 NumPy 数组。它们是 PyTorch 用于数据存储和 神经网络处理的多维数组。

示例

为了启用自动微分,需要将 requires_grad 设置为 True。此标志表明,在反向传播期间计算梯度时,应记录使用此张量的任何操作。

什么是变量?

在早期版本的 PyTorch 中,Variable 是一个单独的类,它封装了一个张量并提供了自动微分功能。在最新版本中,Variable 和 Tensor 类已合并,现在只要将 requires_grad 设置为 True,所有张量都可以像 Variable 一样工作。

在合并之前,您需要像这样创建一个变量:from torch.autograd import Variable

现在,当使用 requires_grad=True 的张量时,这会产生相同的结果。

尽管 Variable 已不再正式使用,但理解其功能对于了解 PyTorch 如何处理梯度和可微分操作至关重要。Variable 是张量的一个轻量级包装器,它记录了其梯度以及应用于它的任何操作。

现在可以直接使用 torch.Tensor 来完成 Variable 以前自动完成的所有工作。

梯度在神经网络中的作用

梯度(函数相对于其输入的偏导数)对于优化神经网络至关重要。神经网络训练的目标是通过改变模型的权重来最小化损失函数。随机梯度下降 (SGD) 是一种常用于此的优化方法。使用梯度沿着最小化损失的方向来更新这些权重。

PyTorch 的 Autograd 模块可以自动计算张量梯度。

考虑这个例子

在这种情况下,y 相对于 x 的梯度将是 [2x + 2],在 x = [1, 2, 3] 处进行评估,并将包含在 x.grad 中。

Autograd 变量和计算图

张量操作的历史存储在一个有向无环图 (DAG) 中,即计算图。在计算图中,PyTorch 中的每个操作都会添加一个新节点,该节点记录了每个张量如何从其他张量推导而来。

例如,PyTorch 在内部生成一个计算图来跟踪我们对张量进行的操作。

在此示例中,计算图显示了 a 和 b 如何组合成 c。在反向传播期间,它会确定 c 相对于其输入(a 和 b)的梯度。

PyTorch 中的反向传播工作原理

用于计算损失函数相对于每个神经网络权重的梯度的算法称为反向传播。这在 PyTorch 中通过使用 .backward() 函数来实现。通过计算每个节点处的梯度,此方法将梯度反向传播通过计算网络。

这是一个在简单神经网络中反向传播工作原理的示例。

在此示例中,通过 .backward() 方法计算了损失相对于权重 w、输入 x 和偏差 b 的梯度。

实际示例

在神经网络中使用 Autograd

当您构建神经网络时,它会处理反向传播期间的梯度计算。让我们通过一个只有一层线性回归模型的示例来手动完成此操作。

说明

  • 模型 y_pred = wx + b 是一个简单的线性回归。
  • 为了跟踪梯度,我们初始化权重 w 和偏差 b,并将 requires_grad 设置为 True。
  • 我们使用均方误差 (MSE) 来计算每个周期的损失。
  • 借助 backward() 应用反向传播。
  • 使用梯度下降手动更新权重。
  • 使用 .zero_() 清零每次更新后的梯度。

高阶梯度

PyTorch 中的 autograd 功能允许我们计算导数的导数,因为它支持高阶梯度。

  • 首先计算 y = x^3 相对于 x 的一阶导数。
  • 要计算二阶导数,我们首先使用 x.grad.zero_() 删除先前的梯度,然后再次调用 .backward()。

使用自定义梯度

torch.autograd.grad() 可用于在存储梯度于原始张量的同时计算梯度,作为 backward() 的替代方法。

它在计算 z 相对于输入 x 和 y 的梯度后,将梯度作为元组返回。

钩子

当与 Autograd 的 Variable 类结合使用时,它们是一项强大的功能,允许用户在正向或反向传播过程中编辑或检查中间输出。register_forward_hook 方法可用于注册正向钩子,该方法在层的正向传播后运行一个函数。通过注册 register_hook 的反向钩子,可以实现梯度自定义,并允许反向传播。这些钩子在实现梯度裁剪等复杂模型行为以及调试和梯度监控方面非常有用。尽管钩子提供了灵活性,但用户在使用它们时需要谨慎,以避免在训练过程中出现意外行为或内存泄漏。

常见陷阱和最佳实践

梯度累积:默认情况下,PyTorch 中的梯度是累积的。因此,在每次反向传播之前,您应该手动清除梯度。

从图中分离:您可以使用此功能从计算图中删除一个张量,以便在操作时停止跟踪其梯度。使用 torch.no_grad() 或 detach()。

结论

PyTorch 的 autograd 自动微分引擎(现在是 Tensor 的一部分)是库架构不可或缺的一部分。理解 Autograd、计算图和反向传播对于神经网络的构建、训练和优化至关重要。随着 PyTorch 的进一步发展,这些工具将成为研究和生产就绪模型的关键。