第21周周报 总结学习了层和块内容中的顺序块和自定义块层和块之前首次介绍神经网络时我们关注的是具有单一输出的线性模型。在这里整个模型只有一个输出。注意单个神经网络1接受一些输入2生成相应的标量输出3具有一组相关参数更新这些参数可以优化某目标函数。然后当考虑具有多个输出的网络时我们利用矢量化算法来描述整层神经元。像单个神经元一样层1接受一组输入2生成相应的输出3由一组可调整参数描述。当我们使用softmax回归时一个单层本身就是模型。然而即使我们随后引入了多层感知机我们仍然可以认为该模型保留了上面所说的基本架构。对于多层感知机而言整个模型及其组成层都是这种架构。整个模型接受原始输入特征生成输出预测并包含一些参数所有组成层的参数集合。同样每个单独的层接收输入由前一层提供生成输出到下一层的输入并且具有一组可调参数这些参数根据从下一层反向传播的信号进行更新。事实证明研究讨论“比单个层大”但“比整个模型小”的组件更有价值。例如在计算机视觉中广泛流行的ResNet‐152架构就有数百层这些层是由层groupsoflayers的重复模式组成。目前ResNet架构仍然是许多视觉任务的首选架构。在其他的领域如自然语言处理和语音层组以各种重复模式排列的类似架构现在也是普遍存在。为了实现这些复杂的网络我们引入了神经网络块的概念。块可以描述单个层、由多个层组成的组件或整个模型本身。使用块进行抽象的一个好处是可以将一些块组合成更大的组件这一过程通常是递归的如图1.1所示。通过定义代码来按需生成任意复杂度的块我们可以通过简洁的代码实现复杂的神经网络。图1.1多个层被组合成块形成更大的模型从编程的角度来看块由类class表示。它的任何子类都必须定义一个将其输入转换为输出的前向传播函数并且必须存储任何必需的参数。注意有些块不需要任何参数。最后为了计算梯度块必须具有反向传播函数。在定义我们自己的块时由于自动微分在2.5节中引入提供了一些后端实现我们只需要考虑前向传播函数和必需的参数。下面的代码生成一个网络其中包含一个具有256个单元和ReLU激活函数的全连接隐藏层然后是一个具有10个隐藏单元且不带激活函数的全连接输出层。import torch from torch import nn from torch.nn import functional as F net nn.Sequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10)) X torch.rand(2, 20) net(X)tensor([[0.0343,0.0264,0.2505,-0.0243,0.0945,0.0012,-0.0141,0.0666,-0.0547,-0.0667],[0.0772,-0.0274,0.2638,-0.0191,0.0394,-0.0324,0.0102,0.0707,-0.1481,-0.1031]], grad_fnAddmmBackward0)在这个例子中我们通过实例化nn.Sequential来构建我们的模型层的执行顺序是作为参数传递的。简而言之nn.Sequential定义了一种特殊的Module即在PyTorch中表示一个块的类它维护了一个由Module组成的有序列表。注意两个全连接层都是Linear类的实例Linear类本身就是Module的子类。另外到目前为止我们一直在通过net(X)调用我们的模型来获得模型的输出。这实际上是net.__call__(X)的简写。这个前向传播函数非常简单它将列表中的每个块连接在一起将每个块的输出作为下一个块的输入。自定义块要想直观地了解块是如何工作的最简单的方法就是自己实现一个。在实现我们自定义块之前我们简要总结一下每个块必须提供的基本功能。1.将输入数据作为其前向传播函数的参数。2.通过前向传播函数来生成输出。请注意输出的形状可能与输入的形状不同。例如我们上面模型中的第一个全连接的层接收一个20维的输入但是返回一个维度为256的输出。3.计算其输出关于输入的梯度可通过其反向传播函数进行访问。通常这是自动发生的。4.存储和访问前向传播计算所需的参数。5.根据需要初始化模型参数。在下面的代码片段中我们从零开始编写一个块。它包含一个多层感知机其具有256个隐藏单元的隐藏层和一个10维输出层。注意下面的MLP类继承了表示块的类。我们的实现只需要提供我们自己的构造函数Python中的__init__函数和前向传播函数。class MLP(nn.Module): # 用模型参数声明层。这里我们声明两个全连接的层 def __init__(self): # 调用MLP的父类Module的构造函数来执行必要的初始化。 # 这样在类实例化时也可以指定其他函数参数例如模型参数params稍后将介绍 super().__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)))我们首先看一下前向传播函数它以X作为输入计算带有激活函数的隐藏表示并输出其未规范化的输出值。在这个MLP实现中两个层都是实例变量。要了解这为什么是合理的可以想象实例化两个多层感知机net1和net2并根据不同的数据对它们进行训练。当然我们希望它们学到两种不同的模型。接着我们实例化多层感知机的层然后在每次调用前向传播函数时调用这些层。注意一些关键细节首先我们定制的__init__函数通过super().__init__()调用父类的__init__函数省去了重复编写模版代码的痛苦。然后我们实例化两个全连接层分别为self.hidden和self.out。注意除非我们实现一个新的运算符否则我们不必担心反向传播函数或参数初始化系统将自动生成这些。net MLP() net(X)tensor([[0.0669,0.2202,-0.0912,-0.0064,0.1474,-0.0577,-0.3006,0.1256,-0.0280,0.4040],[0.0545,0.2591,-0.0297,0.1141,0.1887,0.0094,-0.2686,0.0732,-0.0135,0.3865]], grad_fnAddmmBackward0)块的一个主要优点是它的多功能性。我们可以子类化块以创建层如全连接层的类、整个模型如上面的MLP类或具有中等复杂度的各种组件。我们在接下来的章节中充分利用了这种多功能性比如在处理卷积神经网络时。顺序块现在我们可以更仔细地看看Sequential类是如何工作的回想一下Sequential的设计是为了把其他模块串起来。为了构建我们自己的简化的MySequential我们只需要定义两个关键函数1.一种将块逐个追加到列表中的函数2.一种前向传播函数用于将输入按追加块的顺序传递给块组成的“链条”。下面的MySequential类提供了与默认Sequential类相同的功能。class MySequential(nn.Module): def __init__(self, *args): super().__init__() for idx, module in enumerate(args): # 这里module是Module子类的一个实例。我们把它保存在Module类的成员 # 变量_modules中。_module的类型是OrderedDict self._modules[str(idx)] module def forward(self, X): # OrderedDict保证了按照成员添加的顺序遍历它们 for block in self._modules.values(): X block(X) return X__init__函数将每个模块逐个添加到有序字典_modules中。读者可能会好奇为什么每个Module都有一个_modules属性以及为什么我们使用它而不是自己定义一个Python列表简而言之_modules的主要优点是在模块的参数初始化过程中系统知道在_modules字典中查找需要初始化参数的子块。当MySequential的前向传播函数被调用时每个添加的块都按照它们被添加的顺序执行。现在可以使用我们的MySequential类重新实现多层感知机。net MySequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10)) net(X)tensor([[2.2759e-01,-4.7003e-02,4.2846e-01,-1.2546e-01,1.5296e-01,1.8972e-01,9.7048e-02,4.5479e-04,-3.7986e-02,6.4842e-02],[2.7825e-01,-9.7517e-02,4.8541e-01,-2.4519e-01,-8.4580e-02,2.8538e-01,3.6861e-02,2.9411e-02,-1.0612e-01,1.2620e-01]],grad_fnAddmmBackward0)

