白癜风治疗最好医院 http://m.39.net/disease/yldt/bjzkbdfyy/
在PyTorch中,给我们提供了大量的预定义层,直接拿来就能用,但我们如何自己去设计一些层呢?
PyTorch里面一般是没有层的概念,所谓的层也是当成一个模型来处理的,因为都是通过继承nn.Module类来实现的。
1.解析官方预定义层
首先我们查看官方的源码了解一下网络层包含哪些成员和结构。
官方的线性层实现如下:
参数含义:
输入参数:input_features是输入向量长度,output_features是输出向量的长度,input是调用该类时的输入数据;
内部参数:weight是层的权重,bias是层的偏置;
内部函数:__init__是构造函数,forward是前向传播函数,reset_parameters是参数初始化函数。
其中nn.Parameter表示当前参数需要求导。
根据上述官方案例层总结得出,要实现一个自定义层需要以下三点:
A.自定义一个类,该类继承自nn.Module类,并且一定要实现两个基本的函数:构造函数__init__()、层的逻辑运算函数forward();
B.在构造函数__init__()中实现层的参数定义;
C.在前向传播forward函数中实现批数据的前向传播逻辑,只要在nn.Module的子类中定义了forward()函数,backward()函数就会被自动实现。
注意:一般情况下我们定义的参数是可导的,但是如果自定义操作不可导,就需要我们手动实现backward()函数。
因此,自定义层可以分为两种,一种是带参数的,一种是不带参数的。
2.自定义层
我们在前面模型构建时学过,模型构建是继承nn.Module类来实现的,其实自定义层也是通过继承Module类完成的,两者没有明显的区别。
核心都一样,自定义一个继承自nn.Module的类,在类的forward函数里实现该层的计算,区别在于带参数的层要用到nn.Parameter。
2.1不带参数的自定义层
下面的CenteredLayer类通过继承Module类自定义一个将输入减掉均值后输出的层,并将层的计算定义在forward函数。这个层不含模型参数。
代码演示如下:
2.2带参数的自定义层
在自定义含模型参数的层时,参数将定义成Parameter,这表示参数需要求导。
也可以使用ParameterList和ParameterDict分别定义参数的表和字典。
ParameterList接收一个Parameter实例的列表作为输入然后得到一个参数表,使用的时候可以用索引来访问某个参数,另外也可以使用append和extend在表后面新增参数。
ParameterDict接收一个Parameter实的字典作为输入然后得到一个参数字典,然后可以按照字典的规则使用。如使用update()新增参数,使用keys()返回所有键值,使用items()返回所有键值对。
3.自定义模型+自定义层训练演示
使用自定义层和自定义模型实现求解方程参数
假设函数y=w1*x1+w2*x2,已知数据x和y,基于损失函数MSELoss,利用训练学习的方式求参数w1和w2。
PyTorch代码演示如下:
总结
自定义层继承nn.module类;
含参数层的权重类型为Parameter;
至少实现两个函数__init__和forward;
自定义层如不可导,需要自行实现backward函数。