基于Yolov7的目标检测改进

一、在网络中引入DCNv3

1、首先要安装DCNv3

参考:https://blog.csdn.net/zycnice/article/details/130783757

2、复现yolov7源码

https://github.com/WongKinYiu/yolov7
这里还要安装MMCV和MMdetection

3、将intern_image.py移至yolov7项目中的nets文件夹下。

比如在backbone.py中引入创新在下面加入代码打印计算量和计算参数

if __name__ == '__main__':
    from torchinfo import summary

    x = torch.randn(2, 3, 320, 320)
    x = x.cuda()

    model = Backbone(transition_channels = 32, block_channels = 32, n = 4, phi = 'l', pretrained = False)
    #model = Backbone_inter_image(transition_channels=32, block_channels=32, n=4, phi='l', pretrained=False)
    model.cuda()
    summary(model, (2, 3, 640, 640))

    feat1, feat2, feat3 = model(x)
    print(feat1.shape, feat2.shape, feat3.shape)

在这里插入图片描述

4、将intern_image封装好,这是在intern_image.py里加的一个类

class Internimage(nn.Module):
    def __init__(self,
                 channels,
                 depth,
                 groups,
                 downsample=True,
                 af='GELU',
                 ): # for InternImage-H/G
        super().__init__()
        self.itern_image = InternImageBlock(core_op = 'DCNv3',  # DCNv3
                        channels = channels,
                        depth = depth,  # [4, 4, 18, 4]
                        groups = groups,
                        downsample = downsample,
                        mlp_ratio = 4.,
                        drop = 0.,
                        drop_path=0.,
                        act_layer = af,
                        norm_layer = 'LN',
                        post_norm = False,
                        offset_scale = 1.0,
                        layer_scale = 1.0,
                        with_cp = False,
                        dw_kernel_size = None,  # for InternImage-H/G
                        post_norm_block_ids = None,  # for InternImage-H/G
                        res_post_norm = False,  # for InternImage-H/G
                        center_feature_scale = False) # for InternImage-H/G
    def forward(self, x, return_wo_downsample=False):
        x = x.permute(0, 2, 3, 1) #原始代码没有这一行,这是为了方便放入YOLO中,再转换维度
        x = self.itern_image(x)
        x = x.permute(0, 3, 1, 2) #原始代码没有这一行,这是为了方便放入YOLO中,再转换维度
        return x

到时候直接在YOLO的网络部分调用这一个类就好了。大部分参数都是不用改的,所以调用的时候就保留上面5个参数,避免代码太长,可读性不好。因为yolo里大部分都是卷积操作,所以这里还是使用了permute函数转换维度,使用inrern_image layer后再转换回去。(因为是在ViT的基础上改进的DCNV3)

5、在yolo的网络代码中加入或替换Internimage,比如

self.stem = nn.Sequential(
            Conv(3, transition_channels, 3, 1),  # 640 * 640 * 32
            Internimage(channels=32, depth=2, groups=4, downsample=False, af='GELU'),
            Conv(transition_channels, transition_channels * 2, 3, 2),  # 320 * 320 * 64
            Conv(transition_channels * 2, transition_channels * 2, 3, 1),  # 320 * 320 * 64
        )

6、计算量比较:

 当输入尺寸是(2, 3, 640, 640)时,

在backbone某部分单独加入一个intern_image层后的计算量,这是按照Internimage原始tiny版本的配置来的,实际加入的话depth和group不用加入这么多
网络改进参数量
yolov7原始26,694,432
stem中的第一层CBS后面加入Internimage:depth=4, groups=4,GELU26,811,392
dark2中的第一层CBS后面加入Internimage:depth=4, groups=4,GELU28,142,720
dark3中的第一层CBS后面加入Internimage:depth=4, groups=8,GELU32,433,632
dark4中的第一层CBS后面加入Internimage:depth=18, groups=16,GELU129,507,296
dark5中的第一层CBS后面加入Internimage:depth=4, groups=32,GELU72,284,320
验证groups对参数量的影响
网络改进参数量
yolov7原始26,694,432
stem中的第一层CBS后面加入Internimage:depth=4, groups=4,GELU26,811,392
stem中的第一层CBS后面加入Internimage:depth=4, groups=8,GELU26,839,904
dark4中的第一层CBS后面加入Internimage:depth=18, groups=2,GELU122,526,392
dark4中的第一层CBS后面加入Internimage:depth=18, groups=8,GELU125,518,208
dark4中的第一层CBS后面加入Internimage:depth=18, groups=16,GELU129,507,296
当depth为1时,每一层单独增加的参数
网络改进参数量
yolov7原始26,694,432
stem中的第一层CBS后面加入Internimage:depth=1, groups=4,GELU26,730,896
dark2中的第一层CBS后面加入Internimage:depth=1, groups=4,GELU27,056,888
dark3中的第一层CBS后面加入Internimage:depth=1, groups=8,GELU28,130,000
dark4中的第一层CBS后面加入Internimage:depth=1, groups=16,GELU32,186,576
dark5中的第一层CBS后面加入Internimage:depth=1, groups=32,GELU38,093,440

1、从上面的数据能看出group越大,计算量越大,随着网络的深度增加,group应该逐渐增加。
随着网络深度的增加,通道数增加了,那么计算量也会增加。

2、在更深的层中,Internimage导致参数量增加的过多了,应该谨慎使用。

3、为什么Internimage源码在第三层(也就是yolo中的dark4)将depth设置成18,这肯定有深意,经过了大量实验佐证的,所以还是不要瞎设置。

4、此外将depth设置成0几乎不引入参数,但还是有点,如果GPU资源足够好的话,还可以封装的更好。

7、实际的改进:

1、先试一下所有五块都引入1层Internimage layer

