YOLOv8优化:注意力系列篇 | Involution内卷助力检测-灵析社区

神机妙算

🚀🚀🚀本文改进:Involution,引入到YOLOv8,多种实现方式

🚀🚀🚀NAM在不同检测领域中应用广泛

🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK


1.Involution原理介绍


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

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

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

内卷的优点:

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

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



重新考虑了视觉任务标准卷积的固有原理,特别是与空间无关和特定于通道的方法。取而代之的是,我们通过反转前述的卷积设计原理(称为卷积)提出了一种用于深度神经网络的新颖atomic操作。

2.Involution加入YOLOv8

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


###################### Involution####     start    ###############################
import torch
import torch.nn as nn
from torch.nn import functional as F
 
 
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    ###############################

2.2 修改tasks.py

首先NAMAttention进行注册


from ultralytics.nn.attention.attention import *

函数def parse_model(d, ch, verbose=True): # model_dict, input_channels(3)进行修改


        if m in (Classify, Conv, ConvTranspose, GhostConv, Bottleneck, GhostBottleneck, SPP, SPPF, DWConv, Focus,
                 BottleneckCSP, C1, C2, C2f, C3, C3TR, C3Ghost, nn.ConvTranspose2d, DWConvTranspose2d, C3x, RepC3,
                 Involution):
            c1, c2 = ch[f], args[0]

2.3 yaml实现

2.3.1 yolov8_Involution.yaml

加入backbone SPPF后

​​​


# Ultralytics YOLO 🚀, AGPL-3.0 license
# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect
 
# Parameters
nc: 80  # number of classes
scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'
  # [depth, width, max_channels]
  n: [0.33, 0.25, 1024]  # YOLOv8n summary: 225 layers,  3157200 parameters,  3157184 gradients,   8.9 GFLOPs
  s: [0.33, 0.50, 1024]  # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients,  28.8 GFLOPs
  m: [0.67, 0.75, 768]   # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPs
  l: [1.00, 1.00, 512]   # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs
  x: [1.00, 1.25, 512]   # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs
 
# YOLOv8.0n backbone
backbone:
  # [from, repeats, module, args]
  - [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2
  - [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4
  - [-1, 3, C2f, [128, True]]
  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8
  - [-1, 6, C2f, [256, True]]
  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16
  - [-1, 6, C2f, [512, True]]
  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32
  - [-1, 3, C2f, [1024, True]]
  - [-1, 1, SPPF, [1024, 5]]  # 9
 
# YOLOv8.0n head
head:
  - [-1, 1, Involution, [1024, 1, 1]]
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 6], 1, Concat, [1]]  # cat backbone P4
  - [-1, 3, C2f, [512]]  # 13
 
  - [-1, 1, nn.Upsample, [None, 2, 'nearest']]
  - [[-1, 4], 1, Concat, [1]]  # cat backbone P3
  - [-1, 3, C2f, [256]]  # 16 (P3/8-small)
 
  - [-1, 1, Conv, [256, 3, 2]]
  - [[-1, 13], 1, Concat, [1]]  # cat head P4
  - [-1, 3, C2f, [512]]  # 19 (P4/16-medium)
 
  - [-1, 1, Conv, [512, 3, 2]]
  - [[-1, 10], 1, Concat, [1]]  # cat head P5
  - [[-1, 10], 1, Concat, [1]]  # cat head P5
  - [-1, 3, C2f, [1024]]  # 22 (P5/32-large)
 
  - [[16, 19, 22], 1, Detect, [nc]]  # Detect(P3, P4, P5)


阅读量:649

点赞量:0

收藏量:0