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函数的行为也会有所不同…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...