class Backbone_inter_image(nn.Module):
    '''
    这是改进的backbone网络,结合了intern_image layer,这里的主要操作是dcnv3。如果使用了这个函数,就要把nets.yolo.py中YoloBody的self.backbone换成Backbone_inter_image
    即将原始的Backbone注释掉或删掉。
    初始的不添加任何改进的网络名叫Backbone,在上面。
    '''
    def __init__(self, transition_channels, block_channels, n, phi, pretrained = False):  # 32, 32, 4, l, True
        super().__init__()
        # -----------------------------------------------#
        #   输入图片是640, 640, 3
        # -----------------------------------------------#
        ids = {
            'l': [-1, -3, -5, -6],
            'x': [-1, -3, -5, -7, -8],
        }[phi]
        depths = [1, 1, 1, 1, 1]
        groups_nums = [4, 4, 8, 16, 32]
        AF = ['GELU', 'GELU', 'GELU', 'GELU', 'GELU']

        self.stem = nn.Sequential(
            Conv(3, transition_channels, 3, 1),  # 640 * 640 * 32
            Internimage(channels=transition_channels, depth=depths[0], groups=groups_nums[0], downsample=False, af='GELU'),
            Conv(transition_channels, transition_channels * 2, 3, 2),  # 320 * 320 * 64
            Conv(transition_channels * 2, transition_channels * 2, 3, 1),  # 320 * 320 * 64
        )
        self.dark2 = nn.Sequential(
            Conv(transition_channels * 2, transition_channels * 4, 3, 2),  # 160 * 160 * 128
            Internimage(channels = transition_channels * 4, depth = depths[1], groups = groups_nums[1], downsample = False, af = 'GELU'),
            Multi_Concat_Block(transition_channels * 4, block_channels * 2, transition_channels * 8, n = n, ids = ids),
            # 160 * 160 * 256
        )
        self.dark3 = nn.Sequential(
            Transition_Block(transition_channels * 8, transition_channels * 4),  # 80 * 80 * 256
            Internimage(channels = transition_channels * 8, depth = depths[2], groups = groups_nums[2], downsample = False, af = 'GELU'),
            Multi_Concat_Block(transition_channels * 8, block_channels * 4, transition_channels * 16, n = n, ids = ids),
            # 80 * 80 * 512
        )
        self.dark4 = nn.Sequential(
            Transition_Block(transition_channels * 16, transition_channels * 8),  # 40 * 40 * 512
            Internimage(channels = transition_channels * 16, depth = depths[3], groups =groups_nums[3], downsample = False, af = 'GELU'),
            Multi_Concat_Block(transition_channels * 16, block_channels * 8, transition_channels * 32, n = n,
                               ids = ids),  # 40 * 40 * 1024
        )
        self.dark5 = nn.Sequential(
            Transition_Block(transition_channels * 32, transition_channels * 16),  # 20 * 20 * 1024
            Internimage(channels = transition_channels * 32, depth = depths[4], groups = groups_nums[4], downsample = False, af = 'GELU'),
            Multi_Concat_Block(transition_channels * 32, block_channels * 8, transition_channels * 32, n = n,
                               ids = ids),  # 20 * 20 * 1024
        )
网络修改参数量
yolov7原始26,694,432
改进后45,634,560

参数量几乎增加了1倍。

8、预训练模型

预训练模型主要是加载主干网络的,就是backbone部分,当然也有全部,包括了头(head)部分。在训练中有一个参数,
当它是True的时候就会将主干冻结,不会继续训练,当在主干加入了创新点就要变为False

二、校正卷积-SCC(针对小目标)

博客参考:YOLOv5、v7改进之二十七:解决小目标问题——校正卷积取代特征提取网络中的常规卷积_人工智能算法研究院的博客-CSDN博客

论文:https://mftp.mmcheng.net/Papers/20cvprSCNet.pdf

解决问题:小目标由于携带信息少导致特征表达能力较弱,经过多层次的卷积操作后能提取到的特征较少,因此检测困难。利用自校正卷积取代特征提取网络中的常规卷积,以扩展感受野丰富输出,进而强化对弱特征的提取能力。

改进的具体操作:去代替CBS或CBM这些普通卷积。

三、情景聚合模块 -CABlock (针对小目标)

参考博客: YOLOv8/YOLOv7/YOLOv5/YOLOv4/Faster-rcnn系列算法改进【NO.69】针对遥感图像目标检测中的小目标进行改进CATnet(ContextAggregation模块)_人工智能算法研究院的博客-CSDN博客

论文:https://arxiv.org/pdf/2111.11057.pdf

提出了一种新的上下文聚合网络(CATNet)来改善特征提取过程。所提出的模型利用三个轻量级的即插即用模块,分别是密集特征金字塔网络(DenseFPN)、空间上下文金字塔(SCP)和分层感兴趣区提取器(HRoIE)

博主在C3后加了三个这个

四、添加小目标检测层

参考:目标检测算法——YOLOv5改进|增加小目标检测层_加勒比海带66的博客-CSDN博客

YOLOv8/YOLOv7/YOLOv5系列算法改进【NO.6】增加小目标检测层,提高对小目标的检测效果_yolov8 小目标_人工智能算法研究院的博客-CSDN博客

五、数据增强

DOTA数据集

参考:很详细DOTA:用于航拍图像目标检测的大规模数据集_航拍图像船只数据_Change_ZH的博客-CSDN博客

dota上的检测结果 技术分享 | 遥感影像中的旋转目标检测系列(一)_遥感图像 目标检测_AI Earth地球科学云平台的博客-CSDN博客

六、MPDiou

参考MPDIoU: A Loss for Efficient and Accurate Bounding BoxRegression--论文学习笔记_athrunsunny的博客-CSDN博客

 

 

 

七、两阶段目标检测

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值