Pytorch学习-自动求导

import torch

x = torch.arange(4.0)
x
tensor([0., 1., 2., 3.])

在计算梯度之前,需要存放梯度

x.requires_grad_(True)
x.grad #默认为None
y = 2*torch.dot(x,x)
y
tensor(28., grad_fn=<MulBackward0>)

通过调用反向传播函数来自动计算y关于x每个分量的梯度

y.backward()
x.grad
tensor([ 0.,  4.,  8., 12.])
x.grad == 4*x
tensor([True, True, True, True])

现在计算x的另一个函数

#在默认情况下,PyTorch会累积梯度,我们需要清除之前的值
x.grad.zero_()
#求向量的sum,梯度为全1
y = x.sum()
y.backward()
x.grad
tensor([1., 1., 1., 1.])

在深度学习中,我们的目的不是计算微分矩阵,而是批量中每个样本单独计算的偏导数之和。

#对非标量调用"backward"需要传入一个'gradient'参数,该参数指定微分函数
x.grad.zero_()
y = x*x
#等价于y.backward(torch.ones(len(x)))
y.sum().backward()
x.grad
tensor([0., 2., 4., 6.])

将某些计算移动到记录的计算图之外

#梯度清零
x.grad.zero_()
y = x*x
#将u视为标量
u = y.detach()
z = u * x

z.sum().backward()
x.grad == u
tensor([True, True, True, True])
x.grad.zero_()
y.sum().backward()
x.grad == 2*x
tensor([True, True, True, True])

即使构建函数的计算图需要通过Python控制流(例如:条件、循环或任意函数调用),我们仍然可以计算得到的变量的梯度

def f(a):
    b = a*2
    #norm用于求矩阵或向量范数
    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)
原文地址:https://www.cnblogs.com/MurasameLory-chenyulong/p/14924223.html