相关新闻

最新新闻

通义千问3.8震撼发布:2.4万亿参数国产AI领跑全球

通义千问3.8震撼发布:2.4万亿参数国产AI领跑全球

前言 2026年7月19日,在上海世界人工智能大会(WAIC)上,阿里巴巴通义千问团队正式发布了其最新一代旗舰大模型——Qwen3.8-Max预览版。这款拥有2.4万亿总参数的巨型AI模型,不仅是千问系列首个突破万亿参数门槛的产品&…

2026/7/26 7:22:09
CC253x无线数据链路层:RXFIFO、FCS校验与自动应答机制详解

CC253x无线数据链路层:RXFIFO、FCS校验与自动应答机制详解

1. 项目概述:深入CC253x无线数据链路层在嵌入式无线开发,尤其是Zigbee、6LoWPAN这类低功耗、高可靠性的物联网应用中,如何高效、可靠地处理空中传来的数据帧,是决定整个系统性能与稳定性的基石。很多开发者在使用TI的CC253x系列芯…

2026/7/26 7:22:08
Windows跨进程通信:RegisterWindowMessage机制详解

Windows跨进程通信:RegisterWindowMessage机制详解

1. Windows进程通信基础与RegisterWindowMessage机制在Windows多进程环境中,不同应用程序间的数据交换一直是开发难点。传统的SendMessage/PostMessage API虽然可以实现窗口间通信,但存在一个关键限制:消息标识符(Message ID&…

2026/7/26 7:22:08
二维码支付安全风险与风控系统技术实现详解

二维码支付安全风险与风控系统技术实现详解

最近刷短视频时,你是不是也经常看到这样的剧情:一个水管维修工上门服务,修完后坚决不收现金,只接受二维码付款。看似平常的生活场景,背后却暗藏玄机——这可能是新型洗钱犯罪的冰山一角。作为一名技术博主,…

2026/7/26 7:22:08
RedHat9.6添加硬盘,划分磁盘分区,创建文件系统,挂载分区

RedHat9.6添加硬盘,划分磁盘分区,创建文件系统,挂载分区

磁盘操作 添加三块硬盘: 第一块硬盘,虚拟磁盘类型选择SCSI。大小选择5G。按mbr格式分区。分两个主分区,大小分别为2G和1G。第一个主分区创建ext2类型的文件系统。第一个主分区挂载到/guazai1目录,并在其中存入1.txt的文件。其文件内容是this …

2026/7/26 7:22:08
AI业务信息系统:企业数字化转型的四大核心技术

AI业务信息系统:企业数字化转型的四大核心技术

1. AI业务信息系统:企业数字化转型的核心引擎十年前我第一次接触企业业务系统时,看到财务部同事对着Excel表格手动录入上千条发票信息,销售团队用纸质表格跟踪客户状态,这种低效场景至今记忆犹新。如今AI业务信息系统的出现&#…

2026/7/26 7:17:08

月新闻