leaf Variable、requires_grad、grad_fn的含义以及它们之间的关系

文章内容皆为个人理解,不足之处敬请指正。

1、requires_grad
requires_grad是pytorch中tensor的一个属性,如果requires_grad=True,在进行反向传播的时候会记录t该tensor梯度信息。为了下面方便举例,我将进行运算的tensor称为父tensor,运算后的tensor称为子tensor,比如:c=a+b,c就是子tensor,a、b都为父tensor。

import torch
a=torch.tensor([1.,2,3,4],requires_grad=True)
b=torch.tensor([1.,2,3,4],requires_grad=False) #默认False
c=torch.sum(a*2)
c.backward()
print(a.grad)

d=torch.sum(b+a)
d.backward()
print(b.grad)
print(b.requires_grad)
'''结果
tensor([2., 2., 2., 2.])
None
True   #只要父tensor里有requires_grad=True的,子tensor的requires_grad=True
'''

可以看到requires_grad=True时进行反向传播会记录tensor的梯度信息,很方便我们使用梯度下降法。

2、grad_fn
grad_fn也是tensor的一个属性,它记录的是tensor的运算信息,比如c=a+b,那么c.grad_fn=,记录grad_fn信息的意义有利于我们使用反向传播算法,由子tensor计算父tensor的梯度。

import torch
a=torch.tensor([1.,2,3,4],requires_grad=True)
b=torch.tensor([1.,2,3,4],requires_grad=False) #默认false
c=a+b
print(a.grad_fn,b.grad_fn)
print(c.grad_fn)
print(c)
'''结果
None None

tensor([2., 4., 6., 8.], grad_fn=)
'''

a、b是直接创建的、没有经过运算的tensor,其grad_fn=None,还有一个值得注意的地方,如果父tensor的requires_grad都为False,子tensor的grad_fn=None。因为你都不准备记录父tensor的梯度信息了,那么再记录子tensor的grad_fn信息也没什么必要了。

import torch
a=torch.tensor([1.,2,3,4],requires_grad=False)
b=torch.tensor([1.,2,3,4],requires_grad=False) #默认false
c=a+b
print(c.grad_fn)
print(c)
'''结果
None
tensor([2., 4., 6., 8.])
'''

3、leaf Variable
在写leaf Variable之前,我想先写一下Variable,可以帮助理清leaf Variable、requires_grad、grad_fn之间的关系。我们都知道,用pytorch搭建神经网络,数据都是tensor类型的,在先前的一些pytorch版本中(到底哪些我也不清楚,当前v1.3.1),tensor似乎只包含data信息,不会记录requires_grad、grad_fn信息,转化成variable之后才会有requires_grad和grad_fn属性。现在Variable基本可以被直接用tensor替代了,虽然现在还保留着Variable方法,我觉得用不到了,直接用tensor就可以了。

#Variable的使用
from torch.autograd import Variable
a=Variable(tensor,requires_gard=bool)

leaf variable,你直接理解为手动创建的tensor也无妨,运算得到的tensor都不是leaf variable,可以用 .is_leaf查看tensor是否为leaf variable。

import torch
a=torch.tensor([1.,2,3,4],requires_grad=True)
b=torch.tensor([1.,2,3,4],requires_grad=False) #默认false
c=a+b
print(a.is_leaf)
print(c.is_leaf)
'''结果
True
False
'''

如果只这么理解,我觉得也足够了。

但其实还有一类经过运算得到的tensor也可以为leaf variable,那就是父tensor的requires_grad全为False的子tensor,

import torch
a=torch.tensor([1.,2,3,4],requires_grad=False)
b=torch.tensor([1.,2,3,4],requires_grad=False) #默认false
c=a+b
print(c.is_leaf)
print(c.grad_fn)
'''结果
True
None
'''

所以,更准确的来说,应该是grad_fn为None的tensor都是leaf variable,反之皆不是。我们可以例子中的c=a+b看作是一种直接创建tensor的方法,因为父tensor a和b除了进行c=a+b运算创建c之外,以后的反向传播算法以及我们关心的梯度,跟他俩都没关系(这儿可以把a、b、c当成神经网络底层的一部分),所以,从c才可能开始与梯度打交道。

你可能感兴趣的:(pytorch,神经网络)