yolov5源码--网络结构模块

2023-11-03

可视化

python models/export.py --weights ./weights/yolov5s.pt --img 640 --batch 1

在这里插入图片描述
使用onnx文件可视化
在这里插入图片描述

网络配置文件

在这里插入图片描述

depth_multiple: 0.33 # 模型网络深度参数(如果已经是1了就不做操作,只对非1的乘这个系数)
width_multiple: 0.50 # 模型channel参数
在这里插入图片描述
9就是堆叠BottleneckCSP的次数(网络深度)
512就是网络channel参数

在这里插入图片描述

  1. from 当前层的输入(-1表示由上一层的输出结果做为当前层的输入)
  2. number 当前层堆叠几次
  3. module 当前层的名字
  4. args 是channel数和卷积核的大小

网络结构解读

关于骨干网络前两个结构块,见我的这篇博文:
netron中的参数
在这里插入图片描述
实际上BottleneckCSP深度为1;channer为64
在这里插入图片描述
看onnx结构图中,只要把在这里插入图片描述
看成卷积+激活函数的组合操作,就很好的可以看懂onnx图了。

代码解读

在这里插入图片描述
首先读取网络结构配置文件yaml.
在这里插入图片描述
在这里插入图片描述

然后开始依据配置文件生成网络结构模型。
(使用函数parse_model来解析的)
在这里插入图片描述
parse_model解析网络架构的代码如下:
在这里插入图片描述
其输出参数如下:
在这里插入图片描述
(就是读取的yaml文件里面的内容)

anchors, nc, gd, gw = d['anchors'], d['nc'], d['depth_multiple'], d['width_multiple']

将d中的数据读取出来:
gd是模型深度系数(堆叠次数)
gw是模型通道channer的系数
nc是类别个数
anchor是先验框的系数:在这里插入图片描述
na是anchor个数
no是:(类别数+5) × anchor个数

其中:

d['backbone'] + d['head']

的数据如下(就是从yaml的数据中一模一样读取过来的)

在这里插入图片描述
遍历backbone和head

for i, (f, n, m, args) in enumerate(d['backbone'] + d['head']):  # from, number, module, args

以第一次遍历为例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
f、n、m、args、和在这里插入图片描述完全对应。
在这里插入图片描述

对应的Focus代码:
在这里插入图片描述
再回来,
对堆叠次数乘以系数gd,但最少也得1次
在这里插入图片描述
当前是Focus,在定义的模块里面。。
在这里插入图片描述
再继续:
在这里插入图片描述在这里插入图片描述
ch就是输入的channel在这里插入图片描述
f就是yaml文件里面写再第一位的那个-1
在这里插入图片描述
得到:

c1是输入channel,c2是输出channel

再将channel维度乘以系数

在这里插入图片描述
在这里插入图片描述
args的参数:输入channel,输出channel,卷积核大小
3,32,3
在这里插入图片描述
将Fcous模块添加进去:
在这里插入图片描述

