Yolov5学习笔记7——v6.0源码剖析——Neck部分

在网络结构配置文件yolov5s.yaml中,并未将neck和head区分开来,而是直接以head命名,这也是方便在model/yolo.py中的加载。Yolov5学习笔记7只讨论head中的neck部分。

neck结构概览及参数

neck部分结构图

neck部分参数配置源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# YOLOv5 v6.0 head
head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 13

[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, C3, [256, False]], # 17 (P3/8-small)

[-1, 1, Conv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, C3, [512, False]], # 20 (P4/16-medium)

[-1, 1, Conv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, C3, [1024, False]], # 23 (P5/32-large)
]

可以看到,Neck部分的组件相较于Backbone较为单一,基本上就由CBS、Upsample、Concat和不带shortcut的CSP(C3)。

FPN和PAN

Neck的网络结构设计也是沿用了FPN+PAN的结构。FPN就是使用一种 自顶向下的侧边连接在所有尺度上构建出高级语义特征图,构造了特征金字塔的经典结构;PAN的结构也不稀奇,FPN中间经过多层的网络后,底层的目标信息已经非常模糊了,因此PAN又加入了自底向上的路线,弥补并加强了定位信息。

Neck部分各模块

CBS模块

在Backbone中,为了进一步提取图像中的信息,CBS在改变特征图通道的同时,也会控制卷积模块中的步长s下采样来改变特征图的尺寸。Neck中左侧采用FPN自顶向下设计的过程中,是特征图上采样的过程,因此这个时候再下采样就不合时宜了,所以在FPN中s=1;而到了右侧PAN再次自下而上提取位置信息时,就需要使用CBS继续下采样抽取高层次的语义信息,这也是CBS前后参数差异的原因。

nn.Upsample

1
[-1, 1, nn.Upsample, [None, 2, 'nearest']],

使用的是Pytroch内置的上采样模块,需要指定上采样的倍数和方式。

这里我们不指定size,上采样倍数为2,上采样方式为nearest,也就是最近填充。

Concat

1
[[-1, 6], 1, Concat, [1]],  # cat backbone P4

Concat即拼接,接对象通过from传入,拼接的维度由args参数指定,此处即按照维度1(channel)拼接,其他维度不变。

CSP/C3

Backbone需要更深层次的网络获取更多的信息,可以说backbone已经完成了主要特征信息的提取,所以在Neck阶段我们并不需要再一味地加深网络,采取不带残差的C3模块可能会更合适一些。