PyTorch项目源码学习(3)——Module类初步学习

torch.nn.Module

Module类是用户使用torch来自定义网络模型的基础,Module的设计要求包括低耦合性,高模块化等等。一般来说,计算图上所有的子图都可以是Module的子类,包括卷积,激活函数,损失函数节点以及相邻节点组成的集合等等,注意这里的关键词是“节点”,Module族类在计算图中主要起到搭建结构的作用,而不涉及运算逻辑的具体实现。

要注意的是,Module类对象的children所指向的其他Module类对象,并不等同于计算图中的子节点。如果我们展开Module网络,得到的一般是树形结构而非DAG,Module网络需要经过其他工作才能转化为计算图。

源代码分析

成员分析

首先直接从前端入手,找到torch/nn/module目录,可以看到这个目录下主要存放Module及其子类的定义,如。我们首先找到module.py内Module的定义

阅读__init__ 函数,可以看到Module基类的主要私有成员,其中包括

指向本Module内带梯度的可学习参数的parameter
指向本Module内不需要学习的模型状态参数的buffer
其他临时参数
前向与反向过程的hook函数,这些函数在运行backward与forward时允许自定义其它额外工作
state_dict相关函数,state_dict保存了模型的状态,是模型写入磁盘与加载的主要方式
modules指向该模块内部的所有子模块

方法分析
结构相关
  • 子模块生成

首先从我们日常使用pytorch搭建网络的用法可以想到,应该先去__setattr__函数寻找建立子节点的入口。

下图折叠了几个分支,可以看到当我们运行self.c1 = Conv2d(…)时,将会进入1202行的分支内,并且判断新成员是否是Module类型,如果是则将其放入本对象的子模块字典内。

__setattr__ 内主要对Parameter,Module,特定name的Tensor(也就是buffer)等参数做特判,其他情况则调用object的属性设置流程。事实上,其他的类似方法(如getattr等)也是同样的流程。

  • 内部参数访问

对于存储于私有成员_module内的子模块,一般使用children方法进行调用

我们在外部所使用的xx.modules()方法,就是通过调用children方法实现的。

另外,nn.Module实现了许多对参数转化的方法,比如CPU(将内部参数转移到内存中),CUDA(将内部参数转移到显存中)以及type(将参数转化为指定类型),而这些是通过调用内部的_apply方法实现的

可以看到,_apply接受一个函数指针参数,并对所有的子模块递归地调用自己。然后对本Module内所有的Parameter与buffer应用该函数。

问题来了,既然每个节点都进行函数应用,那么如何避免对同一参数重复应用fn?这个问题的关键在于内部的Parameter到底是如何存储的。

印象里,我们在外部使用xx.parameters()时,得到的是xx模块的所有参数,看起来和上述代码里的_parameters并非直接取用的关系,我们可以看一下parameters()的实现

注意到默认参数recurse=True,相信大部分人已经明白原因了,我们继续看到named_parameters()

对_named_member方法传入了获取子模块_parameters字典键值对的匿名函数,继续看到_named_members()

可以看到具体流程是先递归或者不递归地获取该模块下的所有用户希望获得的东西(具体定义在第一个函数参数中),然后返回迭代器

这里1489行体现递归调用,原因是named_modules方法本身就是一个递归函数

在这里插入图片描述

事实上,named_parameters, named_buffers均是通过named_members进而调用named_modules方法实现的,_module成员体现网络结构的特殊性在这里可以窥见一二。另外可以看到,上述方法内都存在memo集合进行去重,确保不会返回相同的指针对象。

  • 简要流程图

在这里插入图片描述

参考文章

https://zhuanlan.zhihu.com/p/340453841

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/410665.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】管理用户

DCL-管理用户 查询用户 use mysql; select * from user;创建用户 create user 用户名主机名 identified by 密码;修改用户密码 alter user 用户名主机名 identidied with mysql_native_password by 新密码;删除用户 drop user 用户名主机名;创建用户test,只能够…

Demo: 实现PDF加水印以及自定义水印样式

实现PDF加水印以及自定义水印样式 <template><div><button click"previewHandle">预览</button><button click"downFileHandle">下载</button><el-input v-model"watermarkText" /><el-input v-mo…

