从0开始深度学习(18)——层和块

news2024/10/28 4:11:34

1 层和块

1.1层

层是神经网络的基本组成单位。每一层由多个神经元(或单元)组成,这些神经元在前一层的输出上执行某种计算,并将结果传递给下一层。根据功能,层可以分为以下几种类型:

  • 输入层(Input Layer):接收外部数据并将其传递给网络。
  • 隐藏层(Hidden Layer):位于输入层和输出层之间,执行特征提取和表示学习。深度学习模型通常包含多个隐藏层。
  • 输出层(Output Layer):生成最终的输出,例如分类结果或预测值。

1.2 块

块通常指的是一组层的组合,具有特定功能或结构,能够执行某种复杂的操作或特征提取。块的设计目的是为了重用和组织模型的部分。例如:

  • 卷积块(Convolutional Block):通常包括卷积层、激活函数和归一化层的组合。
  • 残差块(Residual Block):包含跳跃连接(skip connections),可以帮助模型训练更深的网络。
  • 循环块(Recurrent Block):包含一个或多个循环层(如LSTM或GRU),用于处理序列数据。

1.3 以多层感知机为例

在这里插入图片描述
多个层组合成块,然后块又与块组合形成更大的模型。

从编程的角度来看,块由类(class)表示。 它的任何子类都必须定义一个将其输入转换为输出的前向传播函数, 并且必须存储任何必需的参数。 注意,有些块不需要任何参数。 最后,为了计算梯度,块必须具有反向传播函数。

2 自定义块

在实现我们自定义块之前,我们简要总结一下每个块必须提供的基本功能:

  1. 将输入数据作为其前向传播函数的参数。
  2. 通过前向传播函数来生成输出。请注意,输出的形状可能与输入的形状不同。
  3. 计算其输出关于输入的梯度,可通过其反向传播函数进行访问。通常这是自动发生的。
  4. 存储和访问前向传播计算所需的参数。
  5. 根据需要初始化模型参数。

在下面的代码片段中,我们从零开始编写一个块。 它包含一个多层感知机,其具有256个隐藏单元的隐藏层和一个10维输出层。

自定义的MLP 类继承自 nn.Module,这是 PyTorch 中所有神经网络模块的基类,通过继承 nn.Module,可以利用 PyTorch 提供的很多功能,如参数管理和自动求导。

import torch
from torch import nn
from torch.nn import functional as F

class MLP(nn.Module):
    def __init__(self):# 类的构造函数,用于初始化网络结构。
        super().__init__() # 调用父类的构造函数,确保父类 nn.Module 得到正确初始化。
        self.hidden=nn.Linear(20,256)
        self.out=nn.Linear(256,10)

    def forward(self,x):
        a=self.hidden(x)
        re=self.out(F.relu(a))
        return re

整段代码实现了一个基本的多层感知机模型,具有以下特点:

  1. 输入层接受 20 维特征。
  2. 隐藏层由一个线性层(输出 256 维)和 ReLU 激活函数组成。
  3. 输出层由另一个线性层(输出 10 维)组成。

运行结果:

X = torch.rand(2, 20)
net = MLP()
net(X)

在这里插入图片描述

2 顺序块

我们曾在从0开始深度学习(13)——多层感知机的简洁实现中使用过Sequential类
在这里插入图片描述
接下来我们将构建自己的顺序块,为了构建自己的简化的MySequential, 我们只需要定义两个关键函数:

  1. 一种将块逐个追加到列表中的函数。
  2. 一种前向传播函数,用于将输入按追加块的顺序传递给块组成的“链条”。
class MySequential(nn.Module):
    def __init__(self, *args):# *args 表示可以接受任意数量的参数,这些参数通常是 nn.Module 的实例
        super().__init__()
        for idx, module in enumerate(args):# 通过 enumerate 函数遍历所有传入的模块,并为每个模块分配一个索引 idx。
            #将每个模块以字符串形式的索引存储在 _modules 字典中。
            #_modules 是 nn.Module 中定义的一个属性,用于存储子模块。
            #使用字符串索引可以确保按照添加的顺序进行存储。
            self._modules[str(idx)] = module

    def forward(self, X):
        # OrderedDict保证了按照成员添加的顺序遍历它们
        for block in self._modules.values():
            X = block(X)
        return X

运行结果:

net = MySequential(nn.Linear(20, 256), nn.ReLU(), nn.Linear(256, 10))
net(X)

