深度解析 PyTorch Autograd:从原理到实践

这篇具有很好参考价值的文章主要介绍了深度解析 PyTorch Autograd:从原理到实践。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文深入探讨了 PyTorch 中 Autograd 的核心原理和功能。从基本概念、Tensor 与 Autograd 的交互,到计算图的构建和管理,再到反向传播和梯度计算的细节,最后涵盖了 Autograd 的高级特性。

关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人

深度解析 PyTorch Autograd:从原理到实践

一、Pytorch与自动微分Autograd

自动微分(Automatic Differentiation,简称 Autograd)是深度学习和科学计算领域的核心技术之一。它不仅在神经网络的训练过程中发挥着至关重要的作用,还在各种工程和科学问题的数值解法中扮演着关键角色。

1.1 自动微分的基本原理

在数学中,微分是一种计算函数局部变化率的方法,广泛应用于物理、工程、经济学等领域。自动微分则是通过计算机程序来自动计算函数导数或梯度的技术。

自动微分的关键在于将复杂的函数分解为一系列简单函数的组合,然后应用链式法则(Chain Rule)进行求导。这个过程不同于数值微分(使用有限差分近似)和符号微分(进行符号上的推导),它可以精确地计算导数,同时避免了符号微分的表达式膨胀问题和数值微分的精度损失。

import torch

# 示例:简单的自动微分
x = torch.tensor(2.0, requires_grad=True)
y = x ** 2 + 3 * x + 1
y.backward()

# 打印梯度
print(x.grad)  # 输出应为 2*x + 3 在 x=2 时的值,即 7

1.2 自动微分在深度学习中的应用

在深度学习中,训练神经网络的核心是优化损失函数,即调整网络参数以最小化损失。这一过程需要计算损失函数相对于网络参数的梯度,自动微分在这里发挥着关键作用。

以一个简单的线性回归模型为例,模型的目标是找到一组参数,使得模型的预测尽可能接近实际数据。在这个过程中,自动微分帮助我们有效地计算损失函数关于参数的梯度,进而通过梯度下降法更新参数。

# 示例:线性回归中的梯度计算
x_data = torch.tensor([1.0, 2.0, 3.0])
y_data = torch.tensor([2.0, 4.0, 6.0])

# 模型参数
weight = torch.tensor([1.0], requires_grad=True)

# 前向传播
def forward(x):
    return x * weight

# 损失函数
def loss(x, y):
    y_pred = forward(x)
    return (y_pred - y) ** 2

# 计算梯度
l = loss(x_data, y_data)
l.backward()

print(weight.grad)  # 打印梯度

1.3 自动微分的重要性和影响

自动微分技术的引入极大地简化了梯度的计算过程,使得研究人员可以专注于模型的设计和训练,而不必手动计算复杂的导数。这在深度学习的快速发展中起到了推波助澜的作用,尤其是在训练大型神经网络时。

此外,自动微分也在非深度学习的领域显示出其强大的潜力,例如在物理模拟、金融工程和生物信息学等领域的应用。

二、PyTorch Autograd 的核心机制

深度解析 PyTorch Autograd:从原理到实践
PyTorch Autograd 是一个强大的工具,它允许研究人员和工程师以极少的手动干预高效地计算导数。理解其核心机制不仅有助于更好地利用这一工具,还能帮助开发者避免常见错误,提升模型的性能和效率。

2.1 Tensor 和 Autograd 的相互作用

深度解析 PyTorch Autograd:从原理到实践
在 PyTorch 中,Tensor 是构建神经网络的基石,而 Autograd 则是实现神经网络训练的关键。了解 Tensor 和 Autograd 如何协同工作,对于深入理解和有效使用 PyTorch 至关重要。

Tensor:PyTorch 的核心

Tensor 在 PyTorch 中类似于 NumPy 的数组,但它们有一个额外的超能力——能在 Autograd 系统中自动计算梯度。

  • Tensor 的属性: 每个 Tensor 都有一个 requires_grad 属性。当设置为 True 时,PyTorch 会跟踪在该 Tensor 上的所有操作,并自动计算梯度。

Autograd:自动微分的引擎

Autograd 是 PyTorch 的自动微分引擎,负责跟踪那些对于计算梯度重要的操作。

  • 计算图: 在背后,Autograd 通过构建一个计算图来跟踪操作。这个图是一个有向无环图(DAG),它记录了创建最终输出 Tensor 所涉及的所有操作。

Tensor 和 Autograd 的协同工作

