pytroch nn.Module源码解析(1)
今天在写一个分类网络时,要使用nn.Sequential中的一个模块,因为nn.Sequential中模块都没有名字,我一时竟无从下笔。于是决定写这篇博客梳理pytorch的nn.Module类,看完这篇博客,你大概率可以学会:
- 提取nn.Sequential中任意一个模块
- 能初始化一个网络的所有权重,不管是随机初始化还是使用权重文件
- 对nn.Module类有个总体把握
1 __init__方法
我们先不看代码,自己小脑袋里想一想这个类应该有什么东西。既然这个类是和各种layer相关,里面一定存着各种layer,如卷积或者relu,肯定还会有layer对应的权重。没错,这些东西类里都有:
from ..backends.thnn import backend as thnn_backend
def __init__(self):
self._backend = thnn_backend
self._parameters = OrderedDict()
self._buffers = OrderedDict()
self._backward_hooks = OrderedDict()
self._forward_hooks = OrderedDict()
self._forward_pre_hooks = OrderedDict()
self._modules = OrderedDict()
self.training = True
其中_modules和_parameters就是存储这些的,那么剩下这些奇奇怪怪的属性是什么呢?第一个奇怪的东西就是这个_backend属性,他的值是thnn_backend,好像和torch的底层代码有关,有点麻烦啊!不用怕,这个属性我们只要大概了解它的意思就可以,对之后这个模块的使用没有任何影响。举个例子来帮助我们理解,想象说我们有maxpooling层,pytorch底层会用cudnn实现,也会用cunn实现,pytorch在前向传播时会自动选择一个速度最快的实现,这里thnn_backend就是指定我们前向传播时用thnn这种实现方式。更多过于backend的直觉理解可以参考这个thread。
第二个奇怪的东西就是_buffer属性,如果我说这个buffer存储的也是网络参数,你会感觉到更加迷惑吗?一个提示:batch norm的参数。(花一分钟想一想。)batch norm中除了有参数$ alpha $和$ beta $外,还有running_mean和running_var,这些在整个学习过程中也需要存储起来但是不需要学习的参数我们就把它们存储到_buffer中。
第三个奇怪的东西就是3个钩子,这三个钩子具体的实现我可能很后面才会讲,不过为了一些好奇宝宝,如果我说forward_hook的功能是在module完成前向传播时做一些事,你能推断出其他两个钩子的功能吗?(答案)
2 children方法和modules方法
children方法和modules方法的作用是很类似的,我们先看一下children方法的代码。
def named_children(self):
memo = set()
for name, module in self._modules.items():
if module is not None and module not in memo:
memo.add(module)
yield name, module
def children(self):
for name, module in self.named_children():
yield module
我们看完代码发现children方法的作用就是把_modules遍历一遍,我们来看一下具体例子(你也可以自己在命令行中把这两个命令输入进去,尽量不要复制粘贴):
>>>model=nn.Sequential(nn.Linear(3,1), \
nn.Sequential(nn.BatchNorm2d(1), \
nn.Linear(1,3)))
>>> for m in model.children():
... print(m)
Linear(in_features=3, out_features=1, bias=True)
Sequential(
(0): BatchNorm2d(1, eps=1e-05, momentum=0.1, affine=True)
(1): Linear(in_features=1, out_features=3, bias=True)
)
如果我们还要把更里层的modules提取出来,我们就需要用到modules方法:
def named_modules(self, memo=None, prefix=''):
if memo is None:
memo = set()
if self not in memo:
memo.add(self) yield prefix, self for name, module in self._modules.items(): if module is None: continue submodule_prefix = prefix + ('.' if prefix else '') + name for m in module.named_modules(memo, submodule_prefix): yield mdef modules(self):
for name, module in self.named_modules():
yeild module
>>> for m in model.modules():
... print(m)
Sequential(
(0): Linear(in_features=3, out_features=1, bias=True)
(1): Sequential(
(0): BatchNorm2d(1, eps=1e-05, momentum=0.1, affine=True)
(1): Linear(in_features=1, out_features=3, bias=True)
)
)
Linear(in_features=3, out_features=1, bias=True)
Sequential(
(0): BatchNorm2d(1, eps=1e-05, momentum=0.1, affine=True)
(1): Linear(in_features=1, out_features=3, bias=True)
)
BatchNorm2d(1, eps=1e-05, momentum=0.1, affine=True)
Linear(in_features=1, out_features=3, bias=True)
了解了这两个方法你应该可以完成我们的第一个目标:提取nn.Sequential的任一个模块。在下一节中我们会完成我们的第二个目标,初始化权重。在结束之前给大家个小问题:有时候你只需要底层的module,而不需要module的子类,如nn.Sequential,那么怎么去除呢?
机器学习小贴士:支持向量机的意思就是我们最后选择的模型只与支持向量有关。
最后编辑于2018-10-1019:39:53 有什么错误请不吝赐教
pytroch nn.Module源码解析(1)的更多相关文章
- Cognitive Graph for Multi-Hop Reading Comprehension at Scale(ACL2019) 阅读笔记与源码解析
论文地址为:Cognitive Graph for Multi-Hop Reading Comprehension at Scale github地址:CogQA 背景 假设你手边有一个维基百科的搜索 ...
- [源码解析] 深度学习流水线并行Gpipe(1)---流水线基本实现
[源码解析] 深度学习流水线并行Gpipe(1)---流水线基本实现 目录 [源码解析] 深度学习流水线并行Gpipe(1)---流水线基本实现 0x00 摘要 0x01 概述 1.1 什么是GPip ...
- [源码解析] 深度学习流水线并行GPipe (2) ----- 梯度累积
[源码解析] 深度学习流水线并行GPipe (2) ----- 梯度累积 目录 [源码解析] 深度学习流水线并行GPipe (2) ----- 梯度累积 0x00 摘要 0x01 概述 1.1 前文回 ...
- [源码解析] 深度学习流水线并行之PopeDream(1)--- Profile阶段
[源码解析] 深度学习流水线并行之PopeDream(1)--- Profile阶段 目录 [源码解析] 深度学习流水线并行之PopeDream(1)--- Profile阶段 0x00 摘要 0x0 ...
- [源码解析] 深度学习流水线并行 PipeDream(3)--- 转换模型
[源码解析] 深度学习流水线并行 PipeDream(3)--- 转换模型 目录 [源码解析] 深度学习流水线并行 PipeDream(3)--- 转换模型 0x00 摘要 0x01 前言 1.1 改 ...
- [源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎
[源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎 目录 [源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎 0x00 摘要 0x01 前言 1.1 ...
- [源码解析] 深度学习分布式训练框架 horovod (21) --- 之如何恢复训练
[源码解析] 深度学习分布式训练框架 horovod (21) --- 之如何恢复训练 目录 [源码解析] 深度学习分布式训练框架 horovod (21) --- 之如何恢复训练 0x00 摘要 0 ...
- [源码解析] PyTorch 流水线并行实现 (1)--基础知识
[源码解析] PyTorch 流水线并行实现 (1)--基础知识 目录 [源码解析] PyTorch 流水线并行实现 (1)--基础知识 0x00 摘要 0x01 历史 1.1 GPipe 1.2 t ...
- [源码解析] PyTorch 流水线并行实现 (2)--如何划分模型
[源码解析] PyTorch 流水线并行实现 (2)--如何划分模型 目录 [源码解析] PyTorch 流水线并行实现 (2)--如何划分模型 0x00 摘要 0x01 问题 0x01 自动平衡 1 ...
随机推荐
- 伯努利数学习笔记&&Luogu P3711 仓鼠的数学题
新科技 Luogu P3711 题意 设$ S_{k,n}$表示$ \displaystyle\sum_{i=0}^n i^k$ 求多项式$\displaystyle\sum_{k=0}^n S_{k ...
- KML,SHP TAB互转,GDAL
最近在接触地图数据转换的东西,从硬件kml的数据转换其他的格式,因为从没做过着东西, 先去了解kml文件格式 http://baike.baidu.com/view/400307.htm?fr=ala ...
- css21规范学习
https://www.w3.org/TR/CSS22 1. An asterisk (*) indicates that the preceding type, word, or group occ ...
- Ubuntu更新Python3及pip3
https://blog.csdn.net/good_tang/article/details/85001211 根据这篇文章的作者给出的方法进行的操作,但是其中出了两个问题: 我在操作之后重开bas ...
- static关键字特点
目录 static关键字特点 静态代码块 static修饰与非static修饰的区别 static关键字特点 随着类的加载而加载 static修饰的变量和方法都会放在方法区中静态区,是属于类的. 静态 ...
- java学习笔记--从c/c++到java转变
final修饰符1)final变量final表示“最后的,最终的”含义,变量一旦赋值后,不能被重新赋值.被final修饰的实例变量必须显示指定初始值.final修饰符通常和static修饰符一起来创建 ...
- 【easy】107. Binary Tree Level Order Traversal II 按层输出二叉树
按层输出二叉树,广度优先. 3 / \ 9 20 / \ 15 7 [ [15,7], [9,20], [3] ] /** * Definition for a binary tree node. * ...
- JAVA第三次实训作业
---恢复内容开始--- 1. 编写“学生”类及其测试类. “学生”类: 类名:Student 属性:姓名.性别.年龄.学号.5门课程的成绩 方法1:在控制台输出各个属性的值. 方法2:计算平均成绩 ...
- 五 Zabbix全网监控
监控的作用 我们的职责 1.保障企业数据的安全可靠. 2.为客户提供7*24小时服务. 3.不断提升用户的体验.在关键时刻,提前提醒我们服务器要出问题了当出问题之后,可以便于找到问题的根源 ...
- zigbee 信道
以zigbee nxp5169 信道是:11-26 15d0f1-170923 15 ----- 信道 d0f1--- 是zigbee 物理地址 170923---时间2017年9月 ...