Pytorch自动求导机制、自定义**函数和梯度以及一些tips【深入Pytorch框架系列--2】
Pytorch自动求导机制、自定义**函数和梯度
前言:
由于pytorch框架只是提供了正向传播的机制,模块中的参数的梯度是通过自动求导推倒出来的,当我们需要自定义某一个针对张量的一些列操作时候就部够用了。
1 自动求导机制
Pytorch会根据计算过程来自动生成动态计算图,然后可以根据动态图的创建过程进行反向传播,计算得到每个节点的梯度直。
1.0 张量本身grad_fn
为了能记录张量的梯度,首先需要在张量创建的时候设置 requires_grad =True.
对于pytorch来说,每一个张量都有一个grad_fn方法,这个方法包含着创建该张量的运算的导数信息。本身携带计算图的信息,该方法还有一个next_functions属性,包含链接该张量的其他张量的grad_fn。
1.1 torch.autograd
Pytorch提供了一个专门用来做自动求导的包,torch.autograd.
包含2个重要函数:
1.1.1 torch.autograd.backward
这个函数通过传入根节点张量,以及初始梯度张量,可以计算产生该根节点所对应的叶子节点的梯度。
当张量为标量张量的时候(及只有一个元素的张量)可以部传入初始梯度张量,默认会设置初始梯度张量为1。
当计算梯度张量的时候,原先建立的计算图会自动释放,如果直接再次求导,肯定就会报错。
如果要在反向传播的时候保留计算图,可以设置retain_graph= True.
在自动求导的时候默认是不会建立反向传播图的,如果需要反向传播计算的同时建立和梯度张量相关的计算图,可以设置create_graph=Ture.
另外,对于一个可到的张量,也可以直接调用该张量内部的backward函数来自动求导。
t1=torch.randn(3,3,requires_grad=True)
t2 =t1.pow(2).sum()
#t2对t1张量求导
t2.backward()#反向传播
t1.grad
t2 =t1.pow(2).sum()
t2.backward()#再次反向传播
t1.grad #梯度累计
t1.grad.zero_() # 单个张量清零
1.1.2 torch.autograd.grad
在某些情况下,我们并不需要求出当前张量对所有产生该张量的叶子节点的梯度,这时候我们可以使用torch.autograd.grad方法。
该函数有2个参数,第一个参数是计算图的数据结果张量,第二个参数是需要对计算图求导的张量,最后输出的结果是第一个参数对第二个参数的求导结果,这个输出梯度也是会累计的。
要注意的地方:
1、这个函数部会改变叶子节点的grad属性。
2、反向传播求导时,自动释放计算图,如果要保留,可以设置retain_graph= True.
3、如果需要反向传播计算图,可以设置create_graph=Ture.
t1=torch.randn(3,3,requires_grad=True)
t2 =t1.pow(2).sum()
#t2对t1张量求导
torch.autograd.grad(t2,t1)
2 自定义**函数和梯度
在下一篇博文更新