Pytorch神经网络的模型架构(nn.Module和nn.Sequential的用法)

一、层和块

       在构造自定义块之前,我们先回顾一下多层感知机的代码。下面的代码生成一个网络,其中包含一个具有256个单元和ReLU激活函数的全连接隐藏层,然后是一个具有10个隐藏单元且不带激活函数的全连接输出层。

import torch
from torch import nn
from torch.nn import functional as Fnet = nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))X = torch.rand(2, 20)
net(X)
tensor([[ 0.0748, -0.1284,  0.0661,  0.1824,  0.1819, -0.0896, -0.0444,  0.0611,-0.1083, -0.2545],[ 0.0015, -0.1136,  0.0300,  0.2422,  0.1924, -0.1676, -0.1643,  0.0208,-0.1123, -0.1084]], grad_fn=<AddmmBackward0>)

       `nn.Sequential`定义了一种特殊的`Module`,即在PyTorch中表示一个块的类,它维护了一个由`Module`组成的有序列表。注意,两个全连接层都是`Linear`类的实例,`Linear`类本身就是`Module`的子类。另外,到目前为止,我们一直在通过`net(X)`调用我们的模型来获得模型的输出。这实际上是`net.__call__(X)`的简写。这个前向传播函数非常简单:它将列表中的每个块连接在一起,将每个块的输出作为下一个块的输入。

二、自定义块

       Pytorch中任何一个层或者一个神经网络基本都是nn.Module的子类。下面是一个自定义的MLP类,功能和前面代码相同。

class MLP(nn.Module):# 用模型参数声明层。这里,我们声明两个全连接的层def __init__(self):# 调用MLP的父类Module的构造函数来执行必要的初始化。# 这样,在类实例化时也可以指定其他函数参数,例如模型参数paramssuper().__init__()self.hidden = nn.Linear(20, 256)  # 隐藏层self.out = nn.Linear(256, 10)  # 输出层# 定义模型的前向传播,即如何根据输入X返回所需的模型输出def forward(self, X):# 注意,这里我们使用ReLU的函数版本,其在nn.functional模块中定义。return self.out(F.relu(self.hidden(X)))

       所有的Module有两个重要的函数,一个是init()函数,在里面定义需要哪些类和参数,另外一个是forward()函数,定义了模型的前向传播。

       实例化多层感知机的层,然后在每次调用前向传播函数时调用这些层。

net = MLP()
net(X)
tensor([[ 0.0617, -0.0381,  0.0605, -0.2711, -0.0481, -0.1107,  0.2265, -0.0549,0.2573,  0.0887],[-0.0170, -0.0350,  0.1438, -0.2079, -0.0148, -0.0230,  0.0590,  0.0136,0.3161,  0.0014]], grad_fn=<AddmmBackward0>)

三、顺序块

       现在我们可以更仔细地看看`Sequential`类是如何工作的,回想一下`Sequential`的设计是为了把其他模块串起来。为了构建我们自己的简化的`MySequential`,我们只需要定义两个关键函数:

  1. 一种将块逐个追加到列表中的函数;
  2. 一种前向传播函数,用于将输入按追加块的顺序传递给块组成的“链条”。

       下面的`MySequential`类提供了与默认`Sequential`类相同的功能。

class MySequential(nn.Module):def __init__(self, *args):  # *args: list of input argumentssuper().__init__()for idx, module in enumerate(args):# 这里,module是Module子类的一个实例。我们把它保存在'Module'类的成员# 变量_modules中。_module的类型是OrderedDict(有序字典)self._modules[str(idx)] = moduledef forward(self, X):# OrderedDict保证了按照成员添加的顺序遍历它们for block in self._modules.values():X = block(X)return X

       当`MySequential`的前向传播函数被调用时,每个添加的块都按照它们被添加的顺序执行。现在可以使用我们的`MySequential`类重新实现多层感知机。

net = MySequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))
net(X)
tensor([[ 0.0425,  0.2652, -0.1381,  0.0156, -0.1683,  0.0906, -0.2825,  0.0234,0.0289,  0.0594],[ 0.0372,  0.2065, -0.1196,  0.0681, -0.1791,  0.1555, -0.4214,  0.1164,-0.0223,  0.0265]], grad_fn=<AddmmBackward0>)

四、在前向传播函数中执行代码

       下面这段代码相比于nn.Sequential更加灵活,能够灵活定义前向计算:

