【深度学习】torch.nn.Sequential方法介绍
admin
2024-02-06 02:53:49

torch.nn.Sequential是一个Sequential容器,模块将按照构造函数中传递的顺序添加到模块中。

另外,也可以传入一个有序模块。

作用:Sequential除了本身可以用来定义模型之外,它还可以包装层,把几个层包装起来像一个块一样。

具体理解如下:

一、普通构建网络

import torch
import torch.nn as nnclass 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 xmodel_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 nnclass 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 xmodel_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): # 继承Moduledef __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 OrderedDictmodel = 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 OrderedDictmodel = 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):

相关内容

热门资讯

最新或2023(历届)军人退役... 近日,国务院、中央军委批准改革完善军人退役养老保险制度。这是党中央、国务院、中央军委深化军人保险制度...
最新或2023(历届)关于军队... 十八大以来,习近平主席就加强军队建设提出了一系列新理念,令人耳目一新。党的十八届三中全会通过的《中共...
浙江省物业管理条例(全文) 浙...   第一章 总 则  第一条 为规范物业管理活动,维护业主和物业服务企业的合法权益,根据国务院《物业...
云南二胎新政策最新或2023(... 云南省已于最新或2023(历届)3月28日正式开始实施单独二胎政策,具体政策内容和办证指南请见下表!...
河北二胎新政策 最新或2023...   二胎政策是中国实行的一种和计划生育政策相对应的生育政策,指符合指定条件的夫妇允许生育“二胎”。最...