autoware.universe源码略读(3.1)--perception:yolo初识
autoware.universe源码略读3 .1--perception:初识yolo
OverView
因为以前没有接触过深度学习这方面的内容,最相关的一次是利用Unet给师兄跑了一个道路裂缝检测的demo,而且单纯跑了个demo之后也没再做深入的学习。这里还是想着不能单纯只拿来用,还是要大概知道这些模块是在干嘛的想法,把一些基础知识和yolo模型的一些东西稍微看了下,做个简单的学习总结,因为自己在这个领域只是初学,所以如有表述不当之处还望理解。这里推荐一位B站大佬FunInCode,他的很多视频对相关知识的理解都很有帮助。
此外,本篇文章的内容尚处在纸上谈兵的阶段,并没有自己去部署真实感受一下YOLO的具体使用,后面的话还是要找时间部署亲自感受一下才行
神经网络
神经网络的结构可以简单分为输入层、隐藏层和输出层,参考神经网络——最易懂最清晰的一篇文章中的图片,可以简单理解三个层的作用:
- 输入层:输入数据,其实就是传递各种数值(包括后边输入的图片也是数值)
- 隐藏层:这里可以类比于人脑的思考过程,机器所做的就是根据权重来进行特征的提取
- 输出层:输出最终的识别结果

这些神经元之间的连接间是存在权重信息的,一个神经网络的训练算法就是让权重的值调整到最佳,以使得整个网络的预测效果最好。当然这里还涉及到激活函数、逆向参数调整一些概念和方法,自己也只是简单了解了一下。
- 激活函数:在计算网络中, 一个节点的激活函数定义了该节点在给定的输入或输入的集合下的输出。标准的计算机芯片电路可以看作是根据输入得到开(1)或关(0)输出的数字电路激活函数。这与神经网络中的线性感知机的行为类似。然而,只有非线性激活函数才允许这种网络仅使用少量节点来计算非平凡问题。 在人工神经网络中,这个功能也被称为传递函数。我的理解就是在输出前加入了一个非线性的步骤,这样网络就不是简单的线性的了,对非线性的结构也可以学习
- 逆向参数调整:我的理解就是根据输出后的残差,来调节权重使得残差最小化的过程。
CNN
卷积神经网路(Convolutional Neural Network,CNN)在多个领域都有着广泛的应用,属于那种即使不了解也一定听过的概念,常见的领域就包括图像识别、目标检测、图像生成等等。首先关于卷积操作,这个概念当初在上数字图像处理这门课的时候确实是有学过的,简单说就是用一个小窗口去遍历整个图像,更像是一种滤波操作。当然在进行卷积操作的时候,因为如果不额外操作的话,会导致最终得到的图像比原图像的大小变小的,因此通常会有zero-padding这样一个扩充操作,也就是在图像的边缘外边格外扩充一些为0的数值,这样就可以使得卷积得到的图像和原图像的分辨率至少是一致的。
在CNN中,池化层也是一个重要的组成部分。由于我们输入的图像可能很大,也就意味着特征可能很大,那么在后续的处理可能会很耗时间也可能会存在过拟合的现象,因此在CNN中增加了池化层这个操作,实际上就是一种非线性降采样的方法,我看到的常见的有窗口最大值方法和平均值法。后续又看到了一个SPP空间金字塔池化(PS:这名字和单点定位的缩写一样,全程错乱),这个空间金字塔和视觉SLAM中常听到的金字塔结构本质上差不多

最后还有一个全连接层的概念,全连接层通常位于卷积神经网络的最后几层,负责将卷积层和池化层提取的特征进行组合和分类。全连接层中的每一个神经元都与上一层的所有神经元相连,通过学习权重和偏置参数,实现对输入数据的高级特征学习和分类。所以在池化层后,还要进行一个扁平化的处理,维基百科的解释是:
最后,在经过几个卷积和最大池化层之后,神经网络中的高级推理通过完全连接层来完成。就和常规的非卷积人工神经网络中一样,完全连接层中的神经元与前一层中的所有激活都有联系。因此,它们的激活可以作为仿射变换来计算,也就是先乘以一个矩阵然后加上一个偏差(bias)偏移量(向量加上一个固定的或者学习来的偏差量)。
这里也是简单学习了下相关的概念,并没有完全深入地研究
YOLOv1
YOLO(You Only Look Once)是一种基于深度神经网络的对象识别和定位算法,在写这篇文章的前几天,还有看到说最新的YOLO v10已经出来了,但是自己还是要一步一步来,毕竟自己连v1都不会呢。这里也是在网上找了非常多的资料和文章进行学习,个人阅读下来觉得观感最佳的一篇是:
通过对前面神经网络和CNN概念的学习之后,自己根据这篇文章看下来整个YOLO的原理还是大概都理解了的。YOLO的第一步就是把图片分成网格,像最原始的就是把448×448的图片分成7×7的网格,那这也就反应了输入和输出的映射关系:

