YOLOv5中添加SE模块详解——原理+代码
目录
- 一、SENet
- 1. 设计原理
- 2. SE Block
- 2.1 Squeeze:Global Information Embedding
- 2.2 Excitation:Adaptive Recalibration
- 3. SE-Inception and SE-ResNet
- 二、YOLOv5中添加SENet
- 1.修改common.py
- 2.修改yolo.py
- 3.修改yolov5s.yaml
- 参考文章
一、SENet
论文地址:Squeeze-and-Excitation Networks [CVPR2017]
Caffe代码地址:SENet-Caffe
Pytorch代码地址:SENet-Pytorch
1. 设计原理
论文中提到,在SENet提出之前,大部分工作专注于研究特征图的空间编码质量(可以理解为每个通道的特征图的特征提取质量),即只关注每个通道中特征图的表达能力,而没有关注不同通道的特征图的融合(如果一个特征图的维度为C×H×WC×H×WC×H×W的话,SENet之前的工作只关注了HHH和WWW维度,而没有关注CCC维度,不同通道的特征图融合还是通过卷积相加的方式完成)。
SENet关注了通道关系,提出了Squeeze-and-Excitation模块,通过显式地模拟通道之间的相互依赖关系,自适应地重新校准通道的特征响应(普通卷积过程的通道关系本质上是隐式的和局部的(除了最顶层的通道关系,因为最顶层的通道与任务相关,比如分割网络的最顶层通道数为分割类别数,而中间层的通道数通常是经验所得))。
2. SE Block

