YOLOv5 | 涨点复现!YOLOv5添加BiFPN有效提升目标检测精度
目录
🚀🚀🚀订阅专栏,更新及时查看不迷路🚀🚀🚀
介绍:
BiFPN
代码实现
⭐欢迎大家订阅我的专栏一起学习⭐
🚀🚀🚀订阅专栏,更新及时查看不迷路🚀🚀🚀
YOLOv5涨点专栏:http://t.csdnimg.cn/AEFts
YOLOv8涨点专栏:http://t.csdnimg.cn/v0d7y
💡魔改网络、复现论文、优化创新💡
介绍:
模型效率在计算机视觉中变得越来越重要。在本文中,我们系统地研究了用于目标检测的神经网络架构设计选择,并提出了几个提高效率的关键优化。首先,我们提出了一种加权双向特征金字塔网络(BiFPN),它可以轻松快速地进行多尺度特征融合;其次,我们提出了一种复合缩放方法,可以同时统一缩放所有主干网络、特征网络和框/类预测网络的分辨率、深度和宽度。基于这些优化和 EfficientNet 主干,我们开发了一个新的目标检测器系列,称为 EfficientDet,它在各种资源限制下始终实现比现有技术更高的效率。特别是,通过单模型和单尺度,我们的 EfficientDetD7 在 COCO 测试开发上实现了最先进的 52.2 AP,具有 52M 参数和 325B FLOPs1,比以前小 4 至 9 倍,使用的 FLOP 数减少 13 至 42 倍探测器。
BiFPN
特征金字塔网络(FPN)最初被引入来应对这个挑战。FPN通过构建一个多层次的特征金字塔,其中包含从粗到细的特征图。这些特征图具有不同的分辨率,允许模型在多个尺度上进行检测。
然而,传统的FPN存在一个问题,即信息流只能沿着金字塔的一个方向传播,通常是从高分辨率到低分辨率。这意味着在检测物体时,粗糙特征图中的细节信息可能会丢失,从而影响准确性。
BIFPN通过引入双向连接来解决这个问题。它允许特征图之间的信息在多个尺度之间双向传播,这意味着不仅可以从粗糙特征图传播到细粒度特征图,而且反之亦然。这样,模型可以更全面地捕捉到各种尺度下的特征信息,从而提高了目标检测和实例分割任务的性能。
具体来说,BIFPN的原理包括以下几个关键点:
双向连接:BIFPN引入了特征金字塔层之间的双向连接,允许信息在不同尺度之间双向传播。
特征融合:在双向连接的基础上,BIFPN执行特征融合操作,将不同尺度的特征图结合起来,以产生更具表征性的特征。
信息传播:双向连接使得底层特征图可以通过上层特征图获取更高级的语义信息,同时,上层特征图也可以通过底层特征图获得更精确的位置信息。
多尺度特征:BIFPN产生的特征图具有多个尺度的特征信息,这有助于模型对于不同尺度物体的检测。
总体来说,BIFPN通过引入双向连接和特征融合操作,允许信息在多个尺度之间进行更全面和有效的传播,从而提高了目标检测和实例分割模型的性能。
代码实现
步骤1:在common.py中添加BiFPN模块
将下面BiFPN模块的代码复制粘贴到common.py文件的末尾。
# BiFPN
# 两个特征图add操作
class BiFPN_Add2(nn.Module):def __init__(self, c1, c2):super(BiFPN_Add2, self).__init__()# 设置可学习参数 nn.Parameter的作用是:将一个不可训练的类型Tensor转换成可以训练的类型parameter# 并且会向宿主模型注册该参数 成为其一部分 即model.parameters()会包含这个parameter# 从而在参数优化的时候可以自动一起优化self.w = nn.Parameter(torch.ones(2, dtype=torch.float32), requires_grad=True)self.epsilon = 0.0001self.conv = nn.Conv2d(c1, c2, kernel_size=1, stride=1, padding=0)self.silu = nn.SiLU()def forward(self, x):w = self.wweight = w / (torch.sum(w, dim=0) + self.epsilon)return self.conv(self.silu(weight[0] * x[0] + weight[1] * x[1]))# 三个特征图add操作
class BiFPN_Add3(nn.Module):def __init__(self, c1, c2):super(BiFPN_Add3, self).__init__()self.w = nn.Parameter(torch.ones(3, dtype=torch.float32), requires_grad=True)self.epsilon = 0.0001self.conv = nn.Conv2d(c1, c2, kernel_size=1, stride=1, padding=0)self.silu = nn.SiLU()def forward(self, x):w = self.wweight = w / (torch.sum(w, dim=0) + self.epsilon) # Fast normalized fusionreturn self.conv(self.silu(weight[0] * x[0] + weight[1] * x[1] + weight[2] * x[2]))
步骤2:在yolo.py文件中加入类名
在yolo.py文件的parse_model函数中找到 elif m is Conat: 语句,在其后面加上下列语句:
# 添加bifpn_add结构
elif m in [BiFPN_Add2, BiFPN_Add3]:c2 = max([ch[x] for x in f])
步骤3:创建自定义yaml文件
然后将yaml文件中所有Concat换成BiFPN_Add。
yaml文件修改后的完整代码如下:
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license# Parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
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 v6.0 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, 6, 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, SPPF, [1024, 5]], # 9]# YOLOv5 v6.1 BiFPN head
head:[[-1, 1, Conv, [512, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 6], 1, BiFPN_Add2, [256, 256]], # cat backbone P4[-1, 3, C3, [512, False]], # 13[-1, 1, Conv, [256, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 4], 1, BiFPN_Add2, [128, 128]], # cat backbone P3[-1, 3, C3, [256, False]], # 17 [-1, 1, Conv, [512, 3, 2]], [[-1, 13, 6], 1, BiFPN_Add3, [256, 256]], #v5s通道数是默认参数的一半[-1, 3, C3, [512, False]], # 20 [-1, 1, Conv, [512, 3, 2]],[[-1, 10], 1, BiFPN_Add2, [256, 256]], # cat head P5[-1, 3, C3, [1024, False]], # 23 [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)]
步骤4:验证是否加入成功
在yolo.py文件里,配置我们刚才自定义的yolov5s_BiFPN.yaml


然后运行yolo.py,得到结果。

由运行结果可以看到,所有Concat已被换成了BiFPN_Add。
这样就算添加成功了。🎉🎉🎉
步骤5:修改train.py
首先找到train.py文件中的 #Optimizer,加入下列代码:
g0, g1, g2 = [], [], [] # optimizer parameter groupsfor v in model.modules():if hasattr(v, 'bias') and isinstance(v.bias, nn.Parameter): # biasg2.append(v.bias)if isinstance(v, nn.BatchNorm2d): # weight (no decay)g0.append(v.weight)elif hasattr(v, 'weight') and isinstance(v.weight, nn.Parameter): # weight (with decay)g1.append(v.weight)# BiFPN_Concatelif isinstance(v, BiFPN_Add2) and hasattr(v, 'w') and isinstance(v.w, nn.Parameter):g1.append(v.w)elif isinstance(v, BiFPN_Add3) and hasattr(v, 'w') and isinstance(v.w, nn.Parameter):g1.append(v.w)
此时,会出现报错提示,原因是我们没有导入相应的包。
接下来,我们就导入相应的包

导入完毕后,我们可以看到:报错消失了!
然后,在train.py文件中找到 parse_opt函数,然后将第二行 '--cfg' 的default改为 'models/yolov5s_BiFPN.yaml',然后就可以开始进行训练了。

现在就完全修改成功了,快去试试吧

相关文章:
YOLOv5 | 涨点复现!YOLOv5添加BiFPN有效提升目标检测精度
目录 🚀🚀🚀订阅专栏,更新及时查看不迷路🚀🚀🚀 介绍: BiFPN 代码实现 ⭐欢迎大家订阅我的专栏一起学习⭐ 🚀🚀🚀订阅专栏,更新及…...
【Nut3】nuxt.config.ts项目nuxt配置文件介绍
简言 记录下nuxt3的nuxt.config.ts文件的介绍和使用。 Nuxt Configuration nuxt.config.ts Nuxt可以通过一个单独的nuxt.config文件进行简单配置。 配置文件创建 nuxt.config文件的扩展名可以是.js、.ts或.mjs。 然后默认导出全局函数defineNuxtConfig的返回值,…...
区块链技术的革命性影响
1. 区块链技术的基本原理: 区块链是一种去中心化的分布式数据库技术,通过不断增长的记录(块)构成一个链式结构。每个区块包含了交易数据的加密信息以及上一个区块的哈希值,从而形成了不可篡改的交易记录。这种去中心化…...
多线程(volatile)
volatile的功能 保证内存可见性禁止指令重排序 内存可见性 简单的理解 两(多)个线程同时针对一个变量进行操作, 一个线程读, 一个线程修改, 此时读到的值不一定是修改过后的值 即读线程没有感知到变量的变化 (其实是 编译器/JVM 对于代码在多线程情况下的优化进行了误判) 从 J…...
蓝桥杯 填空 卡片
蓝桥杯 填空题 卡片 解题思路: 我们只需要消耗完卡片的个数即可。 代码示例: #include<bits/stdc.h> using namespace std; int a[10]; bool isEnd(){for(int i0;i<10;i){if(a[i]-1)return false;}return true; } bool getN(int x){while(x){i…...
ELK介绍使用
文章目录 一、ELK介绍二、Elasticsearch1. ElasticSearch简介:2. Elasticsearch核心概念3. Elasticsearch安装4. Elasticsearch基本操作1. 字段类型介绍2. 索引3. 映射4. 文档 5. Elasticsearch 复杂查询 三、LogStash1. LogStash简介2. LogStash安装 四、kibana1. …...
【UE5】非持枪状态蹲姿移动的动画混合空间
项目资源文末百度网盘自取 在BlendSpace文件夹中单击右键选择动画(Animation)中的混合空间(Blend Space) ,选择SK_Female_Skeleton,命名为BS_NormalCrouch 打开BS_NormalCrouch 水平轴表示角色的方向,命名为Direction,方向的最…...
Windows C++ TCP开发(使用select函数以及设置非阻塞/Reuse属性)
1、select官方函数说明: 语法 C int WSAAPI select([in] int nfds,[in, out] fd_set *readfds,[in, out] fd_set *writefds,[in, out] fd_set *exceptfds,[in] const timeval *timeout );参数 [in] nfds 已忽略。 包含 nf…...
ARM TrustZone技术解析:构建嵌入式系统的安全扩展基石
🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| 💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-LOdvohfCEnd8eKyd {font-family:"trebuchet ms",verdana,arial,sans-serif;f…...
初识Python语言-课堂练习【pyhton123题库】
初识Python语言-课堂练习【pyhton123题库】 一、单项选择题 1、Guido van Rossum正式对外发布Python版本的年份是: A 2008B 1998C 1991D 2002 【答案】C 【解析】暂无解析2、下面不是Python语言特点的是:…...
chrome高内存占用问题
chrome号称内存杀手不是盖的,不设设置的话,经常被它内存耗尽死机是常事。以下自用方法 1 自带的memory saver chrome://settings/performance PerformanceMemory Saver When on, Chromium frees up memory from inactive tabs. This gives active tab…...
【C语言】文件操作篇-----程序文件和数据文件,文件的打开和关闭,二进制文件和文本文件,fopen,fclose【图文详解】
欢迎来CILMY23的博客喔,本篇为【C语言】文件操作篇-----程序文件和数据文件,文件的打开和关闭,二进制文件和文本文件【图文详解】,感谢观看,支持的可以给个一键三连,点赞关注收藏。 前言 在了解完动态内存管…...
知识碎片收集
目录 1. 如何计算两点经纬度之间的距离2. 加权随机采样3.什么时LLDB和GDB 1. 如何计算两点经纬度之间的距离 1.知乎-如何计算两点经纬度间距离 2.根据两点经纬度坐标计算距离 3.根据经纬度计算两点之间的距离的公式推导过程以及google.maps的测距函数 4.根据经纬度点计算经…...
不可不知!用例图的绘制与应用全指南深度解析
在软件开发领域中,用例图是一种强大的工具,用于描述系统的功能需求以及系统与外部实体之间的交互。无论是在需求分析阶段还是在系统设计过程中,用例图都扮演着至关重要的角色。本文将全面介绍用例图的绘制方法和其在软件开发中的应用…...
【数据结构七】堆与PriorityQueue详解
堆 在Java中有一种数据结构基于队列,并保证操作的数据带有优先级,该数据结构应该提供了两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。这种数据结构就是优先级队列(Priority Queue)。它的底层使用了堆这种数据结…...
uniapp写支付的操作
支付的时候一般需要几个参数: ‘timeStamp’: 时间戳,‘nonceStr’: 随机字符串,不超过32位‘package’: 下单后接口返回的prepauid‘signType’: 签名的算法‘paySign’: 后端会给前端一个签名sign: data.sign // 根据签名算法生成签名 <template&…...
微信小程序开发系列(二十四)·wxml语法·列表渲染·wx:for-item 和 wx:for-index
目录 1. 如果需要对默认的变量名和下标进行修改,可以使用wx:for-item 和 wx:for-index 2. 将 wx:for 用在 标签上,以渲染一个包含多个节点的结构块 方法一 方法二 3. 总结 3.1 wx:for-item 和 wx:for-index总结 3.2 总结 1. 如果需要对默…...
下载无水印抖音视频
在抖音看到某些视频想下载,却出现无法保存在本地【显示"作品暂时无法保存,链接已复制"】。或者下载的视频有水印。 而某些微信小程序下载可能需要付费或者有水印。其实我们可以直接使用电脑浏览器直接下载。 举个例子: 这是来自王道官方账号的一条视频链…...
L1-039 古风排版(C++)
中国的古人写文字,是从右向左竖向排版的。本题就请你编写程序,把一段文字按古风排版。 输入格式: 输入在第一行给出一个正整数N(<100),是每一列的字符数。第二行给出一个长度不超过1000的非空字符串&a…...
springboot项目docker分层构建
一、需求场景 在使用dockerfile构建springboot项目时,速度较慢,用时比较长,为了加快构建docker镜像的速度,采用分层构建的方式 二、构建配置 1、pom.xml配置 <properties><project.build.sourceEncoding>UTF-8<…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
