物体检测-系列教程23:YOLOV5 源码解析13 (SPP层、Flatten模块、Concat模块、Classify模块)

😎😎😎物体检测-系列教程 总目录

有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Pycharm中进行
本篇文章配套的代码资源已经上传
点我下载源码

在这里插入图片描述

17、SPP模块

17.1 SPP类

SPP是一种特殊的池化策略,最初在YOLOv3-SPP中被使用,旨在提高模型对于不同尺寸输入的适应性,通过对同一特征图进行不同尺寸的池化,然后将这些池化后的特征图拼接起来,增加了模型捕捉不同尺度特征的能力

class SPP(nn.Module):
    # Spatial pyramid pooling layer used in YOLOv3-SPP
    def __init__(self, c1, c2, k=(5, 9, 13)):
        super(SPP, self).__init__()
        c_ = c1 // 2  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)
        self.cv2 = Conv(c_ * (len(k) + 1), c2, 1, 1)
        self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k])

    def forward(self, x):
        x = self.cv1(x)
        return self.cv2(torch.cat([x] + [m(x) for m in self.m], 1))
  1. 继承nn.Module
  2. 构造函数,传入3个参数:输入通道c1、输出通道c2、不同池化核的大小元组k(包含三个整数,表示特征金字塔池化中不同池化核的大小)
  3. 初始化
  4. c_,计算中间层的通道数,即通道数减半
  5. cv1 ,定义一个卷积模块,通道数从c1降到c_
  6. cv2,定义一个卷积模块,输入通道数为c_ * (len(k) + 1),这是因为SPP层将原始特征图与len(k)个池化后的特征图拼接,因此增加了通道数。该卷积层的作用是将拼接后的特征图降维到输出通道数c2
  7. m,m是一个模块列表,相当于是pytorch对应的list,是专门用来保存pytorch中的模型的list,m包含三个最大池化层,每个池化层的核大小分别为k元组中的值。步长设置为1,并且填充(padding)设置为kernel_size // 2,这样做是为了保持特征图的尺寸不变
  8. 前向传播
  9. x,将输入经过一个卷积模块
  10. 将前面的输出和前面输出经过一个包含3个池化层的模块分别进行拼接,拼接的结果再经过一个卷积模块,返回结果

SPP模块通过特征金字塔池化技术增强了模型对不同尺度特征的捕捉能力。通过在不改变特征图空间维度的前提下增加通道维度信息,SPP可以有效提升模型的性能

17.2 Flatten类

class Flatten(nn.Module):
    # Use after nn.AdaptiveAvgPool2d(1) to remove last 2 dimensions
    @staticmethod
    def forward(x):
        return x.view(x.size(0), -1)
  1. 继承nn.Module
  2. 一个Python装饰器,表示是一个静态方法,静态方法不需要实例化即可调用,它不依赖于类的实例变量
  3. 前向传播,被装饰圈重写
  4. 返回执行压平操作的输出

17.3 Concat类

class Concat(nn.Module):
    def __init__(self, dimension=1):
        super(Concat, self).__init__()
        self.d = dimension
    def forward(self, x):
        return torch.cat(x, self.d)
  1. 继承nn.Module
  2. 构造函数,传入一个在哪个维度进行拼接的参数
  3. 初始化
  4. d,拼接维度
  5. 前向传播
  6. 返回拼接

17.4 Classify类

class Classify(nn.Module):
    def __init__(self, c1, c2, k=1, s=1, p=None, g=1): 
        super(Classify, self).__init__()
        self.aap = nn.AdaptiveAvgPool2d(1)  # to x(b,c1,1,1)
        self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p), groups=g, bias=False)  # to x(b,c2,1,1)
        self.flat = Flatten()
    def forward(self, x):
        z = torch.cat([self.aap(y) for y in (x if isinstance(x, list) else [x])], 1)  # cat if list
        return self.flat(self.conv(z))  # flatten to x(b,c2)
  1. 继承nn.Module
  2. 构造函数,传入输入通道c1、输出c2、卷积核尺寸k=1*1、卷积步长s=1、padding、卷积分组g
  3. 初始化
  4. aap,定义一个全局自适应平均池化层
  5. conv,定义一个卷积层,padding通过调用autopad函数动态计算,不要偏执
  6. flat,调用一个展平模块
  7. 前向传播
  8. z,检查输入x是否为列表:如果是,对列表中的每个元素应用自适应平均池化层aap;如果不是,将x转换为列表后应用aap。然后,在维度1上拼接处理后的特征图,以支持多输入的情况
  9. 进行一个卷积操作后再展平,返回输出