每一个格子对应的是一个1×30的量,所以整个图片的输出理论上就是7730的量,那么关于这个输出量,每一个网格可以对应两个bounding box,我的理解就是预测物体的边界框,所以30维向量包含的就是两个bounding box的位置信度,两个置信率以及20个种类的概率,这里关于置信度的概念我觉得不太好理解,他的计算公式是:

这里第一个代表的就是存在对象的概率,就是包不包含对象的意思。而IOU反应的是预测的bounding box的准确率,可以参考这张图

最后就是这个网络的训练结构了,一共有24个卷积层和2个全连接层

而在推断的时候,根据前面说的这个分格的步骤,也不难理解,不加处理的话可能一个对象会被好几个格子预测到,那样的话就会很重复,所以YOLO还用了一种叫NMS(非极大值抑制)的方法,这个的核心思想就是把所有的检测到的物体目标框分开来看,然后找到一个分数最高的作为输出(但是这样如果一个物体在图片里有好几个不就会覆盖掉么?估计是有点其他的操作)
这里后边又了解了一下,在nms的过程不止单一地对一种指标进行了排序,会先判断置信度再判断IoU,所以不会最后只剩下一个
YOLOv2
YOLOv2/YOLO9000的论文中有下面这张表格总结相对v1都有哪些改变,这里给的评价指标是mAP,Mean Average Precision,也就是平均精确率的平均,下面对几个比较抽象的改进简单记录一下

batch normalization(批归一化)
第一个创新就是这个批归一化,也就是后边很多地方都有提到的BN层,这一层是在网络(线性变换)输出后和激活函数(非线性变换)之前增加的,干的事可以分为以下两步:
- 对于输入的一批数据的特征量分别进行归一化处理,使每个特征的数据分布变换为均值0,方差1。从而使得每一批训练样本在每一层都有类似的分布。
- 对上一步的输出再做一次线性变换,假设上一步的输出为Z,则Z1=γZ + β。这里γ、β是可以训练的参数。增加这一变换是因为上一步骤中强制改变了特征数据的分布,可能影响了原有数据的信息表达能力。增加的线性变换使其有机会恢复其原本的信息。
anchor boxes(先验框)
这里的先验框,其实就是候选区的意思,在神经网络中会检验每个网格的先验框里是否包含着对象,随着先验框的增加,那么召回率提升也是很好理解的。那么比起来手动设置的先验框,YOLOv2里是进行了一个聚类提取来提取先验框:对训练集中标注的边框进行聚类分析,以寻找尽可能匹配样本的边框尺寸。 至于聚类的具体操作,采用的公式是和IoU结合起来的

location prediction
为了让训练早期阶段预测边框的位置尽可能稳定一下,YOLO对预测公式进行了调整,目的是将预测边框的中心约束在特定gird网格内


passthrough(检测细粒度特征)
提出这个层的原因是因为对象有大有小,较小的特征经过卷积的输出可能就被忽略了。v2中的操作是在最后一个pooling之前,特征图的大小是26×26×512,将其1拆4,直接传递(passthrough)到pooling后(并且又经过一组卷积)的特征图,两者叠加到一起作为输出的特征图。
- 但之后的版本好像就不再用这个方法了
mutli-scale(多尺度训练)
参考<机器爱学习>YOLOv2 / YOLO9000 深入理解:
因为去掉了全连接层,YOLO2可以输入任何尺寸的图像。因为整个网络下采样倍数是32,作者采用了{320,352,…,608}等10种输入图像的尺寸,这些尺寸的输入图像对应输出的特征图宽和高是{10,11,…19}。训练时每10个batch就随机更换一种尺寸,使网络能够适应各种大小的对象检测。
总结
v2相对于v1其实变化不是很多,主要在于增加了bn层、passthrough层,然后去掉了全连接层,并且预先设置 了5个聚类得到的先验框,先验框的增加导致最后输出量肯定是变化了的

