在上一篇《YOLOv5的Backbone设计》中,我们从yolov5的backbone配置文件出发,细致讲解了backbone的网络架构及各模块的源码和结构,对骨架网络有了较为全面的初步认知。接下来我们会循着之前的学习思路,继续深入到网络结构源码中去探寻YOLO的Neck端设计。
1 Neck结构总览
网络结构配置文件中并未将neck和head进行区分,而是直接以head命名,这也是方便在models/yolo.py中的加载。为了读者能够清晰明白地感知neck的设计,在本文中我们只讨论head中的neck部分:
neck:
[[-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就是使用一种 自顶向下的侧边连接在所有尺度上构建出高级语义特征图,构造了特征金字塔的经典结构,也就是上图中的a,具体细节可以参考我之前的文章:FPN网络结构+源码讲解;PAN的结构也不稀奇,FPN中间经过多层的网络后,底层的目标信息已经非常模糊了,因此PAN又加入了自底向上的路线,弥补并加强了定位信息,也就是上图中的b。贴一下FPN和PAN原文:
FPN:Feature Pyramid Networks for Object Detection
PAN:Path Aggregation Network for Instance Segmentation
2 Neck部件模块
2.1 CBS
在Backbone中,为了进一步提取图像中的信息,CBS在改变特征图通道的同时,也会控制卷积模块中的步长s下采样来改变特征图的尺寸。Neck中左侧采用FPN自顶向下设计的过程中,是特征图上采样的过程,因此这个时候再下采样就不合时宜了,所以在FPN中s=1;而到了右侧PAN再次自下而上提取位置信息时,就需要使用CBS继续下采样抽取高层次的语义信息,这也是CBS前后参数差异的原因。具体的CBS结构可以参考上篇文章:YOLOv5的Backbone详解,这里不再赘述。
2.2 nn.Upsample
[-1, 1, nn.Upsample, [None, 2, 'nearest']]
Pytroch内置的上采样模块,需要指定上采样的倍数和方式。
这里我们不指定size,上采样倍数为2,上采样方式为nearest,也就是最近填充。
2.3 Concat
[[-1, 6], 1, Concat, [1]], # cat backbone P4
Concat即拼接,接对象通过from传入,拼接的维度由args参数指定,此处即按照维度1(channel)拼接,其他维度不变。至于from中的特征图到底是哪一个,我建议大家运行模型将各层特征图打印出来,如:
通过上图就很容易确定concat的两个对象了,当然,我在文章最开始的时候已经给大家画出来网络结构,大家按图索骥也可以找到。
class Concat(nn.Module):
# Concatenate a list of tensors along dimension
def __init__(self, dimension=1):
super().__init__()
self.d = dimension
def forward(self, x):
return torch.cat(x, self.d)
2.4 CSP/C3
Backbone需要更深层次的网络获取更多的信息,可以说backbone已经完成了主要特征信息的提取,所以在Neck阶段我们并不需要再一味地加深网络,采取不带残差的C3模块可能会更合适一些。
具体的模块结构及源码参考backbone中的介绍。文章来源:https://www.toymoban.com/news/detail-466797.html
neck端的主要内容大体就是以上了。文章来源地址https://www.toymoban.com/news/detail-466797.html
到了这里,关于YOLOv5的Neck端设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!