在这里插入图片描述

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

需要更强的灵活性时,我们需要定义自己的块。 例如,我们可能希望在前向传播函数中执行Python的控制流。 此外,我们可能希望执行任意的数学运算, 而不是简单地依赖预定义的神经网络层。

例如,我们需要一个计算函数 f ( x , w ) = c ⋅ w ⊤ x f(\mathbf{x},\mathbf{w}) = c \cdot \mathbf{w}^\top \mathbf{x} f(x,w)=cwx的层,其中 x x x是输入, w w w是参数, c c c是某个在优化过程中没有更新的指定常量。因此我们实现了一个FixedHiddenMLP类,如下所示:

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)
        # 对 X 和 rand_weight 进行矩阵乘法。这里 rand_weight 是不计算梯度的随机权重。
        X = F.relu(torch.mm(X, self.rand_weight) + 1)
        # 这里再次将处理后的 X 传递给之前定义的线性层 self.linear,这表示这个全连接层的参数在两次调用中是相同的(共享参数)。
        X = self.linear(X)
        # 控制流
        while X.abs().sum() > 1:
            X /= 2
        return X.sum()

在这个FixedHiddenMLP模型中,我们实现一个隐藏层, 权重rand_weight在实例化时被随机初始化之后为常量。 这个权重不是一个模型参数,因此它永远不会被反向传播更新。 然后,神经网络将这个固定层的输出通过一个全连接层。

还展示了如何控制数据流:运行了一个while循环,在 L 1 L_{1} L1范数大于 1 1 1的条件下, 将输出向量除以 2 2 2,直到它满足条件为止。

最后展示一个进行了各种混搭的例子:

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)

即自定义了一个NestMLP类,里面有netlinear,其中net又是一个Sequential

最后还定义了一个chimera 网络,按照顺序包含了NestMLPLinear,FixedHiddenMLP三个网络

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

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

相关文章

《决策思维:人人必备的决策口袋书》

本书干货很多,十分值得一读。但受众不是一线员工与一线管理者,更多的倾向于管理者的管理者。一线员工读完的最大收获是可以理解老板的决策逻辑与思维方式,便于更好的去做执行。同时,还能帮助判断老板的决策是否正确,是…

【Android】view的基础知识