Classify类实现了一个通用的分类头结构,它通过一个自适应平均池化层和一个卷积层将输入特征图转换为一维特征向量,适用于各种分类任务。此外,它通过处理输入列表的能力,为处理多输入或合并来自不同源的特征提供了便利。这种灵活性和效率是深度学习模型在图像分类任务中常见的要求

17.5 辅助函数

autopad用于自动计算卷积层的填充,输出特征图的尺寸与输入相同

def autopad(k, p=None):  # kernel, padding
    # Pad to 'same'
    if p is None:
        p = k // 2 if isinstance(k, int) else [x // 2 for x in k]  # auto-pad
    return p

  1. 接受两个参数:k卷积核大小,p填充量。如果p没有显式提供(即为None),则该函数将计算并返回一个"自动"填充值,使得卷积操作的输出特征图在空间尺寸上与输入特征图相同
  2. 检查是否提供了p参数,如果没有,则进入自动计算填充的逻辑
  3. 这行是自动计算填充量的核心逻辑。如果k是整数(标准情况下,表示卷积核大小是正方形),则p被设置为k // 2。如果k是一个序列(表示卷积核可能是矩形),则对k中的每个元素进行同样的操作,计算出一个填充量列表
  4. 返回计算出的填充量p

DWConv,一个深度可分离卷积层,一种高效的卷积实现方式,能够减少参数数量和计算成本


def DWConv(c1, c2, k=1, s=1, act=True):
    # Depthwise convolution
    return Conv(c1, c2, k, s, g=math.gcd(c1, c2), act=act)
  1. 这个函数定义了一个深度可分离卷积层。c1是输入通道数,c2是输出通道数,k是卷积核大小,默认为1,s是步长,默认为1,act标志是否使用激活函数,默认为True
  2. 返回一个Conv对象,Conv是一个包含二维卷积、激活函数、归一化的卷积模块

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Axuer的中继器~增删改查

目录 1. 中继器 2. 增加 3. 全选 4. 删除 5. 修改 6. 排序 7.分页 正文: 1.中继器:拉一个中继器给中继器名称写一个数据 在右边点击样式 写入数据 1.2 双击中继器进入动态页面 在里面放3个框 1.3 退出来 给中继器添加数据 2. 增加&#xff1…

研发效能DevOps: OpenEuler 部署 drone 持续集成平台

目录 一、实验 1.环境 2.OpenEuler 部署 drone 持续集成平台 二、问题 1.drone登录失败 一、实验 1.环境 (1)主机 表1 主机 系统架构版本IP备注LinuxopenEuler22.03 LTS SP2 192.168.204.145(动态) 192.168.204.141&…

使用maven打包执行install命令时候一直卡在No proxies configured不动,如何解决?

问题描述: [INFO] [INFO] — frontend-maven-plugin:1.9.1:install-node-and-npm (install node and npm) frontend — [INFO] Installing node version v16.0.0 [INFO] Copying node binary from D:\Maven\maven-repository\com\github\eirslett\node\16.0.0\node…

3.11_C++_day1_作业

作业要求&#xff1a; 程序代码&#xff1a; #include <iostream> #include <string.h>using namespace std;int main() {int a0,b0,c0,d0,e0;//分别记录字符串中的大写&#xff0c;小写&#xff0c;数字&#xff0c;空格&#xff0c;其他字符个数string str;cha…

Docker初体验之安装部署和镜像加速(openeuler版)

安装部署&#xff1a; 本人使用的为openeuler版本&#xff0c;无法使用二进制进行安装&#xff08;使用二进制安装时&#xff0c;无法使用docker中的补全命令&#xff0c;需要重新进行配置&#xff09;在此使用yum直接进行安装。 [rootlocalhost ~]# yum install docker 镜像…

java异常概述及自定义处理

前言 学到异常了&#xff0c;本来以为处理异常只是避免bug&#xff0c;结果发现还可以为了编程需要自定义异常。打好基础&#xff0c;daydayup! 异常 什么是异常 异常就是代表程序出现的问题 异常的体系 异常体系指的是java开发人员为了方便程序员使用所开发的异常类&#xff…

稀碎从零算法笔记Day10-LeecCode:赎金信

题型&#xff1a;哈希表、字符串 链接&#xff1a;383. 赎金信 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以…

探索数据可视化:Matplotlib 高级绘图功能(一)

双轴显示 import numpy as np import matplotlib.pyplot as pltx np.linspace(-np.pi, np.pi,50) y np.sin(x)plt.plot(x,y,color blue)# 设置 y 轴的刻度为从 -1 到 1 的 11 个等间距位置 _ plt.yticks(np.linspace(-1,1,11),color blue)ax plt.gca()# 获取当前视图 # …