当一个 Tensor 被操作并生成新的 Tensor 时,PyTorch 会自动构建一个表示这个操作的计算图节点。

  • 示例:简单操作的跟踪

    import torch
    
    # 创建一个 Tensor,设置 requires_grad=True 来跟踪与它相关的操作
    x = torch.tensor([2.0], requires_grad=True)
    
    # 执行一个操作
    y = x * x
    
    # 查看 y 的 grad_fn 属性
    print(y.grad_fn)  # 这显示了 y 是通过哪种操作得到的
    

    这里的 y 是通过一个乘法操作得到的。PyTorch 会自动跟踪这个操作,并将其作为计算图的一部分。

  • 反向传播和梯度计算

    当我们对输出的 Tensor 调用 .backward() 方法时,PyTorch 会自动计算梯度并将其存储在各个 Tensor 的 .grad 属性中。

    # 反向传播,计算梯度
    y.backward()
    
    # 查看 x 的梯度
    print(x.grad)  # 应输出 4.0,因为 dy/dx = 2 * x,在 x=2 时值为 4
    

2.2 计算图的构建和管理

深度解析 PyTorch Autograd:从原理到实践
在深度学习中,理解计算图的构建和管理是理解自动微分和神经网络训练过程的关键。PyTorch 使用动态计算图,这是其核心特性之一,提供了极大的灵活性和直观性。

计算图的基本概念

计算图是一种图形化的表示方法,用于描述数据(Tensor)之间的操作(如加法、乘法)关系。在 PyTorch 中,每当对 Tensor 进行操作时,都会创建一个表示该操作的节点,并将操作的输入和输出 Tensor 连接起来。

  • 节点(Node):代表了数据的操作,如加法、乘法。
  • 边(Edge):代表了数据流,即 Tensor。

动态计算图的特性

PyTorch 的计算图是动态的,即图的构建是在运行时发生的。这意味着图会随着代码的执行而实时构建,每次迭代都可能产生一个新的图。

  • 示例:动态图的创建

    import torch
    
    x = torch.tensor(1.0, requires_grad=True)
    y = torch.tensor(2.0, requires_grad=True)
    
    # 一个简单的运算
    z = x * y
    
    # 此时,一个计算图已经形成,其中 z 是由 x 和 y 通过乘法操作得到的
    

反向传播与计算图

在深度学习的训练过程中,反向传播是通过计算图进行的。当调用 .backward() 方法时,PyTorch 会从该点开始,沿着图逆向传播,计算每个节点的梯度。

  • 示例:反向传播过程

    # 继续上面的例子
    z.backward()
    
    # 查看梯度
    print(x.grad)  # dz/dx,在 x=1, y=2 时应为 2
    print(y.grad)  # dz/dy,在 x=1, y=2 时应为 1
    

计算图的管理

在实际应用中,对计算图的管理是优化内存和计算效率的重要方面。

  • 图的清空:默认情况下,在调用 .backward() 后,PyTorch 会自动清空计算图。这意味着每个 .backward() 调用都是一个独立的计算过程。对于涉及多次迭代的任务,这有助于节省内存。

  • 禁止梯度跟踪:在某些情况下,例如在模型评估或推理阶段,不需要计算梯度。使用 torch.no_grad() 可以暂时禁用梯度计算,从而提高计算效率和减少内存使用。

    with torch.no_grad():
        # 在这个块内,所有计算都不会跟踪梯度
        y = x * 2
        # 这里 y 的 grad_fn 为 None
    

2.3 反向传播和梯度计算的细节

反向传播是深度学习中用于训练神经网络的核心算法。在 PyTorch 中,这一过程依赖于 Autograd 系统来自动计算梯度。理解反向传播和梯度计算的细节是至关重要的,它不仅帮助我们更好地理解神经网络是如何学习的,还能指导我们进行更有效的模型设计和调试。

反向传播的基础

反向传播算法的目的是计算损失函数相对于网络参数的梯度。在 PyTorch 中,这通常通过在损失函数上调用 .backward() 方法实现。

  • 链式法则: 反向传播基于链式法则,用于计算复合函数的导数。在计算图中,从输出到输入反向遍历,乘以沿路径的导数。

反向传播的 PyTorch 实现

以下是一个简单的 PyTorch 示例,说明了反向传播的基本过程:

import torch

# 创建 Tensor
x = torch.tensor(1.0, requires_grad=True)
w = torch.tensor(2.0, requires_grad=True)
b = torch.tensor(3.0, requires_grad=True)

# 构建一个简单的线性函数
y = w * x + b

