前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >YOLOv8改进:HIC-YOLOv8复现魔改HIC-YOLOv5,助力小目标检测(Small Object Detection)

YOLOv8改进:HIC-YOLOv8复现魔改HIC-YOLOv5,助力小目标检测(Small Object Detection)

原创
作者头像
AI小怪兽
发布于 2023-11-06 00:41:14
发布于 2023-11-06 00:41:14
5K00
代码可运行
举报
文章被收录于专栏:YOLO大作战YOLO大作战
运行总次数:0
代码可运行

💡💡💡本文独家改进:改进点:1)backbone加入CBAM;2)backbone、neck连接处加入involution注意力;3)添加一个针对小物体的额外预测头,提升小目标检测性能;

HIC-YOLOv8 | 亲测在多个数据集能够实现大幅涨点,尤其在VisDrone-2019涨点显著, VisDrone-2019-DET 数据集上将 mAP95 提高了 6.42%,将 mAP@0.5 提高了 9.38%。 ​

1.原理介绍

摘要:小目标检测一直是目标检测领域的一个具有挑战性的问题。 已经有一些工作提出了对该任务的改进,例如添加几个注意力块或改变特征融合网络的整体结构。 然而,这些模型的计算成本很大,这使得部署实时目标检测系统不可行,同时还有改进的空间。 为此,提出了一种改进的YOLOv5模型:HICYOLOv5来解决上述问题。 首先,添加一个针对小物体的额外预测头,以提供更高分辨率的特征图,以实现更好的预测。 其次,在backbone和neck之间采用involution block来增加特征图的通道信息。 此外,在主干网末端应用了一种名为 CBAM 的注意力机制,与之前的工作相比,不仅降低了计算成本,而且还强调了通道和空间域中的重要信息。 我们的结果表明,HIC-YOLOv5 在 VisDrone-2019-DET 数据集上将 mAP@[.5:.95] 提高了 6.42%,将 mAP@0.5 提高了 9.38%。

1.1 Convolutional Block Attention Module(CBAM)介绍

论文地址:https://arxiv.org/pdf/1807.06521.pdf

摘要:我们提出了卷积块注意力模块(CBAM),这是一种用于前馈卷积神经网络的简单而有效的注意力模块。 给定中间特征图,我们的模块沿着两个独立的维度(通道和空间)顺序推断注意力图,然后将注意力图乘以输入特征图以进行自适应特征细化。 由于 CBAM 是一个轻量级通用模块,因此它可以无缝集成到任何 CNN 架构中,且开销可以忽略不计,并且可以与基础 CNN 一起进行端到端训练。 我们通过在 ImageNet-1K、MS COCO 检测和 VOC 2007 检测数据集上进行大量实验来验证我们的 CBAM。我们的实验显示各种模型在分类和检测性能方面的持续改进,证明了 CBAM 的广泛适用性。 代码和模型将公开。

上图可以看到,CBAM包含CAM(Channel Attention Module)和SAM(Spartial Attention Module)两个子模块,分别进行通道和空间上的Attention。这样不只能够节约参数和计算力,并且保证了其能够做为即插即用的模块集成到现有的网络架构中去。

1.2 Involution原理介绍

论文链接:https://arxiv.org/abs/2103.06255

作者认为卷积操作的两个特征虽然也有一定的优势,但同样也有缺点。所以提出了Involution,Involution所拥有的特征正好和卷积相对称,即 spatial-specific and channel-agnostic

那就是通道无关和特定于空间。和卷积一样,内卷也有内卷核(involution kernels)。内卷核在空间范围上是不同的,但在通道之间共享。看到这里就有一定的画面感了。

内卷的优点:

1.可以在更大的空间范围中总结上下文信息,从而克服long-range interaction(本来的卷积操作只能在特定的小空间如3x3中集合空间信息)

2.内卷可以将权重自适应地分配到不同的位置,从而对空间域中信息量最大的视觉元素进行优先级排序。(本来的卷积在空间的每一个地方都是用到同一个卷积核,用的同一套权重)

1.3 多头检测器

在进行目标检测时,小目标会出现漏检或检测效果不佳等问题。YOLOv8有3个检测头,能够多尺度对目标进行检测,但对微小目标检测可能存在检测能力不佳的现象,因此添加一个微小物体的检测头,能够大量涨点,map提升明显;

​2.HIC-YOLOv8复现

2.1加入ultralytics/nn/attention/attention.py

核心代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
###################### CBAM     ####     start    ###############################
 
import torch
import torch.nn as nn
from torch.nn import functional as F
 
class ChannelAttention(nn.Module):
    # Channel-attention module https://github.com/open-mmlab/mmdetection/tree/v3.0.0rc1/configs/rtmdet
    def __init__(self, channels: int) -> None:
        super().__init__()
        self.pool = nn.AdaptiveAvgPool2d(1)
        self.fc = nn.Conv2d(channels, channels, 1, 1, 0, bias=True)
        self.act = nn.Sigmoid()
 
    def forward(self, x: torch.Tensor) -> torch.Tensor:
        return x * self.act(self.fc(self.pool(x)))
 
 
class SpatialAttention(nn.Module):
    # Spatial-attention module
    def __init__(self, kernel_size=7):
        super().__init__()
        assert kernel_size in (3, 7), 'kernel size must be 3 or 7'
        padding = 3 if kernel_size == 7 else 1
        self.cv1 = nn.Conv2d(2, 1, kernel_size, padding=padding, bias=False)
        self.act = nn.Sigmoid()
 
    def forward(self, x):
        return x * self.act(self.cv1(torch.cat([torch.mean(x, 1, keepdim=True), torch.max(x, 1, keepdim=True)[0]], 1)))
 
 
class CBAM(nn.Module):
    # Convolutional Block Attention Module
    def __init__(self, c1, kernel_size=7):  # ch_in, kernels
        super().__init__()
        self.channel_attention = ChannelAttention(c1)
        self.spatial_attention = SpatialAttention(kernel_size)
 
    def forward(self, x):
        return self.spatial_attention(self.channel_attention(x))
 
###################### CBAM     ####     end    ###############################
###################### Involution####     start    ###############################

 
from ultralytics.nn.modules import  Conv
 
class Involution(nn.Module):
 
    def __init__(self, c1, c2, kernel_size, stride):
        super(Involution, self).__init__()
        self.kernel_size = kernel_size
        self.stride = stride
        self.c1 = c1
        reduction_ratio = 4
        self.group_channels = 16
        self.groups = self.c1 // self.group_channels
        self.conv1 = Conv(
            c1, c1 // reduction_ratio, 1)
        self.conv2 = Conv(
            c1 // reduction_ratio,
            kernel_size ** 2 * self.groups,
            1, 1)
 
        if stride > 1:
            self.avgpool = nn.AvgPool2d(stride, stride)
        self.unfold = nn.Unfold(kernel_size, 1, (kernel_size - 1) // 2, stride)
 
    def forward(self, x):
        weight = self.conv2(self.conv1(x if self.stride == 1 else self.avgpool(x)))
        b, c, h, w = weight.shape
        weight = weight.view(b, self.groups, self.kernel_size ** 2, h, w).unsqueeze(2)
        out = self.unfold(x).view(b, self.groups, self.group_channels, self.kernel_size ** 2, h, w)
        out = (weight * out).sum(dim=3).view(b, self.c1, h, w)
 
        return out
###################### Involution  ####     end    ###############################

详见:

https://blog.csdn.net/m0_63774211/article/details/134132387

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验