YOLOV5源码解读-Focus

发布时间 2023-09-27 16:01:36作者: FeiYull

  对整体网络架构的解读,请集合博客末尾附录资料(两个网络架构图、配置文件)。

一、Focus

如下图是Focus模块,对应下面配置文件中的第三十行:

[[-1, 1, Focus, [64, 3]],  # 0-P1/2  

 

 

  在网络前面,Focus模块的用作是加速数据处理,但并不能提升网络速度。如下图,将左边4×4×3的特征图进行分块,显然颜色一样的最终被分到一起,最终得到如右图的2×2×12的特征图。就是简单拆分,然后堆叠。

二、激活函数模块

 

 YOLOV5中使用的激活函数是上述Hish函数,看到第三项公式:x*(x+3)/6,其对应下图(黑色部分就是常规加减乘除,下图和附录图可能版本不对应,但不影响理解):

 

 三、BottlenckCSP模块

 

 

 

后续的SPP与PANet在详细架构图中比较抽象。常用的模块在common.py中。

 

 其中,BottleneckCSP层的定义在conmmon.py中,

 1 class BottleneckCSP(nn.Module):
 2     # CSP Bottleneck https://github.com/WongKinYiu/CrossStagePartialNetworks
 3     def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion
 4         super(BottleneckCSP, self).__init__()
 5         c_ = int(c2 * e)  # hidden channels
 6         self.cv1 = Conv(c1, c_, 1, 1)
 7         self.cv2 = nn.Conv2d(c1, c_, 1, 1, bias=False)
 8         self.cv3 = nn.Conv2d(c_, c_, 1, 1, bias=False)
 9         self.cv4 = Conv(2 * c_, c2, 1, 1)
10         self.bn = nn.BatchNorm2d(2 * c_)  # applied to cat(cv2, cv3)
11         self.act = nn.LeakyReLU(0.1, inplace=True)
12         self.m = nn.Sequential(*[Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)])
13 
14     def forward(self, x):
15         # BottleneckCSP 的两条线
16         y1 = self.cv3(self.m(self.cv1(x)))
17         y2 = self.cv2(x)
18         # 在这里汇合
19         return self.cv4(self.act(self.bn(torch.cat((y1, y2), dim=1))))

BottlenckCSP = CSP + ResNet Block。如下图,input后面分为两条路,对应上图y1,y2;之后是一个concat,和上面代码对应。需要注意的是,Bottleneck里面是一个残差连接模块。

 

 

 

 

 

 附:

YOLO5网络结构图(简图):

 

 YOLO5S配置文件YOLOV5S.yaml

 1 # parameters
 2 nc: 80  # number of classes
 3 
 4 # 在四个yaml文件中,
 5 # 5s 5m 5l 5x 也就下面网络的深度、宽度两个参数不同
 6 
 7 # eg:下面backbone中的模块:[-1, 9, C3, [512]]
 8 # 重复9次,在yolo5s中,0.33 * 9 = 3,表示仅重复三次
 9 depth_multiple: 0.33  # model depth multiple
10 
11 # width_multiple:卷积核个数
12 # eg:[-1, 1, Focus, [64, 3]],中的64表示经过该模块后
13 # 得到64个特征图,但是由于这里网络宽度设置为0.5,所以
14 # 输出应该是0.5 * 64 = 32个特征图
15 width_multiple: 0.50  # layer channel multiple
16 
17 # anchors 先验框,和V3一样
18 anchors:
19   - [10,13, 16,30, 33,23]  # P3/8
20   - [30,61, 62,45, 59,119]  # P4/16
21   - [116,90, 156,198, 373,326]  # P5/32
22 
23 # YOLOv5 backbone
24 backbone:
25   # [from, number, module, args]
26   # from:当前层输入来自哪里,例如:-1:连接上一层;6:表示第6层输入
27   # number:模块重复次数
28   # module:模型名字
29   # args:模型参数,eg:卷积核尺寸
30   [[-1, 1, Focus, [64, 3]],  # 0-P1/2  
31    [-1, 1, Conv, [128, 3, 2]],  # 1-P2/4
32    [-1, 3, C3, [128]],
33    [-1, 1, Conv, [256, 3, 2]],  # 3-P3/8
34    [-1, 9, C3, [256]],
35    [-1, 1, Conv, [512, 3, 2]],  # 5-P4/16
36    [-1, 9, C3, [512]],
37    [-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32
38    [-1, 1, SPP, [1024, [5, 9, 13]]],
39    [-1, 3, C3, [1024, False]],  # 9
40   ]
41 
42 # YOLOv5 head
43 head:
44   [[-1, 1, Conv, [512, 1, 1]],
45    [-1, 1, nn.Upsample, [None, 2, 'nearest']],
46    [[-1, 6], 1, Concat, [1]],  # cat backbone P4
47    [-1, 3, C3, [512, False]],  # 13
48 
49    [-1, 1, Conv, [256, 1, 1]],
50    [-1, 1, nn.Upsample, [None, 2, 'nearest']],
51    [[-1, 4], 1, Concat, [1]],  # cat backbone P3
52    [-1, 3, C3, [256, False]],  # 17 (P3/8-small)
53 
54    [-1, 1, Conv, [256, 3, 2]],
55    [[-1, 14], 1, Concat, [1]],  # cat head P4
56    [-1, 3, C3, [512, False]],  # 20 (P4/16-medium)
57 
58    [-1, 1, Conv, [512, 3, 2]],
59    [[-1, 10], 1, Concat, [1]],  # cat head P5
60    [-1, 3, C3, [1024, False]],  # 23 (P5/32-large)
61 
62    [[17, 20, 23], 1, Detect, [nc, anchors]],  # Detect(P3, P4, P5)
63   ]

 

 

 

YOLO5S网络结构图(详细):