对于cnn前馈神经网络如果前馈一次写一个forward函数会有些麻烦,在此就有两种简化方式,ModuleList和Sequential。其中Sequential是一个特殊的module,它包含几个子Module,前向传播时会将输入一层接一层的传递下去。ModuleList也是一个特殊的module,可以包含几个子module,可以像用list一样使用它,但不能直接把输入传给ModuleList。下面举例说明。

目录

一、nn.Sequential()对象

1、模型建立方式

第一种写法:

第二种写法:

第三种写法:

2、检查以及调用模型

查看模型

根据名字或序号提取子Module对象

调用模型

二、nn.ModuleList()对象

为什么有他?

什么时候用?

和list的区别?

1. extend和append方法

2. 建立以及使用方法

3. yolo v3构建网络

一、nn.Sequential()对象
建立nn.Sequential()对象,必须小心确保一个块的输出大小与下一个块的输入大小匹配。基本上,它的行为就像一个nn.Module。

1、模型建立方式

第一种写法:
nn.Sequential()对象.add_module(层名,层class的实例)

1

2

3

4

net1 = nn.Sequential()

net1.add_module('conv', nn.Conv2d(3, 3, 3))

net1.add_module('batchnorm', nn.BatchNorm2d(3))

net1.add_module('activation_layer', nn.ReLU())

第二种写法:
nn.Sequential(*多个层class的实例)

1

2

3

4

5

net2 = nn.Sequential(

nn.Conv2d(3, 3, 3),

nn.BatchNorm2d(3),

nn.ReLU()

)

第三种写法:
nn.Sequential(OrderedDict([*多个(层名,层class的实例)]))

1

2

3

4

5

6

from collections import OrderedDict

net3= nn.Sequential(OrderedDict([

('conv', nn.Conv2d(3, 3, 3)),

('batchnorm', nn.BatchNorm2d(3)),

('activation_layer', nn.ReLU())

]))

2、检查以及调用模型

查看模型
print对象即可

1

2

3

print('net1:', net1)

print('net2:', net2)

print('net3:', net3)

net1: Sequential(
(conv): Conv2d (3, 3, kernel_size=(3, 3), stride=(1, 1))
(batchnorm): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True)
(activation_layer): ReLU()
)
net2: Sequential(
(0): Conv2d (3, 3, kernel_size=(3, 3), stride=(1, 1))
(1): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True)
(2): ReLU()
)
net3: Sequential(
(conv): Conv2d (3, 3, kernel_size=(3, 3), stride=(1, 1))
(batchnorm): BatchNorm2d(3, eps=1e-05, momentum=0.1, affine=True)
(activation_layer): ReLU()
)

根据名字或序号提取子Module对象
1

2

# 可根据名字或序号取出子module

net1.conv, net2[0], net3.conv

(Conv2d (3, 3, kernel_size=(3, 3), stride=(1, 1)),
Conv2d (3, 3, kernel_size=(3, 3), stride=(1, 1)),
Conv2d (3, 3, kernel_size=(3, 3), stride=(1, 1)))

调用模型
可以直接网络对象(输入数据),也可以使用上面的Module子对象分别传入(input)。

1

2

3

4

5

input = V(t.rand(1, 3, 4, 4))

output = net1(input)

output = net2(input)

output = net3(input)

output = net3.activation_layer(net1.batchnorm(net1.conv(input)))

二、nn.ModuleList()对象
为什么有他?
写一个module然后就写foreword函数很麻烦,所以就有了这两个。它被设计用来存储任意数量的nn. module。

什么时候用?
如果在构造函数__init__中用到list、tuple、dict等对象时,一定要思考是否应该用ModuleList或ParameterList代替。

如果你想设计一个神经网络的层数作为输入传递。

和list的区别?
ModuleList是Module的子类,当在Module中使用它的时候,就能自动识别为子module。