对比YOLO1的输出张量,YOLO2的主要变化就是会输出5个先验框,且每个先验框都会尝试预测一个对象。输出的 13×13×5×25 张量中,25维向量包含 20个对象的分类概率+4个边框坐标+1个边框置信度。
YOLOv3
首先放一下YOLOv3的整体网络结构图,来源江大白,同时参考了【YOLO系列】–YOLOv3超详细解读/总结

蓝色框代表的是YOLOv3的三个基本组件:
(1)CBL:Yolov3网络结构中的最小组件,由Conv+Bn+Leaky_relu激活函数三者组成。
(2)Res unit:借鉴Resnet网络中的残差结构,让网络可以构建的更深。
(3)ResX:由一个CBL和X个残差组件构成,是Yolov3中的大组件。每个Res模块前面的CBL都起到下采样的作用,因此经过5次Res模块后,得到的特征图是608->304->152->76->38->19大小。
其他基础操作:
(1)Concat:张量拼接,会扩充两个张量的维度,例如26×26×256和26×26×512两个张量拼接,结果是26×26×768。Concat和cfg文件中的route功能一样。
(2)Add:张量相加,张量直接相加,不会扩充维度,例如104×104×128和104×104×128相加,结果还是104×104×128。add和cfg文件中的shortcut功能一样。
backbone(主干网络)
YOLOv3相对于v2的一大提升就在于backbone,相比于v2的DarkNet19,v3采用了DarkNet53,也就是使用了更多的53层卷积来对数据进行处理

这个DarkNet53主要用的是一些1×1和3×3的卷积核。YOLOv2中对于向前传播中张量尺寸变换,都是通过最大池化来进行,一共有5次。而v3是通过卷积核增大步长来进行,也是5次。(darknet-53最后面有一个全局平均池化,在yolo-v3里面没有这一层,所以张量维度变化只考虑前面那5次) 。
多尺度预测
YOLOv3借鉴了FPN的方法,采用多尺度的特征图对不同大小的物体进行检测,以提升小物体的预测能力。这里是分为了3种尺度,来分别预测大中小三种尺寸下的物体。先验框的话也是根据聚类来得到的,一共得到9个先验框
- 尺度1: 在基础网络之后添加一些卷积层再输出box信息.
- 尺度2: 从尺度1中的倒数第二层的卷积层上采样(x2)再与最后一个16x16大小的特征图相加,再次通过多个卷积后输出box信息.相比尺度1变大两倍.
- 尺度3: 与尺度2类似,使用了32x32大小的特征图.
下面这张图更好的解释了这个过程:

多标签分类
这里使用了logistic 分类器,而不是之前使用的softmax分类,因为softmax只适用于单目标多分类(甚至类别是互斥的假设),但目标检测任务中可能一个物体有多个标签。所以在v3中使用Binary Cross Entropy ( BCE, 二元交叉熵) 来进行类别预测。
YOLOv4
YOLOv4的网络结构图如下

