YOLOv5中的CSP结构

深度学习入门小菜鸟,希望像做笔记记录自己学的东西,也希望能帮助到同样入门的人,更希望大佬们帮忙纠错啦~侵权立删。

目录

一、背景知识 -- CSPNet

二、CSP结构分析

1、总括

2、CSP1_X结构

3、CSP2_X

三、源码分析(内含注释分析)


一、背景知识 -- CSPNet

有关CSPNet的介绍分析可以康康博主之前的博客

深度学习之CSPNet分析_tt丫的博客-CSDN博客


二、CSP结构分析

1、总括

YOLOv5s的CSP结构是将原输入分成两个分支,分别进行卷积操作使得通道数减半,然后一个分支进行Bottleneck * N操作,然后concat两个分支,使得BottlenneckCSP的输入与输出是一样的大小,这样是为了让模型学习到更多的特征。

YOLOv5中的CSP有两种设计,分别为CSP1_X结构和CSP2_X结构。

2、CSP1_X结构

网络结构图如下图所示:

【(1)其中CBL为Conv+BN+Leaky ReLU,代码解析等详见往期博客YOLOv5中的Focus层详解_tt丫的博客-CSDN博客中的代码分析部分。

   (2)其中Resunit是x个残差组件,相关介绍详见往期博客详解YOLOv5中的Bottleneck_tt丫的博客-CSDN博客

YOLOv5中的CSP结构

将输入分为两个分支,一个分支先通过CBL,再经过多个残差结构(Bottleneck * N),再进行一次卷积;另一个分支直接进行卷积;然后两个分支进行concat,再经过BN(正态分布),再来一次激活,最后进行一个CBL。

CSP1_X应用于backbone主干网络部分(backbone具体介绍以后再说哒),backbone是较深的网络,增加残差结构可以增加层与层之间反向传播的梯度值,避免因为加深而带来的梯度消失,从而可以提取到更细粒度的特征并且不用担心网络退化。

3、CSP2_X

网络结构图如图所示

YOLOv5中的CSP结构CSP2_X相对于CSP1_X来说,不一样的地方只有CSP2_X将Resunit换成了2 * X个CBL,主要应用在Neck网络 (网络没那么深)。


三、源码分析(内含注释分析)

每一部分对应网络结构中的哪一部分都有标注如下

(其中Bottleneck类的分析见博客详解YOLOv5中的Bottleneck_tt丫的博客-CSDN博客

class BottleneckCSP(nn.Module):
    #CSP结构
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion
        super().__init__()
        c_ = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, c_, 1, 1)#对应上面网络结构图的上面的分支的第一个CBL
        self.cv2 = nn.Conv2d(c1, c_, 1, 1, bias=False)#对应上面网络结构图的下面的分支的conv
        self.cv3 = nn.Conv2d(c_, c_, 1, 1, bias=False)#对应上面网络结构图的上面的分支的conv
        self.cv4 = Conv(2 * c_, c2, 1, 1)#对应最后的CBL
        self.bn = nn.BatchNorm2d(2 * c_)  # applied to cat(cv2, cv3)
        self.act = nn.SiLU()#对应Concat后的Leaky ReLU
        self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))
        #nn.Sequential--序贯模型是函数式模型的简略版,为最简单的线性、从头到尾的结构顺序,不分叉,是多个网络层的线性堆叠。
        #self.m对应X个Resunit or 2 * X个CBL(对应的切换是通过Bottleneck类中的True 或 False决定,True为X个Resunit,False为2 * X个CBL)
    def forward(self, x):
        y1 = self.cv3(self.m(self.cv1(x)))#对应上面网络结构图的上面的分支
        y2 = self.cv2(x)#对应上面网络结构图的下面的分支
        return self.cv4(self.act(self.bn(torch.cat((y1, y2), dim=1))))
        #torch.cat对应Concat
        #self.bn对应Concat后的BN

欢迎大家在评论区批评指正,谢谢大家~

上一篇:使用sentinel核心库进行服务熔断降级


下一篇:CSP-J 2021解题报告