当添加 nn.ModuleList 作为 nn.Module 对象的一个成员时(即当我们添加模块到我们的网络时),所有 nn.ModuleList 内部的 nn.Module 的 parameter 也被添加作为 我们的网络的 parameter。

class MyModule(nn.Module):
def __init__(self):
super(MyModule, self).__init__()
self.linears = nn.ModuleList([nn.Linear(10, 10) for i in range(10)])

def forward(self, x):
# ModuleList can act as an iterable, or be indexed using ints
for i, l in enumerate(self.linears):
x = self.linears[i // 2](x) + l(x)
return x
1. extend和append方法
nn.moduleList定义对象后,有extend和append方法,用法和python中一样,extend是添加另一个modulelist  append是添加另一个module

class LinearNet(nn.Module):
def __init__(self, input_size, num_layers, layers_size, output_size):
super(LinearNet, self).__init__()

self.linears = nn.ModuleList([nn.Linear(input_size, layers_size)])
self.linears.extend([nn.Linear(layers_size, layers_size) for i in range(1, self.num_layers-1)])
self.linears.append(nn.Linear(layers_size, output_size)
2. 建立以及使用方法
建立以及使用方法如下,

1

2

3

4

5

6

modellist = nn.ModuleList([nn.Linear(3,4), nn.ReLU(), nn.Linear(4,2)])

input = V(t.randn(1, 3))

for model in modellist:

input = model(input)

# 下面会报错,因为modellist没有实现forward方法

# output = modelist(input)

和普通list不一样,它和torch的其他机制结合紧密,继承了nn.Module的网络模型class可以使用nn.ModuleList并识别其中的parameters,当然这只是个list,不会自动实现forward方法,

1

2

3

4

5

6

7

8

9

class MyModule(nn.Module):

def __init__(self):

super(MyModule, self).__init__()

self.list = [nn.Linear(3, 4), nn.ReLU()]

self.module_list = nn.ModuleList([nn.Conv2d(3, 3, 3), nn.ReLU()])

def forward(self):

pass

model = MyModule()

print(model)

MyModule(
(module_list): ModuleList(
(0): Conv2d (3, 3, kernel_size=(3, 3), stride=(1, 1))
(1): ReLU()
)
)
1

2

for name, param in model.named_parameters():

print(name, param.size())

('module_list.0.weight', torch.Size([3, 3, 3, 3]))
('module_list.0.bias', torch.Size([3]))
可见,普通list中的子module并不能被主module所识别,而ModuleList中的子module能够被主module所识别。这意味着如果用list保存子module,将无法调整其参数,因其未加入到主module的参数中。

除ModuleList之外还有ParameterList,其是一个可以包含多个parameter的类list对象。在实际应用中,使用方式与ModuleList类似。

3. yolo v3构建网络
首先module_list = nn.ModuleList()

然后

for index, x in enumerate(blocks[1:]):#根据不同的block 遍历module

module = nn.Sequential()

然后根据cfg读进来的数据,

module.add_module("batch_norm_{0}".format(index), bn)

module.add_module("conv_{0}".format(index), conv)

等等

module_list.append(module)

---------------------
作者:Snoopy_Dream
来源:CSDN
原文:https://blog.csdn.net/e01528/article/details/84397174
版权声明:本文为博主原创文章,转载请附上博文链接!

nn.moduleList 和Sequential由来、用法和实例 —— 写网络模型的更多相关文章

  1. [pytorch笔记] torch.nn vs torch.nn.functional; model.eval() vs torch.no_grad(); nn.Sequential() vs nn.moduleList

    1. torch.nn与torch.nn.functional之间的区别和联系 https://blog.csdn.net/GZHermit/article/details/78730856 nn和n ...

  2. tf.nn.embedding_lookup TensorFlow embedding_lookup 函数最简单实例

    tf.nn.embedding_lookup TensorFlow embedding_lookup 函数最简单实例 #!/usr/bin/env python # -*- coding: utf-8 ...

  3. java中List的用法和实例详解

    java中List的用法和实例详解 List的用法List包括List接口以及List接口的所有实现类.因为List接口实现了Collection接口,所以List接口拥有Collection接口提供 ...

  4. Matlab 之meshgrid, interp, griddata 用法和实例

    http://blog.sina.com.cn/s/blog_67f37e760101bu4e.html 实例结果http://wenku.baidu.com/link?url=SiGsFZIxuS1 ...

  5. Matlab 之meshgrid, interp, griddata 用法和实例(转)

    http://blog.sina.com.cn/s/blog_67f37e760101bu4e.html 实例结果http://wenku.baidu.com/link?url=SiGsFZIxuS1 ...

  6. [转] php foreach用法和实例

    PHP 4 引入了 foreach 结构,和 Perl 以及其他语言很像.这只是一种遍历数组简便方法.foreach 仅能用于数组,当试图将其用于其它数据类型或者一个未初始化的变量时会产生错误.有两种 ...

  7. echo命令的简单用法和实例

    在CentOS 6.8版本下,通过实例的形式,展现选项和参数的灵活运用,可以简明的了解echo的用法. 一.语法:echo [SHORT-OPTION]… [STRING]… :echo [选项]…[ ...

  8. Vue.directive()的用法和实例

    官网实例: https://cn.vuejs.org/v2/api/#Vue-directive https://cn.vuejs.org/v2/guide/custom-directive.html ...

  9. Liunx(centos8)下的yum的基本用法和实例

    yum 命令 Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及CentOS中的Shell前端软件包管理器.基于RPM包管理,能够从指定的 ...

随机推荐

  1. hibernate 查询最大值(数据条目数)

    如下 使用 SELECT COUNT(*) 然后获取最大值 Integer.parseInt(query.list().).toString()); 比如 StringBuffer hql1; hql ...

  2. day36 11-Hibernate中的事务:当前线程中的session

    如果你没有同一个session开启事务的话,那它两是一个独立的事务.必须是同一个session才有效.它给我们提供一个本地线程的session.这个session就保证了你是同一个session.其实 ...

  3. Codevs2490 导弹防御塔

    2490 导弹防御塔 2490 导弹防御塔 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master         题目描述 Description Freda的城堡—— ...

  4. SPOJ GSS5

    GSS5 - Can you answer these queries V #tree You are given a sequence A[1], A[2], ..., A[N] . ( |A[i] ...

  5. 【笔记】http协议笔记

    本文是本人在复习http协议时,手动整理的资料,以备后续查阅. http(hypertext transfer protocol):超文本协议.是万维网(world wide web,www,也简称为 ...

  6. jmeter 之 https 请求

    本文为自己学习总结,转载需说明出处. jmeter发送https请求需要在巨jmeter中导入被测试网站的安全证书. 一.通过浏览器登录对应的网站导出安全证书.下面操作以360浏览器为例: 二.把导出 ...

  7. C# event 和delegate的区别

    其实说实话 event和delegate 并没有什么特别大的区别,event其实就是特殊化的delegate 1.调用上event只能+=和-=,这样做的意义是为了防止,其余的方法覆盖,但是deleg ...

  8. 互联网安全的必要性:CSDN用户信息泄露案告破

    本报讯 昨天,记者从北京警方获悉,历时40多天的侦查,轰动互联网的“CSDN网站用户信息泄露案”告破,涉案嫌疑人已被刑拘.由于保密措施不力,北京警方还向CSDN网站开出我国落实信息安全等级保护制度以来 ...

  9. Codeforces Round #283 (Div. 2) A. Minimum Difficulty【一个数组定义困难值是两个相邻元素之间差的最大值。 给一个数组,可以去掉任意一个元素,问剩余数列的困难值的最小值是多少】

    A. Minimum Difficulty time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  10. php rmdir使用递归函数删除非空目录的方法

    php rmdir()函数 rmdir ― 删除空目录 语法: bool rmdir ( string $dirname [, resource $context ] )尝试删除 dirname 所指 ...