【2022.11.22】pytorch的grad与backward
在上一篇学习原理的时候,卡在了grad怎么计算上,如果不能理解grad,那么就难以理解反向传播
本次参考的教程来源是Pytorch autograd,backward详解 - marsggbo - 博客园 (cnblogs.com)
用一段代码来说明
import torch
x = torch.rand(3, requires_grad=True)
print(x) # tensor([0.9716, 0.6789, 0.7357], requires_grad=True)
print(x.is_leaf) # True
print(x.grad_fn) # None
y = x**2
print(y) # tensor([0.9439, 0.4609, 0.5412], grad_fn=<PowBackward0>)
print(y.is_leaf) # False
print(y.grad_fn) # <PowBackward0 object at 0x00000282A37A4EB0>
z = x + x
print(z) # tensor([1.9431, 1.3578, 1.4714], grad_fn=<AddBackward0>)
print(z.is_leaf) # False
print(z.grad_fn) # <AddBackward0 object at 0x00000282A37A4EB0>
如果我们需要计算某个Tensor的导数,那么我们需要设置其.requires_grad
属性为True
。为方便说明,在本文中对于这种我们自己定义的变量,我们称之为叶子节点(leaf nodes),而基于叶子节点得到的中间或最终变量则可称之为结果节点。
代码
x = torch.tensor(1.0, requires_grad=True)
y = torch.tensor(2.0, requires_grad=True)
z = x**2+y
z.backward()
print(z)
print(x.grad)
print(y.grad)
可以得到输出
tensor(3., grad_fn=<AddBackward0>)
tensor(2.)
tensor(1.)
backward在tensor内有如下定义
def backward(
self, gradient=None, retain_graph=None, create_graph=False, inputs=None
)
tensor
: 用于计算梯度的tensor。也就是说这两种方式是等价的:torch.autograd.backward(z) == z.backward()
grad_tensors
: 在计算矩阵的梯度时会用到。他其实也是一个tensor,shape一般需要和前面的tensor
保持一致。
retain_graph
: 通常在调用一次backward后,pytorch会自动把计算图销毁,所以要想对某个变量重复调用backward,则需要将该参数设置为True
create_graph
: 当设置为True
的时候可以用来计算更高阶的梯度