Pytorch is_leaf 叶子张量

pytorch的叶子张量理解

  • 什么是叶子张量

什么是叶子张量

每个张量都有一个is_leaf属性用来判断是否为叶子节点
只有当requires_grad=True时我们才会记录该tensor的运算过程,并且为自动求导做准备,但是除了叶子张量可以有tensor.grad外,其他非叶子节点得不到反向传播时计算的grad
为什么需要两个条件来确定是否获取grad?
基本逻辑:

首先通过requires_grad判断是否为计算该节点梯度记录关于该节点计算梯度的信息,第二步就是判断是否为叶子节点来确定是否保留计算的grad到张量的grad属性里面。
如果非叶子张量也想要保留梯度用于可视化分析等等,你可以使用retain_grad()

1.所有reaquires_grad=False的张量都是叶子张量,为什么要把requires_grad=False的张量设置为叶子张量呢?
主要是为了节省判断条件的使用,如果requires_grad=False,我就不需要判断该节点是不是叶子节点,因为非叶子节点可以通过retain_grad来获取grad,这样就可以根据requires_grad=False直接做一个判断,这样也比较符合逻辑。

  1. requires_grad=True的张量,如果是由用户创建的,例如卷积核的参数,则它们是叶子张量,所有中间生成的结果都是非叶子节点
    如果一个节点是叶子节点,则代表它不是中间计算的结果,
    所以它的grad_fn is None
conv = nn.Conv2d(3,3,1)
conv.weight.is_leaf
#True

conv.weight.requires_grad=False
conv.weight.is_leaf
#True
#因为它requires_grad=False

3.只有叶子张量在反向传播的过程中才会将本身的grad传入backward()计算中,如果需要得到当前张量在反向传播中的参数,可以使用retain_grad()

a = torch.rand(2, requires_grad=True)
print(a.is_leaf)

b = torch.rand(2, requires_grad=True).cuda()
print(b.is_leaf)
# b was created by the operation that cast a cpu Tensor into a cuda Tensor
c = torch.rand(2, requires_grad=True) + 2
print(c.is_leaf)

# c was created by the addition operation
d = torch.rand(2).cuda()
print(d.is_leaf)

# d does not require gradients and so has no operation creating it (that is tracked by the autograd engine)
e = torch.rand(2).cuda().requires_grad_()
print(e.is_leaf)

# erequires gradients and has no operations creating it
f = torch.rand(2, requires_grad=True, device="cuda")
print(f.is_leaf)

# f requires grad, has no operation creating it
#True
#False
#False
#True
#True
#True

总结:
1.首先requires_grad这个是看用户需求进行设定,如果为false则把你视为叶子节点。requires_grad=False,而is_leaf=True,则不计算该张量的grad
2.如果requires_grad=True and is_leaf=True,则计算该张量的grad,并且把计算得到的grad放到该张量的grad属性里面,
3. requires_grad=True and is_leaf=False, 不保留grad.
4. 如果是非叶子节点,也就是requires_grad=True and is_leaf=False,则可以通过retain_grad()来得到grad

你可能感兴趣的:(torch.tensor,pytorch)