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

Pytorch自动求导机制、自定义**函数和梯度【下】【深入Pytorch框架系列--3】

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

2 自定义**函数和梯度

前言里说了,仅仅使用模块有时候是不能满足我们需要效果的。我们需要自定义**函数,在**函数中定义前向传播和反向传播的代码来实现自己的需求。

2.1 类及方法

Pytorch自定义**函数继承于torch.autograd.Function,其内部有2个静态方法:forward和backward

class Func(torch.autograd.Function):
    @staticmethod
    def forward(ctx,input):
        return result
    
    @staticmethod
    def backward(ctx,grad_output):
        return grad_output

2.2 实例

Quoc V.Le等人的研究成果中,将Swish**函数定义为

Pytorch自动求导机制、自定义**函数和梯度【下】【深入Pytorch框架系列--3】

有关Swish的具体**函数分析,可以看我之前写的一篇博文:
【最全**函数系列】读Paper概述近年常用深度学习神经网络**函数

这里主要是过一遍怎么自定义实现他。

可以看到,这个公式还是比较复杂的,如果要生成图,中间有部少计算节点。

有了公式之后,我们可以求出导数函数,这样方便进行反向传播。

有了**函数和其导数函数,我们就可以来自定义相关**函数了。

swish =Swish.apply #获得**函数
torch.autograd.gradcheck(
swish,torch.randn(
10,requires_grad =True,
dtype =torch.double)
)
#测试反向传播,正常返回值为True

class Swish(torch.autograd.Function):
    @staticmethod
    def forward(ctx,input):
        ctx.input =input
        return input*torch.sigmoid(1*input) #假设b=1
     @staticmethod
    def backward(ctx,grad_output):
        ctx.input =input
        tmp = torch.sigmoid(1*input)
        
        return grad_output*(tmp +1 *input*tmp(1-tmp))
    

2.3 tips

在上面代码可以看到,我们记录了前像传播和反向传播的过程,并且在backward方法中实现了数值梯度的方法。

可以通过讲apply方法赋值给一个变量的方法来**自定义的**函数。

为了保持梯度精度,我们一般都使用双精度类型为张量数值类型

2.4 推荐博文

【最全**函数系列】读Paper概述近年常用深度学习神经网络**函数