文章目录 View与ViewGroupView位置参数View的滑动1. scrollTo与scrollBy2. 属性动画ObjectAnimatorViewPropertyAnimator 3. LayoutParams(布局参数)layout方法offsetLeftAndRight View的弹性滑动1. Scroller 类2. 动画(ObjectAnimator&#…

SYN590RL 300MHz至450MHz ASK接收机芯片IC

一般描述 SYN590RL是赛诺克全新开发设计的一款宽电压范围,低功耗,高性能,无需外置AGC电容,灵敏度达到典型-110dBm,300MHz”450MHz 频率范围应用的单芯片ASK或OOK射频接收器。 SYN59ORL是一款典型的即插即用型单片高集成度无线接收器&…

Spring Boot实现的动态化酒店住宿管理系统

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理酒店客房管理系统的相关信息成为必然。开发…

pytorch的标签平滑介绍

什么是标签平滑(Label Smoothing)? 标签平滑(Label Smoothing)是一种正则化技术,旨在防止模型过度自信(即输出的概率分布过于“尖锐”)。在分类任务中,标准的目标标签是one-hot编码,也就是正确类别的概率为 1,其他类别的概率为 0。而标签平滑通过将正确类别的概率从…

绝了,这款播放器让发烧友疯狂种草,堪称音乐神器

作为音乐爱好者的不二之选,foobar2000凭借其卓越的音频处理能力,在Windows系统用户中树立了极高的声誉。这款轻量级播放器的设计理念是将极致的性能与个性化完美结合。用户可以根据自己的使用习惯,打造出独具特色的播放界面和操作流程。在音频…

【redis】初识非关系型数据库——redis

W...Y的主页 😊 代码仓库分享💕 初识 Redis Redis是⼀种基于键值对(key-value)的NoSQL数据库,与很多键值对数据库不同的是,Redis 中的值可以是由string(字符串)、hash&#xff0…

html 登入界面,用户注册界面相关的标签及案例

案例效果图 以上界面的完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</titl…

Python浪漫之画星星

效果图&#xff08;动态的哦&#xff01;&#xff09;&#xff1a; 完整代码&#xff08;上教程&#xff09;&#xff1a; import turtle import random import time # 导入time模块# 创建一个画布 screen turtle.Screen() screen.bgcolor("red")# 创建一个海龟&a…

【学术论文投稿】Windows11开发指南:打造卓越应用的必备攻略

【IEEE出版南方科技大学】第十一届电气工程与自动化国际会议&#xff08;IFEEA 2024)_艾思科蓝_学术一站式服务平台 更多学术会议论文投稿请看&#xff1a;https://ais.cn/u/nuyAF3 目录 引言 一、Windows11开发环境搭建 二、Windows11关键新特性 三、Windows11设计指南 …

Android 自定义 Dialog 实现列表 单选,多选,搜索

前言 在Android开发中&#xff0c;通过对话框让用户选择&#xff0c;筛选信息是很方便也很常见的操作。本文详细介绍了如何使用自定义 Dialog、RecyclerView 以及自定义搜索框 来实现选中状态和用户交互&#xff0c;文中大本分代码都有明确注释&#xff0c;主打一个简单明了&a…

springboot 同时上传文件和JSON对象

控制器代码 PostMapping("/upload") public ResponseEntity<String> handleFileUpload(RequestPart("file") MultipartFile file,RequestPart("user") User user) {// 处理文件和用户信息return ResponseEntity.ok("File and user i…

tomcat部署war包部署运行,IDEA一键运行启动tomacat服务,maven打包为war包并部署到tomecat

tomcat部署war包前端访问 在Java Web开发中&#xff0c;Tomcat是一个非常流行的开源Web服务器和Servlet容器。它实现了Java Servlet和JavaServer Pages (JSP) 技术&#xff0c;提供了一个纯Java的Web应用环境。本文将介绍如何在Tomcat中部署运行WAR包&#xff0c;让你的应用快…

SpringBoot实现mysql多数据源配置(Springboot+Mybatis)

最近在学习SpringBoot的一些知识&#xff0c;主要是参考了纯洁的微笑的一些博客作为练手&#xff0c;想着他已经把入门的教程写的很详细了,如果再简单的把他的教程拷贝到自己的简书&#xff0c;这是是赤裸裸的剽窃&#xff0c;很不地道&#xff0c;作为一个技术人员&#xff0c…

通过页面添加国际化数据,实现vue的国际化

element ui 写在前面1. 原有的vue的国际化处理1.1 语言文件1.2 lang的index.js1.3 入口文件导入1.3 应用 2. 通过页面添加国际化数据2.1 做法2.2 lang的index.js文件修改2.3 需要注意的点 总结写在最后 写在前面 需求&#xff1a;在系统的国际化管理页面添加国际化数据&#x…

机器视觉-相机、镜头、光源(总结)

目录 1、机器视觉光源概述 2、光源的作用 3、光谱 4、工业场景常见光源 4.1、白炽灯 4.2、卤素灯 4.3、 荧光灯 4.4、LED灯 4.5、激光灯 5、光源的基本性能 5.1、光通量 5.2、光效率 5.3、发光强度 5.4、光照度 5.5、均匀性 5.6、色温 5.7、显色性 6、基本光学…

嵌入式软开项目——电子手环开发——学习引导和资料网址

文末附所有资料下载链接 1、需要将该文件夹放置到英文路径下&#xff0c;否则无法运行 2、目录下总共四个文件夹 2.1 第一个文件夹“0、OV-Watch-main(原版)”&#xff0c;为开源代码的原版资料 2.2第二个文件夹” OV-Watch-main”&#xff0c;为本人对开源代码的学习&…

Java-I/O框架02:使用文件字节流复制文件

package com.yundait.Demo03;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream;/*** 使用文件字节流实现文件的复制* author zhang*/ public class FileInputStreamDemo03 {public static void main(String[] args) th…

多线程——线程的状态

线程状态的意义 ‌线程状态的意义在于描述线程在执行过程中的不同阶段和条件&#xff0c;帮助开发者更好地管理和调度线程资源。 线程的多种状态 线程的状态是一个枚举类型&#xff08;Thread.State&#xff09;&#xff0c;可以通过线程名.getState&#xff08;&#xff09…

基于Springboot+Vue 高考志愿咨询管理系统(源码+LW+部署讲解+数据库+ppt)

&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 会持续一直更新下去 有问必答 一键收藏关注不迷路 源码获取&#xff1a;https://pan.baidu.com/s/1aRpOv3f2sdtVYOogQjb8jg?pwdjf1d 提取码: jf1d &#…