blender 导入到 Marvelous Designer

1&#xff09; 将模型的所有部分合并为一个单独的mesh 2&#xff09; 先调整计量单位&#xff1a; 3&#xff09;等比缩放&#xff0c;身高调整到180cm左右 4&#xff09;应用当前scale 首先&#xff0c;选中你要修改的物体&#xff0c;然后按下Ctrl-A键&#xff0c;打开应用…

Ubuntu 在更新内核后 Virtual Box 不能为虚拟电脑打开一个新任务

前言 我也不知道啥时候自动给我更新了内核&#xff0c;重启电脑之后我的内核升级成6.5.0-14-generic&#xff0c;导致Virtual Box无法找到内核文件。 解决方法 方法1 sudo apt update sudo apt install linux-headers-generic build-essential dkms sudo apt remove virtua…

清华大学操作系统rCore实验-第零章-Lab环境搭建

清华大学操作系统实验—rCore环境搭建 零、前言一、VirtualBox二、Kali Linux三、C四、Rust五、QEMU 模拟器安装六、Hello,world测试 零、前言 一直想动手写一个操作系统&#xff0c;但是没有能力从零开始写&#xff0c;故跟着清华大学操作系统实验&#xff0c;完成这个目标&a…

C# 实现单线程异步互斥锁

文章目录 前言一、异步互斥锁的作用是什么&#xff1f;示例一、创建和销毁 二、如何实现&#xff1f;1、标识&#xff08;1&#xff09;标识是否锁住&#xff08;2&#xff09;加锁&#xff08;3&#xff09;解锁 2、异步通知&#xff08;1&#xff09;创建对象&#xff08;2&a…

CSS||Emmet语法

1、简介 ​ Emmet语法的前身是Zen coding,它使用缩写,来提高html/css的编写速度, Vscode内部已经集成该语法。 ​ 快速生成HTML结构语法 ​ 快速生成CSS样式语法 2、快速生成HTML结构语法 生成标签 直接输入标签名 按tab键即可 比如 div 然后tab 键&#xff0c; 就可以生成 <…

Python进阶知识:整理6 -> 正则表达式

1 基础匹配用法 # 演示Python中正则表达式re模块的3个基础匹配方法 import re # 1. match()方法 从头匹配 string "hello world" result re.match("hello", string) # 如果头部没有匹配成功就直接失败了,后面就不会继续匹配了 print(result) print(r…

Unreal Engine(UE5)中构建离线地图服务

1. 首先需要用到3个软件&#xff0c;Unreal Engine&#xff0c;gis office 和 bigemap离线服务器 Unreal Engine下载地址:点击前往下载页面 Gis office下载地址:点击前往下载页面 Bigemap离线服务器 下载地址: 点击前往下载页面 Unreal Engine用于数字孪生项目开发&#x…

redis7部署集群:包含主从模式、哨兵模式、Cluster集群模式等三种模式

前言&#xff1a; redis部署集群常见的一般有三种模式&#xff1a;主从模式&#xff0c;Sentinel&#xff08;哨兵模式&#xff09;&#xff0c;Redis Cluster&#xff08;高可用Cluster集群&#xff09;&#xff0c;根据不同的需求可自定义选择部署方式。 Redis 主从模式&…

Java_单元测试、反射

一、单元测试 1.1 单元测试快速入门 所谓单元测试&#xff0c;就是针对最小的功能单元&#xff0c;编写测试代码对其进行正确性测试。 我们想想&#xff0c;咱们之前是怎么进行测试的呢&#xff1f; 比如说我们写了一个学生管理系统&#xff0c;有添加学生、修改学生、删除…

OB SQL引擎和存储引擎

文章目录 一 SQL引擎1.1 双模共存1.2 基本操作1.3 查看SQL的执行计划 二 存储引擎2.1 传统数据库存在的问题2.2 LSM-Tree存储2.3 OceanBase转储和合并2.4 控制内存数据落盘2.5 LSMTree存储压缩 三 备份恢复3.1 物理备份系统架构3.2 物理恢复系统架构 一 SQL引擎 1.1 双模共存 …