码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 02.5 自动微分


    文章目录

      • 2.5 自动微分
        • 2.5.1. 一个简单的例子
        • 2.5.2. 非标量变量的反向传播
        • 2.5.3. 分离计算
        • 2.5.4. Python控制流的梯度计算
        • 2.5.5. 小结

    2.5 自动微分

    深度学习框架通过自动计算导数,即自动微分(automatic differentiation)来加快求导

    2.5.1. 一个简单的例子

    1、首先,我们创建变量x并为其分配一个初始值。

    import torch
    
    x = torch.arange(4.0)
    x
    
    tensor([0., 1., 2., 3.])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2、计算梯度

    x.requires_grad_(True)  # 等价于x=torch.arange(4.0,requires_grad=True)
    x.grad  # 默认值是None
    
    # 计算y
    y = 2 * torch.dot(x, x)
    y
    tensor(28., grad_fn=)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    x是一个长度为4的向量,计算x和x的点积,得到了我们赋值给y的标量输出。 接下来,我们通过调用反向传播函数来自动计算y关于x每个分量的梯度,并打印这些梯度。

    y.backward()
    x.grad
    
    tensor([ 0.,  4.,  8., 12.])
    
    • 1
    • 2
    • 3
    • 4

    快速验证这个梯度是否计算正确。

    x.grad == 4 * x
    
    tensor([True, True, True, True])
    
    • 1
    • 2
    • 3

    3、计算x的另一个函数

    # 在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
    x.grad.zero_()
    y = x.sum()
    y.backward()
    x.grad
    
    tensor([1., 1., 1., 1.])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.5.2. 非标量变量的反向传播

    # 对非标量调用backward需要传入一个gradient参数,该参数指定微分函数关于self的梯度。
    # 在我们的例子中,我们只想求偏导数的和,所以传递一个1的梯度是合适的
    x.grad.zero_()
    y = x * x
    # 等价于y.backward(torch.ones(len(x)))
    y.sum().backward()
    x.grad
    
    tensor([0., 2., 4., 6.])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    目的不是计算微分矩阵,而是单独计算批量中每个样本的偏导数之和。

    2.5.3. 分离计算

    下面的反向传播函数计算z=ux关于x的偏导数,同时将u作为常数处理, 而不是z=xx*x关于x的偏导数。

    x.grad.zero_()
    y = x * x
    u = y.detach()
    z = u * x
    
    z.sum().backward()
    x.grad == u
    
    tensor([True, True, True, True])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    由于记录了y的计算结果,我们可以随后在y上调用反向传播, 得到y=xx关于的x的导数,即2x。

    x.grad.zero_()
    y.sum().backward()
    x.grad == 2 * x
    
    tensor([True, True, True, True])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.5.4. Python控制流的梯度计算

    使用自动微分的一个好处是: 即使构建函数的计算图需要通过Python控制流(例如,条件、循环或任意函数调用),仍然可以计算得到的变量的梯度。

    def f(a):
        b = a * 2
        while b.norm() < 1000:
            b = b * 2
        if b.sum() > 0:
            c = b
        else:
            c = 100 * b
        return c
    
    a = torch.randn(size=(), requires_grad=True)
    d = f(a)
    d.backward()
    
    a.grad == d / a
    tensor(True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    2.5.5. 小结

    深度学习框架可以自动计算导数:

    • 我们首先将梯度附加到想要对其计算偏导数的变量上。
    • 然后我们记录目标值的计算,执行它的反向传播函数,并访问得到的梯度。
  • 相关阅读:
    JavaScript 原型、继承、原型链
    如何评价GPT-4o?【该回答来自GPT-4o】
    我在高职教STM32——LCD液晶显示(3)
    智慧社区管理系统08(维修和柱状图显现)
    如何使用反 CSRF 令牌保护您的网站和 Web 应用程序
    006-BSP学习笔记-kernel移植
    操作系统复习第四章:存储器管理
    【Hack The Box】linux练习-- time
    Node.js 入门教程 20 查看 npm 包安装的版本 & 21 安装 npm 包的旧版本
    RK3588平台开发系列讲解(显示篇)MIPI DSI协议介绍之分层
  • 原文地址:https://blog.csdn.net/weixin_45063703/article/details/126684254
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号