zoukankan      html  css  js  c++  java
  • Autograd: 自动求导

    Pytorch中神经网络包中最核心的是autograd包,我们先来简单地学习它,然后训练我们第一个神经网络。

    autograd包为所有在tensor上的运算提供了自动求导的支持,这是一个逐步运行的框架,也就意味着后向传播过程是按照你的代码定义的,并且单个循环可以不同

    我们通过一些简单例子来了解

    Tensor

    torch.tensor是这个包的基础类,如果你设置.requires_grads为True,它就会开始跟踪上面的所有运算。如果你做完了运算使用.backward(),所有的梯度就会自动运算,tesor的梯度将会累加到.grad这个属性。

    若要停止tensor的历史纪录,可以使用.detch()将它从历史计算中分离出来,防止未来的计算被跟踪。

     为了防止追踪历史(并且使用内存),你也可以将代码块包含在with torch.no_grad():中。这对于评估模型时是很有用的,因为模型也许拥有可训练的参数使用了requires_grad=True,但是这种情况下我们不需要梯度。

    还有一个类对autograd的实现非常重要,——Function

    Tensor和Function是相互关联的并一起组成非循环图,它编码了所有计算的历史,每个tensor拥有一个属性.grad_fn,该属性引用已创建tensor的Function。(除了用户自己创建的tensor,它们的.grad_fn为None)。

    如果你想计算导数,可以在一个Tensor上调用.backward()。如果Tensor是一个标量(也就是只包含一个元素数据),你不需要为backward指明任何参数,但是拥有多个元素的情况下,你需要指定一个匹配维度的gradient参数。

    import torch

    创建一个tensor并设置rquires_grad=True来追踪上面的计算

    x=torch.ones(2,2,requires_grad=True)
    print(x)
    
    out:
    tensor([[ 1.,  1.],
            [ 1.,  1.]])

    执行一个tensor运算

    y=x+2
    print(y)

    out:
    tensor([[ 3., 3.],
    [ 3., 3.]])

    y是通过运算的结果建立的,所以它有grad_fn

    print(y.grad_fn)

    out:
    <AddBackward0 object at 0x000001EDFE054D30>

    在y上进行进一步的运算

    z=y*y*3
    out=z.mean()
    print(z,out)
    
    out:
    tensor([[ 27.,  27.],
            [ 27.,  27.]]) tensor(27.)

    .requires_grad_(...)可以用内建方式改变tensor的requires_grad标志位。如果没有给定,输入标志默认为False

    a=torch.randn(2,2)
    a=((a*3)/(a-1))
    print(a.requires_grad)
    a.requires_grad_(True)
    print(a.requires_grad)
    b=(a*a).sum()
    print(b.grad_fn)

    out:
    False
    True
    <SumBackward0 object at 0x000001EDFE054940>

    Gradients

    我们开始反向传播,因为out包含单一标量,out.backward()相当于out.backward(torch.tensor(1)).

    out.backward()

    打印梯度d(out)/dx

    print(x.grad)

    out:
    tensor([[ 4.5000, 4.5000],
    [ 4.5000, 4.5000]])

    你应该得到一个4.5的矩阵。可以简单手动计算一下这一结果。

    你可以使用autograd做许多疯狂的事情

    x=torch.randn(3,requires_grad=True)
    y=x*2
    while y.data.norm()<1000:
        y=y*2
    print(y)

    out:
    tensor([  980.8958,  1180.4403,   614.2102])
    gradients=torch.tensor([0.1,1.0,0.0001],dtype=torch.float)
    y.backward(gradients)
    print(x.grad)

    out:
    tensor([  102.4000,  1024.0000,     0.1024])

    你可以将语句包含在with torch.no_grad()从Tensor的历史停止自动求导

    print(x.requires_grad)
    print((x**2).requires_grad)
    with torch.no_grad():
        print((x**2).requires_grad)
    
    out:
    True
    True
    False

       

  • 相关阅读:
    Ansible
    Ansible
    MySQL
    JS计算时间差(天,时,分钟,秒)
    cookie,localStorage,sessionStorage的区别
    css布局 -双飞翼布局&圣杯布局
    Python批量爬取网站图片
    vue-cli3中引入图片的几种方式和注意事项
    git常用命令
    vue-cli3的打包并在本地查看
  • 原文地址:https://www.cnblogs.com/Thinker-pcw/p/9630367.html
Copyright © 2011-2022 走看看