SE Block的结构如图1所示,首先通过卷积操作FtrF_{tr}Ftr将输入特征图X∈RH′×W′×C′X\in R^{H'\times W'\times C'}X∈RH′×W′×C′映射到特征图U∈RH×W×CU\in R^{H\times W\times C}U∈RH×W×C,在这个过程中,用V=[v1,v2,...,vC]V=[v_{1},v_{2},...,v_{C}]V=[v1,v2,...,vC]表示卷积核的集合,输出可表示为U=[u1,u2,...,uC]U=[u_{1},u_{2},...,u_{C}]U=[u1,u2,...,uC],则:
uc=vc∗X=∑s=1C′vcs∗xsu_c=v_{c}*X=\sum_{s=1}^{C'}v_{c}^s*x^suc=vc∗X=s=1∑C′vcs∗xs
这里 ∗*∗ 表示卷积操作,uc∈RH×Wu_{c}\in R^{H\times W}uc∈RH×W,vc=[vc1,vc2,...,vcC′]v_{c}=[v_{c}^1,v_{c}^2,...,v_{c}^{C'}]vc=[vc1,vc2,...,vcC′],X=[x1,x2,...,xC′]X=[x^{1},x^{2},...,x^{C'}]X=[x1,x2,...,xC′],vcsv_{c}^svcs是一个二维卷积核,表示vcv_{c}vc的单个通道作用于XXX的相应通道上。
2.1 Squeeze:Global Information Embedding
为了考虑输出特征图中每个通道的信息,论文通过全局平均池化的方式,将全局空间信息压缩到一个通道描述符zcz_{c}zc中:
zc=Fsq(uc)=1H×W∑i=1H∑j=1Wuc(i,j)z_{c}=F_{sq}(u_{c})=\frac{1}{H\times W}\sum_{i=1}^{H}\sum_{j=1}^{W}u_{c}(i,j)zc=Fsq(uc)=H×W1i=1∑Hj=1∑Wuc(i,j)
2.2 Excitation:Adaptive Recalibration
为了完全捕获通道依赖关系,论文选择使用一种简单的带有Sigmoid激活的门控机制:
s=Fex(z,W)=σ(g(z,W))=σ(W2δ(W1z))s=F_{ex}(z,W)=\sigma (g(z,W))=\sigma (W_{2}\delta (W_{1}z))s=Fex(z,W)=σ(g(z,W))=σ(W2δ(W1z))
其中,δ\deltaδ为ReLU函数,W1∈RCr×CW_{1}\in R^{\frac{C}{r}\times C}W1∈RrC×C,W2∈RC×CrW_{2}\in R^{C\times\frac{C}{r}}W2∈RC×rC。
通过s重新缩放U,得到SE Block最后的输出:
xˉc=Fscale(uc,sc)=scuc\bar{x}_{c}=F_{scale}(u_{c},s_{c})=s_{c}u_{c}xˉc=Fscale(uc,sc)=scuc
3. SE-Inception and SE-ResNet
图2为原文设计的SE-Inception模块和SE-ResNet模块,这是一个即插即用模块。为了解决通道之间的依赖关系,作者使用全局平均池化操作来压缩全局空间信息,这就是Sequeeze操作。为了利用在Sequeeze操作中聚合的信息,作者通过FC-ReLU-FC-Sigmoid操作来完全捕获通道依赖性,这就是Excitation操作。

class SELayer(nn.Module):def __init__(self, channel, reduction=16):super(SELayer, self).__init__()self.avg_pool = nn.AdaptiveAvgPool2d(1) #全局平均池化,输入BCHW -> 输出 B*C*1*1self.fc = nn.Sequential(nn.Linear(channel, channel // reduction, bias=False), #可以看到channel得被reduction整除,否则可能出问题nn.ReLU(inplace=True),nn.Linear(channel // reduction, channel, bias=False),nn.Sigmoid())def forward(self, x):b, c, _, _ = x.size()y = self.avg_pool(x).view(b, c) #得到B*C*1*1,然后转成B*C,才能送入到FC层中。y = self.fc(y).view(b, c, 1, 1) #得到B*C的向量,C个值就表示C个通道的权重。把B*C变为B*C*1*1是为了与四维的x运算。return x * y.expand_as(x) #先把B*C*1*1变成B*C*H*W大小,其中每个通道上的H*W个值都相等。*表示对应位置相乘。
二、YOLOv5中添加SENet
1.修改common.py
在models/common.py中添加下列代码
class SElayer(nn.Module):def __init__(self, c1, c2, ratio=16):super(SElayer, self).__init__()#c*1*1self.avgpool = nn.AdaptiveAvgPool2d(1)self.l1 = nn.Linear(c1, c1 // ratio, bias=False)self.relu = nn.ReLU(inplace=True)self.l2 = nn.Linear(c1 // ratio, c1, bias=False)self.sig = nn.Sigmoid()def forward(self, x):b, c, _, _ = x.size()y = self.avgpool(x).view(b, c)y = self.l1(y)y = self.relu(y)y = self.l2(y)y = self.sig(y)y = y.view(b, c, 1, 1)return x * y.expand_as(x)
2.修改yolo.py
在models/yolo.py中的parse_model函数中添加SElayer模块
if m in [Conv, GhostConv, Bottleneck, GhostBottleneck, SPP, DWConv, MixConv2d, Focus, CrossConv, BottleneckCSP,C3, C3TR, ASPP, SElayer]:c1, c2 = ch[f], args[0] if c2 != no: c2 = make_divisible(c2 * gw, 8) args = [c1, c2, *args[1:]]
3.修改yolov5s.yaml
在Backbone的倒数第二层添加SElayer,修改后的yolov5s.yaml如下所示:
# parameters
nc: 20 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple# anchors
anchors:- [10,13, 16,30, 33,23] # P3/8- [30,61, 62,45, 59,119] # P4/16- [116,90, 156,198, 373,326] # P5/32# YOLOv5 backbone
backbone:# [from, number, module, args][[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2[-1, 1, Conv, [128, 3, 2]], # 1-P2/4[-1, 3, C3, [128]],[-1, 1, Conv, [256, 3, 2]], # 3-P3/8[-1, 9, C3, [256]],[-1, 1, Conv, [512, 3, 2]], # 5-P4/16[-1, 9, C3, [512]],[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32[-1, 3, C3, [1024]],[-1, 1, SElayer, [1024]],[-1, 1, SPPF, [512, 512]], # 10]head:[[-1, 1, Conv, [512, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 6], 1, Concat, [1]], # cat backbone P4[-1, 3, C3, [512, False]], # 14[-1, 1, Conv, [256, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 4], 1, Concat, [1]], # cat backbone P3[-1, 3, C3, [256, False]], # 18 (P3/8-small)[-1, 1, Conv, [256, 3, 2]],[[-1, 15], 1, Concat, [1]], # cat head P4[-1, 3, C3, [512, False]], # 21 (P4/16-medium)[-1, 1, Conv, [512, 3, 2]],[[-1, 11], 1, Concat, [1]], # cat head P5[-1, 3, C3, [1024, False]], # 24 (P5/32-large)[[18, 21, 24], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5) ]
参考文章
SE-ResNet的实现
YOLOv5-6.1添加注意力机制(SE、CBAM、ECA、CA)
相关文章:
YOLOv5中添加SE模块详解——原理+代码
目录一、SENet1. 设计原理2. SE Block2.1 Squeeze:Global Information Embedding2.2 Excitation:Adaptive Recalibration3. SE-Inception and SE-ResNet二、YOLOv5中添加SENet1.修改common.py2.修改yolo.py3.修改yolov5s.yaml参考文章一、SENet 论文地址:Squeeze-a…...
arcgispro3.1(账号登陆)
ArcGIS Pro 3.1 更新中文概览专注于 制图、GIS、Python前言:本次更新给了我两个惊喜,一个是本来 ArcMap 就有的功能,另一个明显是学习的 QGIS,嘿嘿,大家往下看吧。整理翻译了一下官方的 ArcGIS Pro 3.1 新特性更新概览…...
VB6换个思路解决微信下载文件只读的问题(含源码)
日期:2023年3月10日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方…...
Allegro如何知道组合操作命令的拼写
Allegro如何知道组合操作命令的拼写 前面介绍了如何知道单个操作命令的拼写,但如果是复合命令,就无法直观的通过命令来了解,如下图 Snap Pick to -Segment这个命令拼写是什么 如何知道,具体操作如下 点击File点击Script 出现Scripting窗口...
CDO高效处理气象数据
基础命令,只需要在终端输入命令按enter运行即可 ####### 查看文件信息 cdo infos xxx.nc #显示nc文件中的变量名 cdo showname sst.nc #读文件夹下的数据 for i in $(ls);do echo processing $i ;done #线性插值 cdo remapbil,经度纬度 input.nc output.nc ;done ##…...
1. Qt Designer Studio界面介绍
1. 说明: Qt当中的Qt Quick框架使用QML语言来快速搭建优美的界面,但是对于单纯做界面的设计人员并不是很友好,还要让界面设计人员去消耗时间成本学习QML语法。Qt Designer Studio软件就是为了解决这个问题而设计的,工作人员不需要…...
elementUI+vue_vue-admin-template框架
目录安装版本管理文件mock文件夹---模拟数据permission.js --- 登录权限控制文件安装 克隆项目git clone https://gitee.com/panjiachen/vue-admin-template.git进入项目目录cd vue-element-admin安装依赖npm install启动服务npm run dev版本管理 由于我们之前的项目是直接从…...
SpringBoot项目使用Schedule注释创建定时任务
文章目录知识讲解相关注释(主要两个,EnableScheduling和Scheduled)scheduled的cron语法代码项目目录结构启动类(Application)定时任务类(Task)配置类(application.properties)pom依赖展望(Quart…...
学习 Python 之 Pygame 开发魂斗罗(十一)
学习 Python 之 Pygame 开发魂斗罗(十一)继续编写魂斗罗1. 改写主类函数中的代码顺序2. 修改玩家初始化3. 显示玩家生命值4. 设置玩家碰到敌人死亡5. 设置敌人子弹击中玩家6. 修改updatePlayerPosition()函数逻辑继续编写魂斗罗 在上次的博客学习 Pytho…...
Linux驱动开发
一、驱动分类Linux中包含三大类驱动:字符设备驱动、块设备驱动和网络设备驱动。其中字符设备驱动是最大的一类驱动,因为字符设备最多,从led到I2C、SPI、音频等都属于字符设备驱动。块设备驱动和网络设备驱动都要比字符设备驱动复杂。因为其比…...
32--Vue-前端开发-Vue语法之组件化开发
一、vue语法回顾 购物车的例子 eg1:计算商品价格(掌握对象的迭代方法) <!DOCTYPE html> <html lang="en"> <head>...
打怪升级之CFileDialog类介绍
CFileDialog类 CFileDialog封装用于文件打开操作或文件保存操作的常见对话框。信息来源自Windows官方文档:https://learn.microsoft.com/zh-cn/cpp/mfc/reference/cfiledialog-class?viewmsvc-170 这里重点介绍几个常用的函数功能: 构造函数 explic…...
配天智造自主原创数字工厂:百余名员工人均创收122万
配天智造(832223)2022年度报告显示,报告期内公司实现营业收入1.3亿元,同比增长52%,归属于挂牌公司股东的净利润3867万元,同比增长28.11%。而这家公司全部在职员工仅有107人,人均创收约为122万。…...
COLMAP
简介:在使用instant-ngp过程中需要使用COLMAP得到模型的必要输入,比如模型需要的相机外参我们就可以通过COLMAP中的sparse reconstruction稀疏重建得到;而对于depth map深度图我们则需要dense reconstruction稠密重建得到,下面我们…...
2023-3-8 刷题情况
礼盒的最大甜蜜度 题目描述 给你一个正整数数组 price ,其中 price[i] 表示第 i 类糖果的价格,另给你一个正整数 k 。 商店组合 k 类 不同 糖果打包成礼盒出售。礼盒的 甜蜜度 是礼盒中任意两种糖果 价格 绝对差的最小值。 返回礼盒的 最大 甜蜜度。…...
关于长连接服务器和客户端之间要加入心跳的一些讨论
在之前的章节里深入浅出TCPIP之深入浅出TCPIP之TCP重传机制 我们都知道了TCPIP协议栈有个默认的TCP心跳机制,这个心跳机制是和socket绑定的,可以对指定的套接字开启协议栈的心跳检测机制。默认情况下,协议栈的心跳机制对socket套接字是关闭的,如果要使用需要人为开启的。 比…...
LeetCode——1590. 使数组和能被 P 整除
一、题目 给你一个正整数数组 nums,请你移除 最短 子数组(可以为 空),使得剩余元素的 和 能被 p 整除。 不允许 将整个数组都移除。 请你返回你需要移除的最短子数组的长度,如果无法满足题目要求,返回 -1…...
12N65-ASEMI高压MOS管12N65
编辑-Z 12N65在TO-220封装里的静态漏极源导通电阻(RDS(ON))为0.68Ω,是一款N沟道高压MOS管。12N65的最大脉冲正向电流ISM为48A,零栅极电压漏极电流(IDSS)为10uA,其工作时耐温度范围为-55~150摄氏度。12N65功耗&#x…...
cushy-serial 一个轻量级Python serial库
本文自笔者博客: https://www.blog.zeeland.cn/archives/rgoihgxcoci3 简介 cushy-serial是一个轻量级的Serial框架,初衷是希望使Serial编程变得更加简单、快捷,因此,相较于传统的pyserial,该框架可以更加快速地构建起一个serial…...
音视频开发系列(7)——Opengl常用Api介绍part1
GLES20.glTexParameteri GLES20.glTexParameteri是OpenGL ES 2.0用于设置纹理过滤器和纹理包装模式的函数。它有三个参数: target参数 target参数指定要设置纹理参数的纹理目标,根据不同的target值,glTexParameteri函数的行为也会有所不同…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
