【深度学习】torch.nn.Sequential方法介绍 以你之姓@ 2023-10-02 23:18 1阅读 0赞 `torch.nn.Sequential`是一个`Sequential`容器,模块将按照构造函数中传递的顺序添加到模块中。 另外,也可以传入一个有序模块。 作用:Sequential除了本身可以用来定义模型之外,它还可以包装层,把几个层包装起来像一个块一样。 具体理解如下: ### 一、普通构建网络 ### import torch import torch.nn as nn class Net(nn.Module): def __init__(self, n_feature, n_hidden, n_output): super(Net, self).__init__() self.hidden = nn.Linear(n_feature, n_hidden) self.predict = nn.Linear(n_hidden, n_output) def forward(self, x): x = F.relu(self.hidden(x)) # 隐藏层后接relu层 x = self.predict(x) return x model_1 = Net(1, 10, 1) print(model_1) 输出为: Net ( (hidden): Linear(in features=l, out features=10, bias=True)predict): Linear(in features=10, out features=l, bias=True) ) ### 二、使用Sequential快速搭建网络 ### import torch import torch.nn as nn class Net(nn.Module): def __init__(self, n_feature, n_hidden, n_output): super(Net,self).__init__() self.net_1 = nn.Sequential( nn.Linear(n_feature, n_hidden), nn.ReLU(), nn.Linear(n_hidden, n_output) ) def forward(self,x): x = self.net_1(x) return x model_2 = Net(1,10,1) print(model_2) 输出为: Net ( (net 1): Sequential((0): Linear(in features=l, out features=10, bias=True)(1): ReLU0(2): Linear(in features=10, out features=1, bias=True) ) ) ### 三、关于Sequential类的简介 ### Sequential似乎是一个容器,的确,它是可以作为一个容器包装各层。这里先简单的看一下它的定义: class Sequential(Module): # 继承Module def __init__(self, *args): # 重写了构造函数 def _get_item_by_idx(self, iterator, idx): def __getitem__(self, idx): def __setitem__(self, idx, module): def __delitem__(self, idx): def __len__(self): def __dir__(self): def forward(self, input): # 重写关键方法forward 再看一下container.py里面还有那些“容器”存在: 1 class Container(Module): 2 class Sequential(Module): 3 class ModuleList(Module): 4 class ModuleDict(Module): 5 class ParameterList(Module): 6 class ParameterDict(Module): ## 四、Sequential类的三种实现 ## ### 4.1 最简单的序贯模型 ### import torch.nn as nn model = nn.Sequential( nn.Conv2d(1,20,5), nn.ReLU(), nn.Conv2d(20,64,5), nn.ReLU() ) print(model) print(model[2]) # 通过索引获取第几个层 '''运行结果为: Sequential( (0): Conv2d(1, 20, kernel_size=(5, 5), stride=(1, 1)) (1): ReLU() (2): Conv2d(20, 64, kernel_size=(5, 5), stride=(1, 1)) (3): ReLU() ) Conv2d(20, 64, kernel_size=(5, 5), stride=(1, 1)) ''' 注意:这种实现方法有一个问题,那就是每一层是没有名称的,默认的是以0、1、2、3来命名。 ### 4.2 给每一层添加名称 ### import torch.nn as nn from collections import OrderedDict model = nn.Sequential(OrderedDict([ ('conv1', nn.Conv2d(1, 20, 5)), ('relu1', nn.ReLU()), ('conv2', nn.Conv2d(20, 64, 5)), ('relu2', nn.ReLU()) ])) print(model) print(model[2]) # 通过索引获取第几个层 print(model.conv1) '''运行结果为: Sequential( (conv1): Conv2d(1, 20, kernel_size=(5, 5), stride=(1, 1)) (relu1): ReLU() (conv2): Conv2d(20, 64, kernel_size=(5, 5), stride=(1, 1)) (relu2): ReLU() ) Conv2d(20, 64, kernel_size=(5, 5), stride=(1, 1)) Conv2d(1, 20, kernel_size=(5, 5), stride=(1, 1)) ''' 注意:从上面的结果中可以看出,这个时候每一个层都有了自己的名称,但是此时需要注意,并不能通过名称直接获取层,依然只能通过索引index,即model\[2\],不能通过model\[“conv2”\]来获取。这其实是由它的定义实现的,看上面的Sequential定义可知,支持inddex访问。但可以通过model.covn2获取。 ### 4.3 Sequential的第三种实现 ### import torch.nn as nn from collections import OrderedDict model = nn.Sequential() model.add_module("conv1", nn.Conv2d(1, 20, 5)) model.add_module('relu1', nn.ReLU()) model.add_module('conv2', nn.Conv2d(20, 64, 5)) model.add_module('relu2', nn.ReLU()) print(model) print(model[2]) # 通过索引获取第几个层 print(model.conv1) """运行结果为: Sequential( (conv1): Conv2d(1, 20, kernel_size=(5, 5), stride=(1, 1)) (relu1): ReLU() (conv2): Conv2d(20, 64, kernel_size=(5, 5), stride=(1, 1)) (relu2): ReLU() ) Conv2d(20, 64, kernel_size=(5, 5), stride=(1, 1)) Conv2d(1, 20, kernel_size=(5, 5), stride=(1, 1)) """ 注意:Sequential里面并没有定义add\_module()方法,实际上,这个方法是定义在它的父类Module里面的,Sequential继承了而已,它的定义如下: def add_module(self, name, module):
还没有评论,来说两句吧...