Focus(
  (conv): Conv(
    (conv): Conv2d(12, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
    (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (act): Hardswish()
  )
)

将Fcous添加并计算参数
在这里插入图片描述
和控制台打印数据有关的参数:

m_.i, m_.f, m_.type, m_.np = i, f, t, np  # attach index, 'from' index, type, number params
logger.info('%3s%18s%3s%10.0f  %-40s%-30s' % (i, f, n, np, t, args))  # print

在这里插入图片描述
将当前层添加到layer里面
在这里插入图片描述
由开始第二层的遍历。。。。。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
其中2是步长,如果是1特征图大小不变,是2的话,特征图减半:在这里插入图片描述
。。。。。。
最后的结果:
在这里插入图片描述
初始化先验框和参数权重
在这里插入图片描述

前向传播

特征提取网络

定位到forward_once函数:
在这里插入图片描述
其中self.model就是之前定义的网络结构
在这里插入图片描述
对self.model进学校遍历:
在这里插入图片描述

第一个m是:

Focus(
  (conv): Conv(
    (conv): Conv2d(12, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
    (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (act): Hardswish()
  )
)

图像经过Focus的处理…
在这里插入图片描述
跳转到Focus:
在这里插入图片描述

  1. 先分块,再拼接,最后卷积
  2. 间隔来完成分块
  3. channel由3变为12(3x4)
  4. 为了加速
    在这里插入图片描述

x(b,c,w,h) -> y(b,4c,w/2,h/2)

其卷积为:
在这里插入图片描述

Conv(
  (conv): Conv2d(12, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (act): Hardswish()
)

再回来。。。
到了第二个模块的遍历。。
在这里插入图片描述

Conv(
  (conv): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
  (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (act): Hardswish()
)

在这里插入图片描述
到三个模块的遍历
在这里插入图片描述

BottleneckCSP(
  (cv1): Conv(
    (conv): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
    (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (act): Hardswish()
  )
  (cv2): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
  (cv3): Conv2d(32, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
  (cv4): Conv(
    (conv): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)
    (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
    (act): Hardswish()
  )
  (bn): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (act): LeakyReLU(negative_slope=0.1, inplace=True)
  (m): Sequential(
    (0): Bottleneck(
      (cv1): Conv(
        (conv): Conv2d(32, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)
        (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (act): Hardswish()
      )
      (cv2): Conv(
        (conv): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
        (bn): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
        (act): Hardswish()
      )
    )
  )
)

跳转到BottleneckCSP函数
在这里插入图片描述
在这里插入图片描述

y1是主分支的路径
y2是捷径分支的路径
最后return self.cv4(self.act(self.bn(torch.cat((y1, y2), dim=1))))就是concat拼接合并后的操作

在这里插入图片描述

在这里插入图片描述

  1. 结合了resnet模块
  2. 提升map
  3. 叠加个数=配置文件中的个数x深度系数

然后,到spp结构了:
在这里插入图片描述
1024为输出特征图channel
5,9,13为不同kernel核的池化
在这里插入图片描述
4. 第四个分支直接短路,然后拼接
5. 先卷积(cv1),再三池化一短路,最后卷积(cv2)
6. 第一个cv1卷积为了降维(之后拼接就升回来了)
7.

在这里插入图片描述

ModuleList(
  (0): MaxPool2d(kernel_size=5, stride=1, padding=2, dilation=1, ceil_mode=False)
  (1): MaxPool2d(kernel_size=9, stride=1, padding=4, dilation=1, ceil_mode=False)
  (2): MaxPool2d(kernel_size=13, stride=1, padding=6, dilation=1, ceil_mode=False)
)

不同的操作,最后得到的图中图大小是一样的,以便完成拼接操作
输出特征图计算公司如下:
在这里插入图片描述
例如(300-5+2x2)/1 +1 =300
(300-9+2x4)/1 +1 = 300特征图不会变化。。
在这里插入图片描述
channel输入是256,输出是256x4=1024,卷积再降维到512…、、

带上卷积操作:
在这里插入图片描述
在这里插入图片描述

整体的结构为:
(卷积后的那一些乘除加是hardswish激活函数的计算过程)
在这里插入图片描述

特征融合网络

在这里插入图片描述
在这里插入图片描述

深层网络的特征图感受野大-检测大目标
浅层网络的特征图感受野小-检测小目标

第一个模块中的卷积模块如下:
(i=11的那一层卷积操作)(第11层)
在这里插入图片描述
在这里插入图片描述

上采用模块(第12层)
在这里插入图片描述
特征拼接模块(第13层)
在这里插入图片描述
在这里插入图片描述
看到,yaml文件中的:
[[-1, 6], 1, Concat, [1]], # cat backbone P4
6,表示和第六层的拼接,其特征层维度一样。

torch.Size([1, 256, 8, 8])concat torch.Size([1, 256, 8, 8])

在这里插入图片描述
在这里插入图片描述


开始第二个卷积模块:
在这里插入图片描述
这里的拼接是和第四层进行concat的
在这里插入图片描述
在这里插入图片描述
上采样输出的结果就是16层的特征图
和第四层的拼接就是17层的输出维度

层数: 4 特征图大小: torch.Size([1, 128, 16, 16])
层数: 16 特征图大小: torch.Size([1, 128, 16, 16])
特征图拼接后:
层数: 17 特征图大小: torch.Size([1, 256, 16, 16])

在这里插入图片描述


开始第三个卷积模块
在这里插入图片描述
在这里插入图片描述
其concat是拼接第14个层结构。
在这里插入图片描述
在这里插入图片描述


第四个卷积块的concat
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
拼接前是22层输出的大小
拼接后是23层输出的大小
在这里插入图片描述

检测头

在这里插入图片描述

在这里插入图片描述

na是anchor的个数
nc是类别个数
5=4+1(位置预测+置信度)
具体的大图见pdf.

在这里插入图片描述
在这里插入图片描述

Detect(
  (m): ModuleList(
    (0): Conv2d(128, 21, kernel_size=(1, 1), stride=(1, 1))
    (1): Conv2d(256, 21, kernel_size=(1, 1), stride=(1, 1))
    (2): Conv2d(512, 21, kernel_size=(1, 1), stride=(1, 1))
  )
)

将17层、20层、23层的进行检测头操作(1x1卷积)。

输出的通道数channel: 21 = 3x(2+5)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

yolov5源码--网络结构模块 的相关文章

随机推荐

  • IDEA OutOfMemory(内存溢出)的问题解决

    1 idea编译时内存溢出 解决办法 打开设置界面 搜索Compiler 编译 如下图所示 将这个值设置为一个较大的值 2 运行时内存溢出 解决办法 打开tomcat设置页面 VM options加上参数 server XX PermSiz
  • MySQL-如何分库分表?一看就懂

    一 为什么要分库分表 如果一个网站业务快速发展 那这个网站流量也会增加 数据的压力也会随之而来 比如电商系统来说双十一大促对订单数据压力很大 Tps十几万并发量 如果传统的架构 一主多从 主库容量肯定无法满足这么高的Tps 业务越来越大 单
  • CentOS 8 正式停服;复旦教授痛批 Google 修复高危漏洞一直延期;WebStorm 2021.3.1 发布

    整理 宋彤彤 责编 屠敏 开源吞噬世界的趋势下 借助开源软件 基于开源协议 任何人都可以得到项目的源代码 加以学习 修改 甚至是重新分发 关注 开源日报 一文速览国内外今日的开源大事件吧 一分钟速览新闻点 开源大新闻 CentOS 8 正式
  • 蓝牙mesh_解密蓝牙mesh:低功耗节点LPN工作过程

    转载自蓝牙技术联盟 低功耗蓝牙 Bluetooth Low Energy 是全球最具节能性的短距离无线通信技术之一 其低功耗的特性广受开发者和消费者赞誉 随着蓝牙mesh网络的推出 开发者可能想知道蓝牙mesh网络是否也被设计为低功耗 是否
  • cmake使用总结

    官方文档CMake Reference Documentation CMake 3 7 2 Documentation CMake是一个跨平台的安装 编译 工具 可以用简单的语句来描述所有平台的安装 编译过程 输出各种各样的makefile
  • 老电脑装Win11的步骤

    去UUP dump选择最新的win11 pro 运行脚本生成ISO文件 使用 https github com AveYo MediaCreationTool bat tree main bypass11 此脚本对ISO文件进行处理 让其可
  • 李开复硅谷之行感悟:跟他们比,我们的创业者现在最缺什么?

    李开复硅谷之行感悟 跟他们比 我们的创业者现在最缺什么 创业10日谈 2016 03 04 i黑马 15天 100人 2016年新年伊始 李开复亲自带队奔赴硅谷 26位鼎鼎大佬 DST米尔纳 Google皮猜 雅虎杨致远 YC孵化器SAM
  • R语言中rattle安装,GTK+反复不成功的问题

    1 首先百度到R语言官网下载最新的R语言环境 2 安装Rstudio去官网下载最新的Rstudio版本安装 如果下载太慢 可以通过百度网盘来下载 链接 https pan baidu com s 1N9eDa14Z5D dUQ5jH LDH
  • 【Leetcode】二叉树刷题I:226/116/114

    还是喜欢手写笔记 这里就直接附上笔记图片和代码 Cpp 学习资源 公众号labuladong 一 二叉树总述 二 leetcode226 Definition for a binary tree node struct TreeNode i
  • shell脚本的正则表达式

    一 概念 正则表达式是通过一些特殊字符的排序 用以删除 查找 替换一行或者多行文字字符串的程序 二 特殊字符 1 字符类 注意 任意字符 与重复字符 1 小数点 代表一定有一个任意字符的意思 2 星号 代表重复前一个0到无穷多次的意思 为组
  • unity台桌小游戏

    1 创建桌面 新建一个empty命名为table 创建子物体plane和四个cube 调整位置和大小 并赋予材质设置颜色 table cube1 cube2 cube3 cube4 2 给主相机添加代码 使相机始终跟随小球 using Sy
  • 卡尔曼滤波推导笔记

    文章目录 卡尔曼滤波 Kalman Filter 第一节 递归算法 第二节 数学基础 数据融合 Data Fuslen 协方差矩阵 Covariance Matrix 状态空间表达 State Space Representation 第三
  • VOC数据集和COCO数据集直接的相互转换

    VOC数据集 xml格式 和COCO数据集 json格式 的相互转换 我们先来看看voc和coco数据集的目录结构 以VOC2012数据集为例 下载下来有如下五个文件夹 Annotations文件夹是存放图片对应的xml文件 比如 2007
  • Intellij Idea 将java项目打包成jar

    1 菜单 File gt project stucture 2 在弹窗最左侧选中Artifacts gt 选jar 选择from modules with dependencies 然后会有配置窗口出现 配置完成后 勾选Build on m
  • Sklearn机器学习中fit,transform, fit_transform的区别

    一 简介 机器学习是从大量的数据中学习到相关的规律和逻辑 然后利用他们来预测未知的事物 它通过学习模拟人类的学习行为 能够自身组织和整理已学习到的知识 并在应用中不断地完善自身缺陷 二 机器学习的步骤 获取数据 数据处理 特征工程 标准化
  • QT添加外部库使用方法

    1 编译库 明确一点 不同编译器编译出来的库不一定可以互相使用的 所以尽量你的库文件是使用同一个编译器编译出来 首先找到你的qt所使用的编译器是哪个 一般会在QT的安装目录下的tools文件夹下 比如 D QT Tools mingw492
  • 基于RFID技术应用于图书档案管理

    基于RFID技术应用于图书档案管理 RFID是一种非接触式自动识别技术 通过射频信号自动识别目标对象并获取相关数据 它具有远距离 批量读取 可识别静止和运动状态下的物品信息 同传统的以条形码为代表的自动识别技术相比 RFID技术具有数据自动
  • 【笔记】行人属性识别

    论文 https arxiv org pdf 1901 07474 pdf 以下序号与论文序列不对应 属性可以看作是高层语义信息 对视点变化和观察条件多样性具有更强的鲁棒性 本文试图解决以下几个重要问题 1 传统和基于深度学习的行人属性识别
  • 华为OD机试 Python 【不开心的小朋友】

    描述 在游乐园里 有一些受小孩欢迎的摇摇车 但每辆车只能由一个小孩使用 其他的小孩要么选择等待要么选择离开 那些选择等待但最后未能玩的小孩会感到不开心 你能帮忙计算出哪些小孩会不开心吗 输入 摇摇车的数量 介于1到10之间 小孩的行动序列
  • yolov5源码--网络结构模块

    网络结构模块 可视化 网络配置文件 网络结构解读 代码解读 前向传播 特征提取网络 特征融合网络 检测头 可视化 python models export py weights weights yolov5s pt img 640 batc