动手学深度学习Pytorch版
2.5自动求导
#2.5.1 一个简单的例子
通过调用反向传播函数来自动计算y关于每个x分量的梯度。
import torch
x = torch.arange(4.0,requires_grad=True)
print(x)
print(x.grad)
y = 2 * torch.dot(x,x)
print(y)
y.backward()
print(x.grad)
print(x.grad==4*x)
x.grad.zero_()
y = x.sum()
y.backward()
print(y)
print(x.grad)
------
tensor([0., 1., 2., 3.], requires_grad=True)
None
tensor(28., grad_fn=<MulBackward0>)
tensor([ 0., 4., 8., 12.])
tensor([True, True, True, True])
tensor(6., grad_fn=<SumBackward0>)
tensor([1., 1., 1., 1.])
#2.5.2 非标量变量的反向传播
x.grad.zero_()
y = x*x
y.sum().backward()
print(x.grad)
------
tensor([0., 2., 4., 6.])
#2.5.3 分离计算
分离y返回新变量u,与y具有相同的值,但丢弃计算图中如何计算y的任何信息,将u作为常数处理。
x.grad.zero_()
y = x*x
u = y.detach()
z = u * x
z.sum().backward()
print(x.grad == u)
------
tensor([True, True, True, True])
y.sum().backward()
print(y.sum())
print(x.grad == 2*x)
------
tensor(14., grad_fn=<SumBackward0>)
tensor([True, True, True, True])
#2.5.4 Python控制流的梯度计算
下例中f(a)对任何a为线性。
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()
print(a.grad == d/a)
------
tensor(True)
小结
? 深度学习框架可以?动计算导数。为了使?它,我们?先将梯度附加到想要对其计算偏导数的变量上。 然后我们记录?标值的计算,执?它的反向传播函数,并访问得到的梯度。
|