class FixedHiddenMLP(nn.Module):def __init__(self):super().__init__()# 不计算梯度的随机权重参数。因此其在训练期间保持不变self.rand_weight = torch.rand((20, 20), requires_grad=False)self.linear = nn.Linear(20, 20)def forward(self, X):X = self.linear(X)# 使用创建的常量参数以及relu和mm函数X = F.relu(torch.mm(X, self.rand_weight) + 1)# 复用全连接层。这相当于两个全连接层共享参数X = self.linear(X)# 控制流while X.abs().sum() > 1:X /= 2return X.sum()net = FixedHiddenMLP()
net(X)
tensor(0.0402, grad_fn=<SumBackward0>)

五、嵌套使用

       我们可以混合搭配各种组合块的方法。在下面的例子中,我们以一些想到的方法嵌套块。

class NestMLP(nn.Module):def __init__(self):super().__init__()self.net = nn.Sequential(nn.Linear(20, 64), nn.ReLU(),nn.Linear(64, 32), nn.ReLU())self.linear = nn.Linear(32, 16)def forward(self, X):return self.linear(self.net(X))chimera = nn.Sequential(NestMLP(), nn.Linear(16, 20), FixedHiddenMLP())
chimera(X)
tensor(-0.0394, grad_fn=<SumBackward0>)

六、总结

  • 一个块可以由许多层组成;一个块可以由许多块组成。
  • 块可以包含代码。
  • 块负责大量的内部处理,包括参数初始化和反向传播。
  • 层和块的顺序连接由`Sequential`块处理。

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

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

相关文章

Linux 基本语句_16_Udp网络聊天室

代码&#xff1a; 服务端代码&#xff1a; #include <stdio.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdlib.h> #include <unistd.h> #include <string…

中小型企业网络综合实战案例分享

实验背景 某公司总部在厦门&#xff0c;北京、上海都有分部&#xff0c;网络结构如图所示&#xff1a; 一、网络连接描述&#xff1a; 厦门总部&#xff1a;内部网络使用SW1、SW2、SW3三台交换机&#xff0c;SW1为作为核心交换机&#xff0c;SW2、SW3作为接入层交换机&#x…

go语言实现文件夹上传前后端代码案例

go语言实现文件夹上传前后端代码案例 前端用于上传的测试界面 如果上传的文件夹有子文件要遍历子文件夹创建出子文件夹再进行拷贝需要获取文件名和对应的路径&#xff0c;将文件的相对路径和文件对象添加到FormData中这几行代码很关键 for (let i 0; i < files.length; i…

PDF控件Spire.PDF for .NET【转换】演示:将多个图像转换为单个 PDF

如果您想要将多个图像合并为一个文件以便于分发或存储&#xff0c;将它们转换为单个 PDF 文档是一个很好的解决方案。这一过程不仅节省空间&#xff0c;还确保所有图像都保存在一个文件中&#xff0c;方便共享或传输。在本文中&#xff0c;您将学习如何使用Spire.PDF for .NET …

为什么选择计算机?

还记得当初自己为什么选择计算机&#xff1f; 当然记得。高一下学期(2017年)听数学老师说着大数据&#xff0c;听着是那么牛&#xff0c;那么神奇&#xff0c;还说着目前社会上也缺少这样的人&#xff0c;然后那时候就有个这样的梦&#xff0c;想去学&#xff0c;想去当那少数…

36 动态规划之编辑距离

问题描述&#xff1a;给你两个单词word1和word2&#xff0c;请你计算出将word1转换为word2所需要的最少操作数。插入一个字符删除一个字符替换一个字符&#xff1b; 暴力穷举法&#xff1a;将短的那一个串作为子串(长度s)&#xff0c;寻找在母串(长串长度p)共同字符最多的情况…

Electron V28主进程与渲染进程互相通信总结

本文示例采用ElectronVue3TS编写&#xff0c;请读者理顺思路&#xff0c;自行带入自己的项目。 注&#xff1a; 读本文前请先搞懂什么是主进程&#xff0c;什么是渲染进程。 在Electron中有着ipcMain和ipcRenderer、contextBridge模块&#xff0c;以及创建窗口对象上的webCont…

-bash: docker-compose: 未找到命令

-bash: docker-compose: 未找到命令 我在使用Docker搭建Nacos容器时遇到了这个问题&#xff1a;是没有安装 docker-compose工具 。 docker-compose的用处主要体现在以下几个方面&#xff1a; 快速搭建开发环境&#xff1a;使用docker-compose可以快速搭建起开发环境&#xff0…

