• 02.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. 小结

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

    • 我们首先将梯度附加到想要对其计算偏导数的变量上。
    • 然后我们记录目标值的计算,执行它的反向传播函数,并访问得到的梯度。
  • 相关阅读:
    问:未来5年的IT互联网行业,就业形势会是什么样的?
    阶段七-Day01-SpringMVC
    初级篇—第六章创建和管理表
    mingw-gcc编译窗体和console
    本地数仓网络设备迁移实录
    iOS代码混淆教程
    硬核 阿里P8终于把(数据结构与算法经典问题解析)讲全了
    (附源码)ssm失物招领平台 毕业设计 271621
    Leetcode 剑指 Offer II 001. 整数除法
    qml Textinput 、TextField、TextEdit、TextArea用法介绍
  • 原文地址:https://blog.csdn.net/weixin_45063703/article/details/126684254