为何Tensor不是叶子张量?b的定义如何影响d的叶子张量属性?
PyTorch叶子节点判定与计算图的关系
核心逻辑:什么是叶子节点?
PyTorch里的**叶子节点(Leaf Tensor)**简单说就是:用户直接创建的、不是通过张量运算生成的张量。如果它的requires_grad=True,反向传播时会保留梯度;非叶子节点的梯度默认会被自动释放。
1. 为什么b的requires_grad会影响d的叶子节点状态?
场景1:b开启requires_grad
import torch a = torch.tensor(4, dtype=torch.float32) b = a.detach().clone().requires_grad_(True) c = b*b d = torch.empty_like(c).copy_(c).requires_grad_(True) print(b.is_leaf) # True print(d.is_leaf) # False
b是叶子节点:它是通过clone()直接生成的,然后手动开启梯度,不属于任何运算的输出;c = b*b是运算得到的张量,因为b开启了梯度,c也带有梯度,属于计算图里的中间节点;d用copy_(c)赋值时,c是计算图的一部分,d相当于绑定到了原计算图上,就算手动开启梯度,它也不是用户独立创建的张量,所以不是叶子节点。
场景2:b关闭requires_grad
import torch a = torch.tensor(4, dtype=torch.float32) b = a.detach().clone() c = b*b d = torch.empty_like(c).copy_(c).requires_grad_(True) print(b.is_leaf) # True print(d.is_leaf) # True
b是叶子节点:clone()直接生成,默认关闭梯度,属于用户直接创建的张量;c = b*b因为b没开梯度,自身也不带梯度,就是个普通的数值张量,和计算图完全无关;d复制c的数值时,相当于新建了一个张量再赋值,然后开启梯度,完全是用户独立创建的,所以是叶子节点。
2. 为什么detach().clone()总能让d成为叶子节点?
用d = c.detach().clone().requires_grad_(True)时,无论b开不开梯度,d都是叶子节点,原因很明确:
detach()直接把c和原计算图彻底断开,变成一个不带梯度的独立张量;clone()基于这个断开的张量生成新张量,这个新张量完全是用户独立创建的,和原计算图没有任何关联;- 最后开启梯度,完全符合叶子节点的判定条件,所以不管原计算图是什么状态,d都是叶子节点。
内容的提问来源于stack exchange,提问作者Jake Levi
相关产品推荐
相关产品推荐