# 计算损失
loss = y - 5

# 反向传播
loss.backward()

# 检查梯度
print(x.grad)  # dy/dx
print(w.grad)  # dy/dw
print(b.grad)  # dy/db

在这个例子中,loss.backward() 调用触发了整个计算图的反向传播过程,计算了 loss 相对于 xwb 的梯度。

梯度积累

在 PyTorch 中,默认情况下梯度是累积的。这意味着在每次调用 .backward() 时,梯度都会加到之前的值上,而不是被替换。

  • 梯度清零: 在大多数训练循环中,我们需要在每个迭代步骤之前清零梯度,以防止梯度累积影响当前步骤的梯度计算。
# 清零梯度
x.grad.zero_()
w.grad.zero_()
b.grad.zero_()

# 再次进行前向和反向传播
y = w * x + b
loss = y - 5
loss.backward()

# 检查梯度
print(x.grad)  # dy/dx
print(w.grad)  # dy/dw
print(b.grad)  # dy/db

高阶梯度

PyTorch 还支持高阶梯度计算,即对梯度本身再次进行微分。这在某些高级优化算法和二阶导数的应用中非常有用。

# 启用高阶梯度计算
z = y * y
z.backward(create_graph=True)

# 计算二阶导数
x_grad = x.grad
x_grad2 = torch.autograd.grad(outputs=x_grad, inputs=x)[0]
print(x_grad2)  # d^2y/dx^2

三、Autograd 特性全解

PyTorch 的 Autograd 系统提供了一系列强大的特性,使得它成为深度学习和自动微分中的重要工具。这些特性不仅提高了编程的灵活性和效率,还使得复杂的优化和计算变得可行。

动态计算图(Dynamic Graph)

PyTorch 中的 Autograd 系统基于动态计算图。这意味着计算图在每次执行时都是动态构建的,与静态图相比,这提供了更大的灵活性。

  • 示例:动态图的适应性

    import torch
    
    x = torch.tensor(1.0, requires_grad=True)
    if x > 0:
        y = x * 2
    else:
        y = x / 2
    y.backward()
    

    这段代码展示了 PyTorch 的动态图特性。根据 x 的值,计算路径可以改变,这在静态图框架中是难以实现的。

自定义自动微分函数

PyTorch 允许用户通过继承 torch.autograd.Function 来创建自定义的自动微分函数,这为复杂或特殊的前向和后向传播提供了可能。

  • 示例:自定义自动微分函数

    class MyReLU(torch.autograd.Function):
        @staticmethod
        def forward(ctx, input):
            ctx.save_for_backward(input)
            return input.clamp(min=0)
    
        @staticmethod
        def backward(ctx, grad_output):
            input, = ctx.saved_tensors
            grad_input = grad_output.clone()
            grad_input[input < 0] = 0
            return grad_input
    
    x = torch.tensor([-1.0, 1.0, 2.0], requires_grad=True)
    y = MyReLU.apply(x)
    y.backward(torch.tensor([1.0, 1.0, 1.0]))
    print(x.grad)  # 输出梯度
    

    这个例子展示了如何定义一个自定义的 ReLU 函数及其梯度计算。

requires_grad 和 no_grad

在 PyTorch 中,requires_grad 属性用于指定是否需要计算某个 Tensor 的梯度。torch.no_grad() 上下文管理器则用于临时禁用所有计算图的构建。

  • 示例:使用 requires_gradno_grad

    x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
    
    with torch.no_grad():
        y = x * 2  # 在这里不会追踪 y 的梯度计算
    
    z = x * 3
    z.backward(torch.tensor([1.0, 1.0, 1.0]))
    print(x.grad)  # 只有 z 的梯度被计算
    

    在这个例子中,y 的计算不会影响梯度,因为它在 torch.no_grad() 块中。

性能优化和内存管理

PyTorch 的 Autograd 系统还包括了针对性能优化和内存管理的特性,比如梯度检查点(用于减少内存使用)和延迟执行(用于优化性能)。

  • 示例:梯度检查点

    使用 torch.utils.checkpoint 来减少大型网络中的内存占用。

    import torch.utils.checkpoint as checkpoint
    
    def run_fn(x):
        return x * 2
    
    x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
    y = checkpoint.checkpoint(run_fn, x)
    y.backward(torch.tensor([1.0, 1.0, 1.0]))
    

    这个例子展示了如何使用梯度检查点来优化内存使用。

