YOLOv8目标检测创新改进与实战案例专栏
专栏目录: YOLOv8有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例
专栏链接: YOLOv8基础解析+创新改进+实战案例
介绍
摘要
我们提出了焦点调制网络(简称FocalNets),在其中完全用焦点调制模块替代了自注意力(SA),用于建模视觉中的标记交互。焦点调制由三个组件组成:(i)焦点上下文化,通过一系列深度卷积层实现,从短距离到长距离编码视觉上下文,(ii)门控聚合,选择性地将上下文聚合到每个查询标记的调制器中,以及(iii)逐元素仿射变换,将调制器注入查询标记。大量实验表明,FocalNets展现了非凡的可解释性(图1),并在图像分类、目标检测和分割任务中以类似的计算成本超越了最先进的SA模型(例如,Swin和Focal Transformers)。具体来说,FocalNets的小型和基础版本在ImageNet-1K上分别达到了82.3%和83.9%的top-1准确率。在ImageNet-22K上以224×224分辨率进行预训练后,微调到224×224和384×384分辨率时分别达到了86.5%和87.3%的top-1准确率。在使用Mask R-CNN进行目标检测时,FocalNet基础版本以1×训练计划超越了Swin对照组2.1个点,并且已经超过了使用3×训练计划的Swin(49.0对48.5)。在使用UPerNet进行语义分割时,FocalNet基础版本在单尺度下超越了Swin 2.4个点,并且在多尺度下也超过了Swin(50.5对49.7)。使用大型FocalNet和Mask2former,我们在ADE20K语义分割任务中达到了58.5的mIoU,并在COCO全景分割任务中达到了57.9的PQ。使用巨型FocalNet和DINO,我们在COCO minival和test-dev上分别达到了64.3和64.4的mAP,超越了诸如Swinv2-G和BEIT-3等基于注意力的大型模型。这些令人鼓舞的结果表明,焦点调制可能正是我们在视觉领域所需要的。
文章链接
论文地址:论文地址
代码地址:代码地址
基本原理
Focal Modulation机制旨在结合CNNs和自注意力机制的优点,通过在不同的空间尺度上聚焦(Focal)和调制(Modulation)特征来增强模型的表达能力。具体来说,Focal Modulation包含以下几个关键组件:
局部特征聚焦(Local Focalization):
- 通过聚焦机制在局部区域内提取特征,类似于卷积操作。这有助于捕捉局部模式和细节。
全局信息调制(Global Modulation):
- 在全局范围内对特征进行调制,类似于自注意力机制。这有助于整合全局上下文信息,使模型能够理解更广泛的特征关系。
多尺度处理(Multi-Scale Processing):
- 通过在不同尺度上进行特征提取和调制,Focal Modulation能够同时处理图像中的细节和整体结构。这种多尺度特性使得模型在处理复杂场景时更具鲁棒性。
具体实现
Focal Modulation的具体实现可以通过以下步骤进行:
特征提取:
- 使用卷积层或其他局部运算层提取初始特征。
局部聚焦:
- 对提取的特征进行局部聚焦操作,可以采用池化(Pooling)或注意力机制来实现。
全局调制:
- 利用全局上下文信息对局部聚焦后的特征进行调制。这可以通过全局注意力层或其他全局运算层实现。
多尺度融合:
- 将不同尺度上的特征进行融合,通过跳跃连接(Skip Connections)或金字塔结构(Pyramid Structure)来整合多尺度信息。
核心代码
class FocalModulation(nn.Module):
""" 焦点调制模块
Args:
dim (int): 输入通道数。
proj_drop (float, optional): 输出的dropout比率。默认值:0.0
focal_level (int): 焦点层级的数量
focal_window (int): 焦点层级1的焦点窗口大小
focal_factor (int, default=2): 增加焦点窗口的步长
use_postln (bool, default=False): 是否使用后调制层归一化
"""
def __init__(self, dim, proj_drop=0., focal_level=2, focal_window=7, focal_factor=2, use_postln=False):
super().__init__()
self.dim = dim
# 焦点调制模块的特定参数
self.focal_level = focal_level
self.focal_window = focal_window
self.focal_factor = focal_factor
self.use_postln = use_postln
# 线性层,输出维度为2*dim+(焦点层级数+1)
self.f = nn.Linear(dim, 2*dim+(self.focal_level+1), bias=True)
# 1x1卷积层,输入和输出通道数均为dim
self.h = nn.Conv2d(dim, dim, kernel_size=1, stride=1, padding=0, groups=1, bias=True)
# GELU激活函数
self.act = nn.GELU()
# 线性层,输入和输出维度均为dim
self.proj = nn.Linear(dim, dim)
# Dropout层,使用给定的丢弃比率
self.proj_drop = nn.Dropout(proj_drop)
# 存储焦点层的列表
self.focal_layers = nn.ModuleList()
if self.use_postln:
# 如果使用后调制层归一化,定义层归一化层
self.ln = nn.LayerNorm(dim)
# 构建每个焦点层
for k in range(self.focal_level):
# 根据层级计算卷积核大小
kernel_size = self.focal_factor*k + self.focal_window
self.focal_layers.append(
nn.Sequential(
nn.Conv2d(dim, dim, kernel_size=kernel_size, stride=1, groups=dim,
padding=kernel_size//2, bias=False),
nn.GELU(),
)
)
task与yaml配置
详见: https://blog.csdn.net/shangyanaf/article/details/140456375