一分钟轻松制作AI数字人播报视频

随着人工智能的快速发展&#xff0c;AI数字人播报成为了媒体和信息传播领域的一项创新技术。AI数字人播报是利用人工智能技术创建的一系列短视频&#xff0c;以新闻主播为中心&#xff0c;展示各种场景和情境能够以短视频的形式进行新闻的报道。这种创新的内容形式在社交媒体和…

Java刷题篇——单链表练习题上

206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 1. 题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例1 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例2 输入&#xff1a;head [1,2] 输出&…

<软考高项备考>《论文专题 - 14 绩效域(四)》

8 交付绩效域 交付绩效域涉及与交付项目相关的活动和职能。在项目整个生命周期过程中&#xff0c; 有效执行本绩效域可以实现预期目标&#xff0c;主要包含&#xff1a; ①项目有助于实现业务目标和战略&#xff1b; ②项目实现了预期成果&#xff1b; ③在预定时间内实现了项…

Spring Boot 3 + Vue 3 整合 WebSocket (STOMP协议) 实现广播和点对点实时消息

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

PostgreSQL基础

一、数据库操作命令 创建数据库 CREATE DATABASE xxxxxxx; 删除数据库 drop databse xxxxx; 查看所有数据库 \l 切换数据库 \c xxx 二、模式的更改 a)重命名&#xff1a;alter schema 旧名字 to 新名字; b)修改模式的归属用户&#xff1a;alter schema 模式名 to 新用户; 模式…

CDH安装出现Cannot open channel to X at election address Connection refused

CDH安装出现Cannot open channel to X at election address Connection refused 在刚刚启动cdh的时候要是出现以上的问题或者 org.apache.zookeeper.server.quorum.QuorumCnxManager: Cannot open channel to 3 at election address srv252/10.1.50.252:4181 java.net.Connec…

06组团队项目-Beta冲刺-2/3

github仓库&#xff1a;https://github.com/orgs/oucdehaze/repositories 冲刺概况汇报 前端 上周冲刺中完成的任务及遇到的问题 这一周我们小组中负责前端部分的同学继续完善了web网页的界面。在上一周的基础上对字体颜色和字体内容进行了修改&#xff0c;使得网站的专业性…

高可用接入层技术演化及集群概述

集群概述 集群的介绍及优势 集群&#xff1a;将多台服务器通过硬件或软件的方式组合起来&#xff0c;完成特定的任务&#xff0c;而这些服务器对外表现为一个整体。集群的优势 高可靠性&#xff1a;利用集群管理软件&#xff0c;当主服务器故障时&#xff0c;备份服务器能够自…

2023年国赛高教杯数学建模D题圈养湖羊的空间利用率解题全过程文档及程序

2023年国赛高教杯数学建模 D题 圈养湖羊的空间利用率 原题再现 规模化的圈养养殖场通常根据牲畜的性别和生长阶段分群饲养&#xff0c;适应不同种类、不同阶段的牲畜对空间的不同要求&#xff0c;以保障牲畜安全和健康&#xff1b;与此同时&#xff0c;也要尽量减少空间闲置所…

【SpringBoot实战】实现用户名密码登录

【SpringBoot实战】实现用户名密码登录 在Java项目中&#xff0c;实现用户名密码登录是最基本的功能。尽管实现起来不难&#xff0c;但也有些细节问题&#xff0c;故写下此篇博客作为记录。 1.创建用户表 CREATE TABLE ad_user (id int unsigned NOT NULL COMMENT 主键,name…

代码随想录算法训练营第五十五天 _ 动态规划_392. 判断子序列、115.不同的子序列。

学习目标&#xff1a; 动态规划五部曲&#xff1a; ① 确定dp[i]的含义 ② 求递推公式 ③ dp数组如何初始化 ④ 确定遍历顺序 ⑤ 打印递归数组 ---- 调试 引用自代码随想录&#xff01; 60天训练营打卡计划&#xff01; 学习内容&#xff1a; 392. 判断子序列 这个题目就是 …

消息队列kafka详解:Kafka原理分析总结

一、概述 Kakfa起初是由LinkedIn公司开发的一个分布式的消息系统&#xff0c;后成为Apache的一部分&#xff0c;它使用Scala编写&#xff0c;以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Apache Storm、Spark等都支持与Kafka集成。 Kaf…