PlantUML + VS Code

PlantUML 使用实例 文章目录 PlantUML 使用实例1. PlantUML简介1.1 什么是PlantUML1.2 PlantUML优势在哪 2. 怎么用2.1 环境依赖2.2 VS Code组件安装 3. 常用语法3.1 标记开始结束3.2 声明参与者3.3 声明关系3.4 对消息序列编号3.5 组合消息 4. 实例 1. PlantUML简介 1.1 什么…

vulhub靶场-matrix-breakout-2-morpheus

下载&部署 从官网中下载 https://www.vulnhub.com/entry/matrix-breakout-2-morpheus,757/ 下载完成后&#xff0c;在vmware中打开&#xff0c;选择刚刚下载的ova文件 vmware打开文件后需要将刚导入的机器重新启动 再检查下网卡是否是和kali在同一张网卡下就可以开始打靶了…

Jmter接口网站压力测试工具

首先下载Jmeter 官方地址&#xff1a;Apache JMeter - Apache JMeter™ 安装Jmeter 把下载的文件进行解压&#xff0c;产生如下目录&#xff1a; 打开bin文件夹下的jmeter.bat文件及进入程序的主界面窗体jmeter.log是日志文件。 主意&#xff1a;需要配置java环境。 jmter创…

解决虚拟机静态网址设置后还是变动的的问题

源头就是我的虚拟机静态网址设置好了以后但是网址还是会变动 这是我虚拟机的配置 vi /etc/sysconfig/network-scripts/ifcfg-ens33 这是出现的问题 进入这里 cd /etc/sysconfig/network-scripts/ 然后我去把多余的ens33的文件都删了 然后还不行 后来按照这个图片进行了下 然后…

权限管理系统-0.4.0

五、权限管理 5.1 引入JWT JWT是JSON Web Token的缩写&#xff0c;即JSON Web令牌&#xff0c;是一种自包含令牌。 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。 JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息&#xff0c;以…

STM32CubeIDE基础学习-STM32CubeIDE软件新增工程文件夹

STM32CubeIDE基础学习-STM32CubeIDE软件新增工程文件夹 文章目录 STM32CubeIDE基础学习-STM32CubeIDE软件新增工程文件夹前言第1章 添加文件夹第2章 添加文件路径2.1 相对路径方法2.2 绝对路径方法 总结 前言 在编程的过程中&#xff0c;如果需要在原有的工程基础上新增其它的…

C 嵌入式系统设计模式 24:安全性和可靠性介绍

本书的原著为&#xff1a;《Design Patterns for Embedded Systems in C ——An Embedded Software Engineering Toolkit 》&#xff0c;讲解的是嵌入式系统设计模式&#xff0c;是一本不可多得的好书。 本系列描述我对书中内容的理解。本文章描述嵌入式安全性和可靠性模式之一…

二叉搜索树题目:前序遍历构造二叉搜索树

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 解法三思路和算法代码复杂度分析 解法四思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;前序遍历构造二叉搜索树 出处&#xff1a;1008. …

Anacond 安装及使用教程pytorch安装

下载网址&#xff1a;Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror pycharm安装教程 【从Python基础到深度学习】1. Python PyCharm安装及激活-CSDN博客 pycharm添加anaconda环境 conda创建虚拟环境 base表示当前conda的base环境&a…

sheng的学习笔记- AI-类别不平衡问题

目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 什么是类别不平衡问题 类别不平衡&#xff08;class-imbalance&#xff09;&#xff0c;也叫数据倾斜&#xff0c;数据不平衡&#xff0c;就是指分类任务中不同类别的训练样例数目差别很大的情况。 例如有998个反例&#xf…

【智能算法】蜻蜓算法(DA)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.代码实现4.参考文献 1.背景 2016年&#xff0c;Mirjalili受到蜻蜓静态和动态集群行为启发&#xff0c;提出了蜻蜓算法(Dragonfly algorithm, DA)。 2.算法原理 2.1算法思想 蜻蜓集群有两种行为目的&#xff1a;狩猎&#xf…

大模型相关整理

机器学习 模型就是函数&#xff0c;这个函数可能是一个很简单的线性函数&#xff0c;也可以是一个非常复杂的高阶函数、或者是一个多层的神经网络函数。 机器学习领域的很多研究和方法都是在尝试设计这个函数&#xff0c;以自动驾驶领域为例&#xff0c;之前的自动驾驶基于人…