nn.Sequential

  • nn.Sequential()介绍
  • Pytorch官网举例
  • nn.Sequential()的本质作用
  • nn.Sequential()源码
  • nn.Sequential()介绍

    一个序列容器,用于搭建神经网络的模块被按照被传入构造器的顺序添加到nn.Sequential()容器中。除此之外,一个包含神经网络模块的OrderedDict也可以被传入nn.Sequential()容器中。利用nn.Sequential()搭建好模型架构,模型前向传播时调用forward()方法,模型接收的输入首先被传入nn.Sequential()包含的第一个网络模块中。然后,第一个网络模块的输出传入第二个网络模块作为输入,按照顺序依次计算并传播,直到nn.Sequential()里的最后一个模块输出结果。

    Pytorch官网举例

    看一下Pytorch官网举的例子:

    # Using Sequential to create a small model. When `model` is run,
    # input will first be passed to `Conv2d(1,20,5)`. The output of
    # `Conv2d(1,20,5)` will be used as the input to the first
    # `ReLU`; the output of the first `ReLU` will become the input
    # for `Conv2d(20,64,5)`. Finally, the output of
    # `Conv2d(20,64,5)` will be used as input to the second `ReLU`
    model = nn.Sequential(
              nn.Conv2d(1,20,5),
              nn.ReLU(),
              nn.Conv2d(20,64,5),
              nn.ReLU()
            )
    
    # Using Sequential with OrderedDict. This is functionally the
    # same as the above code
    model = nn.Sequential(OrderedDict([
              ('conv1', nn.Conv2d(1,20,5)),
              ('relu1', nn.ReLU()),
              ('conv2', nn.Conv2d(20,64,5)),
              ('relu2', nn.ReLU())
            ]))
    

    上述两种方法构建出的 model 和 model1 是一样的。

    nn.Sequential()的本质作用

    按照上边的说法,与一层一层的单独调用模块组成序列相比,nn.Sequential() 可以允许将整个容器视为单个模块(即相当于把多个模块封装成一个模块),forward()方法接收输入之后,nn.Sequential()按照内部模块的顺序自动依次计算并输出结果。

    这就意味着我们可以利用nn.Sequential() 自定义自己的网络层。

    from torch import nn
    
    
    class net(nn.Module):
        def __init__(self, in_channel, out_channel):
            super(net, self).__init__()
            self.layer1 = nn.Sequential(nn.Conv2d(in_channel, in_channel / 4, kernel_size=1),
                                        nn.BatchNorm2d(in_channel / 4),
                                        nn.ReLU())
            self.layer2 = nn.Sequential(nn.Conv2d(in_channel / 4, in_channel / 4),
                                        nn.BatchNorm2d(in_channel / 4),
                                        nn.ReLU())
            self.layer3 = nn.Sequential(nn.Conv2d(in_channel / 4, out_channel, kernel_size=1),
                                        nn.BatchNorm2d(out_channel),
                                        nn.ReLU())
            
        def forward(self, x):
            x = self.layer1(x)
            x = self.layer2(x)
            x = self.layer3(x)
            
            return x
    

    上边的代码,我们通过nn.Sequential()将卷积层,BN层和激活函数层封装在一个层中,输入x经过卷积、BN和ReLU后直接输出激活函数作用之后的结果。

    nn.Sequential()和torch.nn.ModuleList的区别在于:torch.nn.ModuleList只是一个储存网络模块的list,其中的网络模块之间没有连接关系和顺序关系。而nn.Sequential()内的网络模块之间是按照添加的顺序级联的。

    nn.Sequential()源码

    def __init__(self, *args):
            super(Sequential, self).__init__()
            if len(args) == 1 and isinstance(args[0], OrderedDict):
                for key, module in args[0].items():
                    self.add_module(key, module)
            else:
                for idx, module in enumerate(args):
                    self.add_module(str(idx), module)
    

    nn.Sequential()首先判断接收的参数是否为OrderedDict类型,如果是的话,分别取出OrderedDict内每个元素的key(自定义的网络模块名)和value(网络模块),然后将其通过add_module方法添加到nn.Sequrntial()中。

        # NB: We can't really type check this function as the type of input
        # may change dynamically (as is tested in
        # TestScript.test_sequential_intermediary_types).  Cannot annotate
        # with Any as TorchScript expects a more precise type
        def forward(self, input):
            for module in self:
                input = module(input)
            return input
    

    调用forward()方法进行前向传播时,for循环按照顺序遍历nn.Sequential()中存储的网络模块,并以此计算输出结果,并返回最终的计算结果。

    来源:一颗磐石

    物联沃分享整理
    物联沃-IOTWORD物联网 » nn.Sequential()

    发表评论