torch.nn.Function类
自定义模型、自定义层、自定义激活函数、自定义损失函数都属于pytorch的拓展,前面讲过通过继承torch.nn.Module类来实现拓展,它最大的特点是以下几点:
- 包装torch普通函数和torch.nn.functional专用于神经网络的函数;(torch.nn.functional是专门为神经网络所定义的函数集合)
- 只需要重新实现__init__和forward函数,求导的函数是不需要设置的,会自动按照求导规则求导。
- 可以保存参数和状态信息;
注意:当在构建模型时,有时候一些****操作是不可导****的,这时候你需要自定义求导方式,就不能再使用上面提到的方式了,需要通过继承torch.nn.Function类来实现拓展。
它最大的特点是:
- 在有些操作通过组合pytorch中已有的层或者是已有的方法实现不了的时候,比如你要实现一个新的方法,这个新的方法需要forward和backward一起写,然后自己写对中间变量的操作。
- 需要重新实现__init__和forward函数,以及backward函数,需要自己定义求导规则;
- 不可以保存参数和状态信息
Function类和Module类最明显的区别是它多了一个backward方法,这也是他俩****最本质的区别:****
如果某一个类my_function继承自Function类,实现了这个类的forward和backward方法,那么我依然可以用nn.Module对这个自定义的类my_function进行包装组合。
# 定义一个继承了Function类的子类,实现y=f(x)的正向运算以及反向求导
class sqrt_and_inverse(torch.autograd.Function):
'''
本例子所采用的数学公式是:
z=sqrt(x)+1/x+2*power(y,2)
z是关于x,y的一个二元函数它的导数是
z'(x)=1/(2*sqrt(x))-1/power(x,2)
z'(y)=4*y
forward和backward可以定义成静态方法,向定义中那样,也可以定义成实例方法
'''
# 前向运算
def forward(self, input_x, input_y):
'''
self.save_for_backward(input_x,input_y) ,这个函数是定义在Function的父类_ContextMethodMixin中
它是将函数的输入参数保存起来以便后面在求导时候再使用,起前向反向传播中协调作用
''