可以看到,相比于YOLOv3,多了SPP、PAN这些结构在里面
整理下Yolov4的五个基本组件:
- CBM:Yolov4网络结构中的最小组件,由Conv+Bn+Mish激活函数三者组成。
- CBL:由Conv+Bn+Leaky_relu激活函数三者组成。
- Res unit:借鉴Resnet网络中的残差结构,让网络可以构建的更深。
- CSPX:借鉴CSPNet网络结构,由卷积层和X个Res unint模块Concat组成。
- SPP:采用1×1,5×5,9×9,13×13的最大池化的方式,进行多尺度融合。
其他基础操作:
- Concat:张量拼接,维度会扩充,和Yolov3中的解释一样,对应于cfg文件中的route操作。
- Add:张量相加,不会扩充维度,对应于cfg文件中的shortcut操作。
关于v4相对于v3的创新,江大白的文章已经总结得非常详细了,具体的内容可以参考这篇文章,这里只记录下简单的总结:
(1)输入端:这里指的创新主要是训练时对输入端的改进,主要包括Mosaic数据增强、cmBN、SAT自对抗训练。
(2)BackBone主干网络:将各种新的方式结合起来,包括:CSPDarknet53、Mish激活函数、Dropblock
(3)Neck:目标检测网络在BackBone和最后的输出层之间往往会插入一些层,比如Yolov4中的SPP模块、FPN+PAN结构
(4)Prediction:输出层的锚框机制和Yolov3相同,主要改进的是训练时的损失函数CIOU_Loss,以及预测框筛选的nms变为DIOU_nms
当然也可以参考【YOLO系列】–YOLOv4超详细解读/总结(网络结构),里面对YOLOv4的创新也做出了非常详细的总结。
YOLOv5
autoware.universe中galatic分支里还是有tensorrt_yolo模块的,其中提到了YOLOv3-v5三个版本,所以这里再来看一下v5,事实上v5说是包含了四种网络模型,分别是Yolov5s、Yolov5m、Yolov5l和Yolov5x,但具体到autoware中使用到的是YOLOv5n ‘Nano’ models,这是一种专门为Nano设备准备的模型,提供适用于边缘设备的准确度,应该是比v5s还要小的一个网络结构,那这里先结合着v5s来看,图片依旧引自江大白的文章

四个部分的特点总结如下:
(1)输入端:Mosaic数据增强、自适应锚框计算
(2)Backbone:Focus结构,CSP结构
(3)Neck:FPN+PAN结构
(4)Prediction:GIOU_Loss
输入端:自适应锚框计算
这应该是v5相对于v4的一个改变,在YOLO算法里,会针对不同的数据集先设定长款的锚框,在网络训练中,网络在初始锚框的基础上输出预测框,进而和真实框groundtruth进行比对,计算两者差距,再反向更新,迭代网络参数。相比于之前的版本,v5的改进就是每次训练时,自适应的计算不同训练集中的最佳锚框值
输入端:自适应图片缩放
在输入图片的缩放里,v5也做出了创新,其实说白了就是找了一个边作为参考,然后另一个边不够的地方用黑色填充一下,不过这样的好处就是保证图片的信息,当然在填充的时候也是稍微进行了一下限制,以免黑色填充得太多了

这里需要得最重要的一点是:训练时没有采用缩减黑边的方式,还是采用传统填充的方式,即缩放到416×416大小。只是在测试,使用模型推理时,才采用缩减黑边的方式,提高目标检测,推理的速度。
Backbone:Focus结构
Focus结构的关键部分是数据切片,虽然都是下采样,但是比起使用卷积的方式,切片的方式可以保持特征图的信息,并且增加了通道数,这有助于模型在早期层次提取更多细节特征。而且对计算效率和计算量应该是有明显的帮助。
Backbone:CSP结构
关于CSP结构,GPT给出了一个解释是CSP 结构的核心思想是将特征图在某个阶段进行分块处理,一部分特征图通过一个路径,另一部分特征图通过另一个路径。然后,将这两个路径的特征图再次结合起来。这种分块策略有助于减少冗余计算,平衡计算负载,同时提高特征表达的多样性。 结合了下网络结构图看感觉这个说法应该是有道理的,v5相比于v4设计了两种CSP结构,分别用在了backbone部分和neck部分
Neck
Yolov5和Yolov4的不同点在于,Yolov4的Neck中,采用的都是普通的卷积操作。
而Yolov5的Neck结构中,采用借鉴CSPNet设计的CSP2结构,加强网络特征融合的能力。

输出端
这里在v4中做了的改进是使用了DIOU_nms的方法,但说是v5又使用了加权nms的方式,说是DIOU_nms效果会刚好一些
不同模型的区别
首先先明确两个参数,网络的深度和宽度,这个根据配置文件可以看出,v5l应该是一个基准,剩下的三个分别是对应的比值,这两个参数我个人的理解是(也不知道对不对)
- 深度:应该就是层数,理论上在计算性能差不多的情况下,层数应该是越多越好的?
- 宽度:应该是对每一层的通道数进行控制