关注TechLead,分享AI全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士,上亿营收AI产品研发负责人
如有帮助,请多关注
TeahLead KrisChang,10+年的互联网和人工智能从业经验,10年+技术和业务团队管理经验,同济软件工程本科,复旦工程管理硕士,阿里云认证云服务资深架构师,上亿营收AI产品业务负责人。文章来源地址https://www.toymoban.com/news/detail-776478.html

到了这里,关于深度解析 PyTorch Autograd:从原理到实践的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • RTMP协议深度解析:从原理到实践,掌握实时流媒体传输技术

    在当今的互联网时代,流媒体传输技术在人们的日常生活中扮演着越来越重要的角色。从在线教育到实时娱乐,流媒体技术已经渗透到了生活的方方面面。在这篇博客中,我们将从C++语言的角度,探讨流媒体传输技术的重要性,为什么选择RTMP协议以及RTMP协议的发展与应用。

    2023年04月26日
    浏览(88)
  • Python与Pytorch系列(二) 本文(1.8万字) | 解析Opencv, Matplotlib, PIL | 三者之间的转换 | 三者对JPG和PNG读取和写入 |

    点击进入专栏: 《人工智能专栏》 Python与Python | 机器学习 | 深度学习 | 目标检测 | YOLOv5及其改进 | YOLOv8及其改进 | 关键知识点 | 各种工具教程 推荐网站 : OpenCV Matplotlib Pillow opencv的基本图像类型可以和numpy数组相互转化,因此可以直接调用 torch.from_numpy(img) 将图像转换成 t

    2024年02月03日
    浏览(83)
  • Pytorch autograd.grad与autograd.backward详解

    平时在写 Pytorch 训练脚本时,都是下面这种无脑按步骤走: 对用户屏蔽底层自动微分的细节,使得用户能够根据简单的几个 API 将模型训练起来。这对于初学者当然是极好的,也是 Pytorch 这几年一跃成为最流行的深度学习框架的主要原因:易用性。 但是,我们有时需要深究自

    2023年04月09日
    浏览(44)
  • pytorch工具——pytorch中的autograd

    注意

    2024年02月15日
    浏览(32)
  • pytorch2 AutoGrad

    注意:grad在反向传播过程中是累加的(accumulated),这意味着每一次运行反向传播,梯度都会累加之前的梯度,所以一般在反向传播之前需把梯度清零 torch.Tensor 是这个包的核心类。如果设置它的属性 .requires_grad 为 True,那么它将会追踪对于该张量的所有操作。当完成计算后可以

    2024年02月11日
    浏览(40)
  • Pytorch Tutorial【Chapter 2. Autograd】

    1. Review Matrix Calculus 1.1 Definition向量对向量求导 ​ Define the derivative of a function mapping f : R n → R m f:mathbb{R}^ntomathbb{R}^m f : R n → R m as the n × m ntimes m n × m matrix of partial derivatives. That is, if x ∈ R n , f ( x ) ∈ R m xinmathbb{R}^n,f(x)inmathbb{R}^m x ∈ R n , f ( x ) ∈ R m , the derivative of f

    2024年02月14日
    浏览(37)
  • PyTorch 中autograd.Variable模块的基本操作

    在 PyTorch 中, autograd.Variable 是一个自动求导变量,用于构建计算图并进行梯度自动求导。 Variable 提供了许多基本操作,下面介绍其中的一些常用操作: 创建变量: 访问数据: 注意,PyTorch 1.0 版本后, Variable 被弃用,可以直接使用 Tensor。 反向传播计算梯度: 在创建变量时

    2024年02月11日
    浏览(33)
  • pytorch深度学习实践

    B站-刘二大人 参考-PyTorch 深度学习实践_错错莫的博客-CSDN博客

    2024年02月10日
    浏览(41)
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**

    PyTorch月学习计划 - 第6-7天: 自动梯度(Autograd) 学习目标: 掌握自动微分的基本原理,特别是在深度学习中的应用。 学会如何在PyTorch中使用autograd模块进行自动梯度计算。 学习内容: 自动微分和计算图的概念 自动微分:自动微分是深度学习中用于自动计算导数或梯度的技

    2024年01月21日
    浏览(46)
  • PyTorch detach():深入解析与实战应用

    PyTorch detach():深入解析与实战应用 在PyTorch中, detach() 函数是实现计算图灵活控制的关键。通过理解其背后的原理和应用场景,我们能够更有效地利用PyTorch进行深度学习模型的训练和优化。本文将深入探讨 detach() 函数的工作原理,并通过实战案例展示其在深度学习实践中的

    2024年02月20日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包