核心内容摘要
DeerFlow调试技巧:常见启动失败原因与解决方案
前言本文介绍了基于增强层间特征相关性EFC的轻量级融合策略及其在 YOLO26中的结合。
检测无人机图像小物体具有挑战性传统多尺度特征融合方法存在不足。
EFC 模块通过引入分组的特征聚焦单元GFF增强特征关联性利用多级特征重构模块MFR进行特征重构减少冗余特征生成且具有通用性和适应性。
我们将 EFC 模块集成进 YOLO26替换部分特征融合策略。
该方法即插即用有望提升 YOLO26在小物体检测任务中的性能。
文章目录 YOLO26改进大全卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总专栏链接: YOLO26改进专栏文章目录前言介绍摘要文章链接基本原理核心代码YOLO26引入代码tasks注册步骤1:步骤2配置yolo26-EFC.yaml实验脚本结果介绍摘要鉴于无人机图像存在低分辨率以及背景混合的情况检测其中的小物体颇具挑战性这会造成特征信息有限。
多尺度特征融合能够通过获取不同尺度上的信息来增强检测能力然而传统方法存在一定缺陷。
简单的连接或加法运算无法充分发挥多尺度融合的优势致使特征之间的相关性不足。
这一缺陷对小物体的检测造成了阻碍尤其是在复杂背景和人口稠密地区。
为解决该问题并有效利用有限的计算资源本文提出一种基于增强层间特征相关性EFC的轻量级融合策略用以替代传统特征金字塔网络FPN中的特征融合策略。
特征金字塔中不同图层的语义表达存在不一致性。
在EFC策略里分组的特征聚焦单元GFF通过聚焦不同特征的上下文信息来增强各层的特征相关性。
多级特征重构模块MFR对金字塔中各层的强弱信息进行有效的重构和变换减少冗余的特征融合从而保留更多的小目标信息。
值得一提的是所提出的方法具有即插即用的特性能够广泛应用于各种基础网络。
文章链接论文地址论文地址代码地址代码地址基本原理EFC (Enhanced Inter-layer Feature Correlation) 模块是一种轻量级的特征融合策略旨在提升小物体检测的性能尤其是在复杂的背景中。
以下是对 EFC 模块各组成部分的详细介绍特征关联增强 EFC 模块通过引入Grouped Feature Focusing Unit (GFF)来强化不同层之间的特征关联性。
GFF 通过关注特征的空间上下文信息聚合邻近层的特征使得特征之间的语义表示更加一致和丰富。
这种对上下文信息的聚焦有助于解决小物体特征的不确定性问题使模型能够更好地定位小物体。
特征重构 EFC 中的Multi-Level Feature Reconstruction Module (MFR)关键在于有效利用各层的特征而不是仅依赖于简单的卷积操作。
MFR 模块能够分离强弱特征信息通过对特征进行重构来最大程度地保留对于小物体检测至关重要的细节信息降低语义偏差。
这使得模型在不同层次的特征融合中能够更精确地理解小物体的空间位置和语义内容。
冗余特征的减少 EFC 特别设计时考虑到了减少冗余特征生成的方法。
传统的特征融合常常使用大型卷积核导致冗余信息的产生而 EFC 通过采用小型卷积或者轻量级卷积设计降低了计算复杂度并在不损失信息的前提下使得输出特征更加精炼和有用。
通用性和适应性 EFC 模块设计为“插件式”可以广泛应用于多种特征金字塔网络FPN框架提供了更灵活的检测模型适应能力。
这种普遍适用性使得 EFC 可以与不同基础网络结合进一步提升各种目标检测任务中的表现。
通过上述原理EFC 模块能够有效应对小物体检测中的挑战尤其是在多尺度和复杂背景下增强了特征表达能力最终实现了更高的检测精度和效率核心代码importtorch.nnasnnimporttorch.nn.functionalasFfrommmcv.cnnimportConvModulefrommmcv.runnerimportBaseModule,auto_fp16from..builderimportNECKSclassEFC(BaseModule):def__init__(self,c1,c
:super().__init__()self.conv1nn.Conv2d(c1,c2,kernel_size1,stride
self.conv2nn.Conv2d(c2,c2,kernel_size1,stride
self.conv4nn.Conv2d(c2,c2,kernel_size1,stride
self.bnnn.BatchNorm2d(c
self.sigomidnn.Sigmoid()self.group_num16self.eps1e-10self.gammann.Parameter(torch.randn(c2,1,
)self.betann.Parameter(torch.zeros(c2,1,
)self.gate_genatornn.Sequential(nn.AdaptiveAvgPool2d((1,
),nn.Conv2d(c2,c2,1,
,nn.ReLU(True),nn.Softmax(dim
,)self.dwconvnn.Conv2d(c2,c2,kernel_size3,stride1,padding1,groupsc
self.conv3nn.Conv2d(c2,c2,kernel_size1,stride
self.Aptnn.AdaptiveAvgPool2d(
self.onec2 self.twoc2 self.conv4_gobalnn.Conv2d(c2,1,kernel_size1,stride
forgroup_idinrange(0,
:self.interactnn.Conv2d(c2//4,c2//4,1,1,)defforward(self,x):x1,x2x global_conv1self.conv1(x
bn_xself.bn(global_conv
weight_1self.sigomid(bn_x)global_conv2self.conv2(x
bn_x2self.bn(global_conv
weight_2self.sigomid(bn_x
X_GOBALglobal_conv1global_conv2 x_conv4self.conv4_gobal(X_GOBAL)X_4_sigmoidself.sigomid(x_conv
X_X_4_sigmoid*X_GOBAL X_X_.chunk(4,dim
out[]forgroup_idinrange(0,
:out_1self.interact(X_[group_id])N,C,H,Wout_
size()x_1_mapout_
reshape(N,1,-
mean_1x_1_map.mean(dim2,keepdimTrue)x_1_avx_1_map/mean_1 x_2_2F.softmax(x_1_av,dim-
x1x_2_
reshape(N,C,H,W)x1X_[group_id]*x1 out.append(x
outtorch.cat([out[0],out[1],out[2],out[3]],dim
N,C,H,Wout.size()x_add_1out.reshape(N,self.group_num,-
N,C,H,WX_GOBAL.size()x_shape_1X_GOBAL.reshape(N,self.group_num,-
mean_1x_shape_
mean(dim2,keepdimTrue)std_1x_shape_
std(dim2,keepdimTrue)x_guiyi(x_add_1-mean_
/(std_1self.eps)x_guiyi_1x_guiyi.reshape(N,C,H,W)x_gui(x_guiyi_1*self.gammaself.beta)weight_x3self.Apt(X_GOBAL)reweightsself.sigomid(weight_x
x_up_1reweightsweight_1 x_low_1reweightsweight_1 x_up_2reweightsweight_2 x_low_2reweightsweight_2 x_upx_up_1*X_GOBALx_up_2*X_GOBAL x_lowx_low_1*X_GOBALx_low_2*X_GOBAL x11_up_dwcself.dwconv(x_low)x11_up_dwcself.conv3(x11_up_dwc)x_soself.gate_genator(x_low)x11_up_dwcx11_up_dwc*x_so x22_low_pwself.conv4(x_up)xLx11_up_dwcx22_low_pw xLxLx_guireturnxLYOLO26引入代码在根目录下的ultralytics/nn/目录新建一个featureFusion目录然后新建一个以EFC为文件名的py文件 把代码拷贝进去。
importtorchimporttorch.nnasnnimporttorch.nn.functionalasFclassEFC(nn.Module):def__init__(self,c1,c
:super().__init__()self.conv1nn.Conv2d(c1,c2,kernel_size1,stride
self.conv2nn.Conv2d(c2,c2,kernel_size1,stride
self.conv4nn.Conv2d(c2,c2,kernel_size1,stride
self.bnnn.BatchNorm2d(c
self.sigomidnn.Sigmoid()self.group_num16self.eps1e-10self.gammann.Parameter(torch.randn(c2,1,
)self.betann.Parameter(torch.zeros(c2,1,
)self.gate_genatornn.Sequential(nn.AdaptiveAvgPool2d((1,
),nn.Conv2d(c2,c2,1,
,nn.ReLU(True),nn.Softmax(dim
,)self.dwconvnn.Conv2d(c2,c2,kernel_size3,stride1,padding1,groupsc
self.conv3nn.Conv2d(c2,c2,kernel_size1,stride
self.Aptnn.AdaptiveAvgPool2d(
self.onec2 self.twoc2 self.conv4_gobalnn.Conv2d(c2,1,kernel_size1,stride
forgroup_idinrange(0,
:self.interactnn.Conv2d(c2//4,c2//4,1,1,)defforward(self,x):x1,x2x global_conv1self.conv1(x
bn_xself.bn(global_conv
weight_1self.sigomid(bn_x)global_conv2self.conv2(x
bn_x2self.bn(global_conv
weight_2self.sigomid(bn_x
X_GOBALglobal_conv1global_conv2 x_conv4self.conv4_gobal(X_GOBAL)X_4_sigmoidself.sigomid(x_conv
X_X_4_sigmoid*X_GOBAL X_X_.chunk(4,dim
out[]forgroup_idinrange(0,
:out_1self.interact(X_[group_id])N,C,H,Wout_
size()x_1_mapout_
reshape(N,1,-
mean_1x_1_map.mean(dim2,keepdimTrue)x_1_avx_1_map/mean_1 x_2_2F.softmax(x_1_av,dim
x1x_2_
reshape(N,C,H,W)x1X_[group_id]*x1 out.append(x
outtorch.cat([out[0],out[1],out[2],out[3]],dim
N,C,H,Wout.size()x_add_1out.reshape(N,self.group_num,-
N,C,H,WX_GOBAL.size()x_shape_1X_GOBAL.reshape(N,self.group_num,-
mean_1x_shape_
mean(dim2,keepdimTrue)std_1x_shape_
std(dim2,keepdimTrue)x_guiyi(x_add_1-mean_
/(std_1self.eps)x_guiyi_1x_guiyi.reshape(N,C,H,W)x_gui(x_guiyi_1*self.gammaself.beta)weight_x3self.Apt(X_GOBAL)reweightsself.sigomid(weight_x
x_up_1reweightsweight_1 x_low_1reweightsweight_1 x_up_2reweightsweight_2 x_low_2reweightsweight_2 x_upx_up_1*X_GOBALx_up_2*X_GOBAL x_lowx_low_1*X_GOBALx_low_2*X_GOBAL x11_up_dwcself.dwconv(x_low)x11_up_dwcself.conv3(x11_up_dwc)x_soself.gate_genator(x_low)x11_up_dwcx11_up_dwc*x_so x22_low_pwself.conv4(x_up)xLx11_up_dwcx22_low_pw xLxLx_guireturnxLtasks注册在ultralytics/nn/tasks.py中进行如下操作步骤1:fromultralytics.nn.featureFusion.EFCimportEFC步骤2修改def parse_model(d, ch, verboseTrue):elifmisEFC:c1,c2ch[f[0]],args[0]c2make_divisible(min(c2,max_channels)*width,
args[c1,c2]配置yolo26-EFC.yamlultralytics/cfg/models/26/yolo26-EFC.yaml# Ultralytics AGPL-
0 License - https://ultralytics.com/license# Ultralytics YOLO26 object detection model with P3/8 - P5/32 outputs# Model docs: https://docs.ultralytics.com/models/yolo26# Task docs: https://docs.ultralytics.com/tasks/detect# Parametersnc:80# number of classesend2end:True# whether to use end-to-end modereg_max:1# DFL binsscales:# model compound scaling constants, i.e. modelyolo26n.yaml will call yolo
yaml with scale n# [depth, width, max_channels]n:[
50,
25,1024]# summary: 260 layers, 2,572,280 parameters, 2,572,280 gradients,
1 GFLOPss:[
50,
50,1024]# summary: 260 layers, 10,009,784 parameters, 10,009,784 gradients,
2
8 GFLOPsm:[
50,
00,512]# summary: 280 layers, 21,896,248 parameters, 21,896,248 gradients,
7
4 GFLOPsl:[
00,
00,512]# summary: 392 layers, 26,299,704 parameters, 26,299,704 gradients,
9
8 GFLOPsx:[
00,
50,512]# summary: 392 layers, 58,993,368 parameters, 58,993,368 gradients,
2