这一部分具体是怎么控制的,还是参考江大白的文章吧
YOLOv5相比于之前的版本,可能是更多的结构带来了不同场景下的使用可能?在galatic分支里应该使用的就是当前版本
YOLOx
autoware中还有一个YOLOx模块,这个在最新的分支也是被保留了下来的。YOLOx也是包含了几种网络结构,最小的Nano、Tiny、Darknet53、s、m、l和x,对应的应该也就是网络结构大小的一些东西。

值得注意的是,这里对比的基准模型是v3_spp,也就是加入了spp模型的v3版本,没有使用到v4和v5,接下来跟着江大白的文章先来简单学习下几种模型
Yolox-Darknet53

在输入端,这里使用到了Mosaic、Mixup两种数据增强方法,其中,Mosaic方法在v4和v5中也有使用到,通过对四张图片进行的拼接,使得图片大中小目标数量更合理,而且拼接之后还能有效减少计算量。
Mixup方法则是在Mosaic基础上的额外增强策略,这个的策略也是把图片组合起来,不过这里不是拼接,而是叠加了,所以这样会对那种重叠比较多的目标检测效果帮助比较明显?

这里的Backbone是和v3的主干网络保持一致了,Neck部分使用到的则是FPN结构,当然YOLOx的其他网络类型还是会使用到FPN+PAN结构。
在预测层,应该是Yolox-Darknet53改进比较多的地方?首先是Decoupled Head,看名字应该就是一个解耦的操作,在网络图中对应就是Prediction部分中的一开始的地方,根据下面这张图,看起来就是把一个输入的数据分开来了,根据江大白的解释是分成了cls_output(主要对目标框的类别,预测分数)、obj_output(主要判断目标框是前景还是背景)和reg_output(主要对目标框的坐标信息)三部分。

感觉这里的优势应该就是通过分离处理,可以更好地优化各自需要的特征,提高模型整体性能?
另一个改进是针对Anchor的,在之前版本里,无论是v3指定还是v4/v5通过聚类等方法获得,都属于是Anchor-Based的方法,在YOLOx中的方法是Anchor-Free的,关于这里,主要就是输出信息的数据大小相关的,最终得到的特征向量是85×8400的,针对这8400维的向量,结合之前backbone的下采样过程,下采样5次的大小就是32×32的,下采样四次的是16×16,三次的是8×8的。

那么到这里,当有了8400个预测框的信息,每张图片也有标注的目标框的信息。这时需要做的,就是将8400个锚框,和图片上所有的目标框进行关联,挑选出正样本锚框。这里涉及到的下一个概念,就是标签分配。
在预测框中,只有少部分是正样本,绝大多数都是负样本,为了得到哪些是正样本,需要利用锚框和实际目标框的关系,挑选出一部分适合的正样本锚框。YOLOx中,挑选正样本锚框的部分涉及到了两个关键点:初步筛选、SimOTA。
- 初步筛选:寻找anchor_box中心点,落在groundtruth_boxes矩形范围的所有anchors。

此外,还有一种规则是以groundtruth中心点为基准,设置边长为5的正方形,挑选在正方形内的所有锚框

- 精细化筛选:SimOTA
SimOTA分为了初筛正样本信息提取、Loss函数计算、cost成本计算和SimOTA求解四个步骤。这里还是有点复杂的,具体的步骤和原理还是参考江大白的文章吧。
YOLOx-s、l、m、x系列
这里是针对v5的一系列网络结构,使用了一系列trick进行的改进。在四个部分的主要区别分别是:
(1)输入端:在Mosa数据增强的基础上,增加了Mixup数据增强效果;
(2)Backbone:激活函数采用SiLU函数;
(3)Neck:激活函数采用SiLU函数;
(4)输出端:检测头改为Decoupled Head、采用anchor free、multi positives、SimOTA的方式。
(下图为YOLOx-s的网络结构图)

总结
到这里,把YOLO系列的1-5以及x系列的基本知识算是过了一遍吧,稍微有理解些这个模型具体是干什么的以及怎么发挥作用的了,但是因为完全没有看代码,也没有去实地部署之类的,所以这里很多东西的理解都是模棱两可的。后续的话还是应该结合实际的代码以及实际部署的操作,来更好地理解这个部分是怎么用在autoware之中的。
更多推荐



所有评论(0)