专栏介绍:YOLOv9改进系列 | 包含深度学习最新创新,主力高效涨点!!!
一、论文简介
最大池化或跨步卷积等下采样操作在卷积神经网络(CNNs)中广泛使用,以聚合局部特征,扩大感受野,并最大限度地减少计算开销。然而,对于语义分割任务,在局部邻域上汇集特征可能会导致重要空间信息的丢失,这有利于像素预测。为了解决这个问题,我们引入了一种简单而有效的池化操作,称为基于Haar小波的下采样(HWD)模块。该模块可以很容易地集成到细胞神经网络中,以提高语义分割模型的性能。HWD的核心思想是应用Haar小波变换来降低特征图的空间分辨率,同时保留尽可能多的信息。此外,为了研究HWD的好处,我们提出了一种新的度量,称为特征熵指数(FEI),它测量下采样后的信息不确定性程度。
适用检测目标: 适用下采样改进
二、HWD模块详解
论文地址: https://www.sciencedirect.com/science/article/abs/pii/S0031320323005174
2.1 模块简介
HWD的主要思想: 应用Haar小波变换来降低特征图的空间分辨率,同时保留尽可能多的信息。
总结: HWD是一种下采样模型,应用了小波变换的方法。
HWD模块的原理图
三、HWD模块使用教程
3.1 HWD模块的代码
class HWD(nn.Module):
def __init__(self, in_ch, out_ch):
super(HWD, self).__init__()
from pytorch_wavelets import DWTForward
self.wt = DWTForward(J=1, mode='zero', wave='haar')
self.conv = Conv(in_ch * 4, out_ch, 1, 1)
def forward(self, x):
yL, yH = self.wt(x)
y_HL = yH[0][:, :, 0, ::]
y_LH = yH[0][:, :, 1, ::]
y_HH = yH[0][:, :, 2, ::]
x = torch.cat([yL, y_HL, y_LH, y_HH], dim=1)
x = self.conv(x)
return x
3.2 在YOlO v9中的添加教程
阅读YOLOv9添加模块教程或使用下文操作
1. 将YOLOv9工程中models下common.py文件中增加模块的代码。
2. 将YOLOv9工程中models下yolo.py文件中的第718行(可能因版本变化而变化)增加以下代码。
elif m in (HWD,):
args = [ch[f], ch[f]]
3.3 运行配置文件
# YOLOv9
# Powered bu https://blog.csdn.net/StopAndGoyyy
# parameters
nc: 80 # number of classes
#depth_multiple: 0.33 # model depth multiple
depth_multiple: 1 # model depth multiple
#width_multiple: 0.25 # layer channel multiple
width_multiple: 1 # layer channel multiple
#activation: nn.LeakyReLU(0.1)
#activation: nn.ReLU()
# anchors
anchors: 3
# YOLOv9 backbone
backbone:
[
[-1, 1, Silence, []],
# conv down
[-1, 1, Conv, [64, 3, 2]], # 1-P1/2
# conv down
[-1, 1, Conv, [128, 3, 2]], # 2-P2/4
# elan-1 block
[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 3
# avg-conv down
[-1, 1, ADown, [256]], # 4-P3/8
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 5
# avg-conv down
[-1, 1, ADown, [512]], # 6-P4/16
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 7
# avg-conv down
[-1, 1, HWD, []], # 8-P5/32
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 9
]
# YOLOv9 head
head:
[
# elan-spp block
[-1, 1, SPPELAN, [512, 256]], # 10
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 7], 1, Concat, [1]], # cat backbone P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 13
# up-concat merge
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 5], 1, Concat, [1]], # cat backbone P3
# elan-2 block
[-1, 1, RepNCSPELAN4, [256, 256, 128, 1]], # 16 (P3/8-small)
# avg-conv-down merge
[-1, 1, ADown, [256]],
[[-1, 13], 1, Concat, [1]], # cat head P4
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 19 (P4/16-medium)
# avg-conv-down merge
[-1, 1, ADown, [512]],
[[-1, 10], 1, Concat, [1]], # cat head P5
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 22 (P5/32-large)
# multi-level reversible auxiliary branch
# routing
[5, 1, CBLinear, [[256]]], # 23
[7, 1, CBLinear, [[256, 512]]], # 24
[9, 1, CBLinear, [[256, 512, 512]]], # 25
# conv down
[0, 1, Conv, [64, 3, 2]], # 26-P1/2
# conv down
[-1, 1, Conv, [128, 3, 2]], # 27-P2/4
# elan-1 block
[-1, 1, RepNCSPELAN4, [256, 128, 64, 1]], # 28
# avg-conv down fuse
[-1, 1, ADown, [256]], # 29-P3/8
[[23, 24, 25, -1], 1, CBFuse, [[0, 0, 0]]], # 30
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 256, 128, 1]], # 31
# avg-conv down fuse
[-1, 1, ADown, [512]], # 32-P4/16
[[24, 25, -1], 1, CBFuse, [[1, 1]]], # 33
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 34
# avg-conv down fuse
[-1, 1, ADown, [512]], # 35-P5/32
[[25, -1], 1, CBFuse, [[2]]], # 36
# elan-2 block
[-1, 1, RepNCSPELAN4, [512, 512, 256, 1]], # 37
# detection head
# detect
[[31, 34, 37, 16, 19, 22], 1, DualDDetect, [nc]], # DualDDetect(A3, A4, A5, P3, P4, P5)
]
3.4 训练过程
欢迎关注!