欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Pytorch自动求导机制、自定义**函数和梯度以及一些tips【深入Pytorch框架系列--2】

程序员文章站 2022-05-27 09:52:40
...

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 自定义**函数和梯度

在下一篇博文更新