当前位置: 代码迷 >> 综合 >> 行为分析(六):人形检测部分(一):YOLOv1-v5的学习笔记
  详细解决方案

行为分析(六):人形检测部分(一):YOLOv1-v5的学习笔记

热度:16   发布时间:2023-11-21 09:21:11.0

**写在前面的通常很重要

原博客在https://blog.csdn.net/lemonbit/article/details/109281590,这里只是一份学习笔记,记录学习这篇博客时的一些想法,点赞收藏优先原博客,感谢。

YOLOv1

YOLOv1部分我们梳理一下YOLO系列通用的技术。

一句话概括YOLO的原理

将输入图像划分为S*S(最终feature map的大小)个grid cell,每一个cell预测B个bounding boxes,以及C个类别概率。训练过程中,ground truth的中心落在哪个grid cell中,那个grid cell就负责预测这个ground truth框。

grid cell如何预测

每个网络(grid cell)需要预测B个BBox的位置信息和confidence(置信度)信息,一个BBox对应着四个位置信息和一个confidence信息。confidence代表了所预测的box中含有object的置信度和这个box预测的有多准两重信息。

每个bounding box要预测(x, y, w, h)和confidence共5个值,每个网格还要预测一个类别信息,记为C类。则SxS个网格,每个网格要预测B个bounding box还要预测C个categories。输出就是S x S x (5*B+C)的一个tensor。(注意:class信息是针对每个网格的,confidence信息是针对每个bounding box的。)

举例说明: 在PASCAL VOC中,图像输入为448x448,取S=7,B=2,一共有20个类别(C=20)。则输出就是7x7x30的一个tensor。

然后根据阈值去除可能性比较低的目标窗口,最后NMS去除冗余窗口即可

confidence怎么计算

confidence = P(object)*IoU(truth->pred)
其中如果有object落在一个grid cell里,第一项取1,否则取0。第二项是预测的bounding box和实际的groundtruth之间的IoU值

NMS-非极大抑制

就像上面的图片一样,定位一个车辆,最后算法就找出了一堆的方框,我们需要判别哪些矩形框是没用的。非极大值抑制的方法是:先假设有6个矩形框,根据分类器的类别分类概率做排序,假设从小到大属于车辆的概率 分别为A、B、C、D、E、F。
(1)从最大概率矩形框F开始,分别判断A~E与F的重叠度IOU是否大于某个设定的阈值;
(2)假设B、D与F的重叠度超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。
(3)从剩下的矩形框A、C、E中,选择概率最大的E,然后判断E与A、C的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。
就这样一直重复,找到所有被保留下来的矩形框。

参考链接:https://www.cnblogs.com/makefile/p/nms.html

损失函数

在实现中,最主要的就是怎么设计损失函数,让这个三个方面得到很好的平衡。作者简单粗暴的全部采用了sum-squared error loss来做这件事。
这种做法存在以下几个问题:
        第一,8维的localization error和20维的classification error同等重要显然是不合理的;
        第二,如果一个网格中没有object(一幅图中这种网格很多),那么就会将这些网格中的box的confidence push到0,相比于较少的有object的网格,这种做法是overpowering的,这会导致网络不稳定甚至发散。
        第三,对不同大小的box预测中,相比于大box预测偏一点,小box预测偏一点肯定更不能被忍受的。而sum-square error loss中对同样的偏移loss是一样。
解决办法:
问题1&2

        更重视8维的坐标预测,给这些损失前面赋予更大的loss weight。
        对没有object的box的confidence loss,赋予小的loss weight。
        有object的box的confidence loss和类别的loss的loss weight正常取1。
问题3
        为了缓和这个问题,作者用了一个比较取巧的办法,就是将box的width和height取平方根代替原本的height和width。这个参考下面的图很容易理解,小box的横轴值较小,发生偏移时,反应到y轴上相比大box要大。(也是个近似逼近方式)图源:知乎“初始cv”

推理过程中的目标框概率是怎么计算的

yolo推理的时候,把置信度乘以分类的最高概率,作为一个bounding box的得分,然后大于某一个阈值的得分的bouding box再送到NMS里面处理,最终得出输出框

YOLOv1优点

1.速度快,达到了完全实时的效率
2.错误率低(相对于faster rcnn会把很多背景预测为物体)
3.泛华能力强(论文试验-在美术绘画作品中也有较好的效果)

YOLOv1缺点

1.由于输出层为全连接层,因此在检测时,YOLO训练模型只支持与训练图像相同的输入分辨率。2.虽然每个格子可以预测B个bounding box,但是最终只选择只选择IOU最高的bounding box作为物体检测输出,即每个格子最多只预测出一个物体。当物体占画面比例较小,如图像中包含畜群或鸟群时,每个格子包含多个物体,但却只能检测出其中一个。这是YOLO方法的一个缺陷。3.YOLO loss函数中,大物体IOU误差和小物体IOU误差对网络训练中loss贡献值接近(虽然采用求平方根方式,但没有根本解决问题)。因此,对于小物体,小的IOU误差也会对网络优化过程造成很大的影响,从而降低了物体检测的定位准确性。

关于YOLOv1的结构

YoloV1的网络采用了24个卷积层+2个FC层。可以发现此时BN技术与残差连接尚未提出,因此yolo的网络里面并没有使用BN层以及残差模块。并且后面连续使用了两个FC,参数量比较大。目前主流的检测器基本抛弃了fc,使用全卷积。另外就是Yolo V1没有使用特征融合,没有在多个分辨率上进行预测。这也与当前的目标检测框架不一样。

 所以导致了缺点1:YOLO训练模型只支持与训练图像相同的输入分辨率。以及产生了接下来的结构优化。

YOLOv2

这部分我们说说YOLOv2相比YOLOv1的改进策略

Batch Normalization(批量归一化)

顺便说说BN层为什么这么重要

1.BN层为什么能防止梯度爆炸和梯度消失

它可以使每层输出的数据保持到固定的均值和标准差,这样会避免数值过小或过大,梯度也就会比较规范,因此可以避免梯度消失或爆炸

2.BN层的四个参数有什么意义,为什么能加速模型的收敛:https://blog.csdn.net/m0_37192554/article/details/88662560

作者认为:网络训练过程中参数不断改变导致后续每一层输入的分布也发生变化,而学习的过程又要使每一层适应输入的分布,因此我们不得不降低学习率、小心地初始化。前两个的参数减去一个均值后再除以方差,是在调整数据的分布,统一数据分布后则会更容易优化。继续即使原因的话,可以说数据模型的初始化分割线大致在0附近,进行BN后数据也在0附近,则更容易拟合。
但如果简单的这么干,会降低层的表达能力。比如在使用sigmoid激活函数的时候,如果把数据限制到0均值单位方差,那么相当于只使用了激活函数中近似线性的部分,这显然会降低模型表达能力。 于是作者引入了两个科学系的参数。

3.BN算法防止过拟合

在网络的训练中,BN的使用使得一个minibatch中所有样本都被关联在了一起,因此网络不会从某一个训练样本中生成确定的结果,即同样一个样本的输出不再仅仅取决于样本的本身,也取决于跟这个样本同属一个batch的其他样本,而每次网络都是随机取batch,这样就会使得整个网络不会朝这一个方向使劲学习。一定程度上避免了过拟合。

就是说“使每层输出的数据保持到固定的均值和标准差”这项功能,可以直接防止过拟合和梯度爆炸/消失问题,而恰巧这种操作也会改变数据分布,进而加速了模型的收敛。

High resolution classifier(高分辨率图像分类器)

使用高分辨率图像进行训练

Convolution with anchor boxes(使用先验框)

学习RPN使用先验框,这种操作基于的理论是:“模型学习拟合偏移量相对于学习直接拟合出坐标操作会更加容易”(题外话,当时ResNet的残差结构也看到了这种说法)

简单说就是预先设定一些检测框,然后在训练的过程中去调整这些检测框(这个过程就是在学习偏移量)

Dimension clusters(聚类提取先验框的尺度信息)

更科学与更准确的选择Anchor Box的尺寸

Direct location prediction(约束预测边框的位置

借鉴Faster RCNN的先验框方法来限制预测框的位置。预测边框的中心可能出现在任何位置,训练早期阶段不容易稳定。YOLO调整了预测公式,将预测边框的中心约束在特定gird网格内

Fine-Grained Features(passthrough层检测细粒度特征)

对象检测面临的一个问题是图像中对象会有大有小,输入图像经过多层网络提取特征,最后输出的特征图中(比如YOLO2中输入416*416经过卷积网络下采样最后输出是13*13),较小的对象可能特征已经不明显甚至被忽略掉了。为了更好的检测出一些比较小的对象,最后输出的特征图需要保留一些更细节的信息。

YOLO2引入一种称为passthrough层的方法在特征图中保留一些细节信息。具体来说,就是在最后一个pooling之前,特征图的大小是26*26*512,将其1拆4,直接传递(passthrough)到pooling后(并且又经过一组卷积)的特征图,两者叠加到一起作为输出的特征图。
 

Multi-ScaleTraining(多尺度图像训练)

这个很好理解,区别于之前的补全图片的尺寸的方法,YOLOv2每迭代几次都会改变网络参数。每10个Batch,网络会随机地选择一个新的图片尺寸

Hi-res detector(高分辨率图像的对象检测)

图1表格中最后一行有个hi-res detector,使mAP提高了1.8。因为YOLO2调整网络结构后能够支持多种尺寸的输入图像。通常是使用416*416的输入图像,如果用较高分辨率的输入图像,比如544*544,则mAP可以达到78.6,有1.8的提升。

Hierarchical classification(分层分类)

作者提出了一种在分类数据集和检测数据集上联合训练的机制。使用检测数据集的图片去学习检测相关的信息,例如bounding box 坐标预测,是否包含物体以及属于各个物体的概率。使用仅有类别标签的分类数据集图片去扩展可以检测的种类。

作者通过ImageNet训练分类、COCO和VOC数据集来训练检测,这是一个很有价值的思路,可以让我们达到比较优的效果。通过将两个数据集混合训练,如果遇到来自分类集的图片则只计算分类的Loss,遇到来自检测集的图片则计算完整的Loss。

这部分还要解决一个标签的多对一问题,有机会再说

YOLOv3

YOLOv3给人的感觉就像是:一个时代的必然产物,简单说就是引入现阶段效果比较好的trick

改进之处

1.多尺度预测 (引入FPN)。
2.更好的基础分类网络(darknet-53, 类似于ResNet引入残差结构)。
3.分类器不再使用Softmax,分类损失采用binary cross-entropy loss(二分类交叉损失熵)

多尺度预测

每种尺度预测3个box, anchor的设计方式仍然使用聚类,得到9个聚类中心,将其按照大小均分给3个尺度.

尺度1: 在基础网络之后添加一些卷积层再输出box信息.

尺度2: 从尺度1中的倒数第二层的卷积层上采样(x2)再与最后一个16x16大小的特征图相加,再次通过多个卷积后输出box信息.相比尺度1变大两倍.

尺度3: 与尺度2类似,使用了32x32大小的特征图.

基础网络修改为Darknet-53

Darknet-53是一种仿ResNet的结构, 与ResNet-101或ResNet-152准确率接近,但速度更快。

Softmax和Logistic的不同 

理论上Logistic被应用于一个二分类的问题,而Softmax用于完成多分类的任务,但是我们完全可以在最后一层设定类别个数的全连接层,每一层使用Logistic,从而完成多分类任务。

他们之间的区别是在一个多分类任务中,如果类别是互斥的使用Softmax,因为Softmax类似于onehot编码,只能有一个被激活;如果类别是不互斥的可以使用Logistic,可能同时激活多个单元。

YOLOv4

YOLOv4的特点是集大成者,俗称堆料。但最终达到这么高的性能,一定是不断尝试、不断堆料、不断调参的结果,给作者点赞。具体使用了:

Weighted-Residual-Connections (WRC),  Cross-Stage-Partial-connections (CSP)
Cross mini-Batch Normalization (CmBN),  Self-adversarial-training (SAT)
Mish-activation ,  Mosaic data augmentation
DropBlock regularization, CIoU loss

YOLOv4框架

Backbone:CSPDarknet53, Neck:SPP,PAN, Head:YOLOv3
YOLOv4 = CSPDarknet53+SPP+PAN+YOLOv3

YOLOv5

因为YOLOv5没有论文,我大多数是参考了这篇博客:https://blog.csdn.net/l641208111/article/details/109286497和https://zhuanlan.zhihu.com/p/326284473?ivk_sa=1024320u

其实YOLOv5版本相对于YOLOv4版本没有太多的改进,但是在速度与模型大小上比yolo4有较大提升,可以认为是通过模型裁剪后的工程化应用(即推理速度和准确率增加、模型尺寸减小)。

但不可否认,这也是一种很重要、很被需要的过程。从以下几个方面说明yolo5的改进之处

Data Augmentation

YOLOv4使用了多种数据增强技术的组合,对于单一图片,使用了几何畸变,光照畸图像,遮挡(Random Erase,Cutout,Hide and Seek,Grid Mask ,MixUp)技术,对于多图组合,作者混合使用了CutMix与Mosaic 技术。除此之外,作者还使用了Self-Adversarial Training (SAT)来进行数据增强。

YOLOv5会通过数据加载器传递每一批训练数据,并同时增强训练数据。数据加载器进行三种数据增强:缩放,色彩空间调整和马赛克增强。据悉YOLOv5的作者Glen Jocher正是Mosaic Augmentation的创造者,故认为YOLOv5性能巨大提升很大程度是马赛克数据增强的功劳,也许你不服,但他在YOLOv4出来后的仅仅两个月便推出YOLOv5,不可否认的是马赛克数据增强确实能有效解决模型训练中最头疼的“小对象问题”,即小对象不如大对象那样准确地被检测到。

Mosaic Augmentation是CutMix Augmentation的增强版,使用四张图片进行拼接。

Auto Learning Bounding Box Anchors-自适应锚定框

YOLOv3中的锚框是预先利用kmeans定义好的,YOLOv4沿用了YOLOv3;

YOLOv5锚定框是基于训练数据自动学习的。个人认为算不上是创新点,只是手动改代码改为自动运行。

对于自定义数据集来说,由于目标识别框架往往需要缩放原始图片尺寸,并且数据集中目标对象的大小可能也与COCO数据集不同,因此YOLOv5会重新自动学习锚定框的尺寸。 

Activation Function

YOLOv5的作者使用了 Leaky ReLU和Sigmoid激活函数。YOLOv5中中间/隐藏层使用了 Leaky ReLU激活函数,最后的检测层使用了Sigmoid形激活函数。而YOLOv4使用Mish激活函数

Optimization Function

YOLOv5的作者提供了两个优化函数Adam和SGD(默认),并都预设了与之匹配的训练超参数,而YOLOv4使用SGD。

YOLOv5的作者建议是,如果需要训练较小的自定义数据集,Adam是更合适的选择,尽管Adam的学习率通常比SGD低。但是如果训练大型数据集,对于YOLOv5来说SGD效果比Adam好。

实际上学术界上对于SGD和Adam哪个更好,一直没有统一的定论,取决于实际项目情况。

这里可以看出,YOLOv5确实是YOLOv4工程上的优化(指的是这不就是调优)

Cost Function

YOLO系列的损失计算是基于 objectness score, class probability score,和 bounding box regression score。YOLOv5使用GIOU Loss作为bounding box的损失。

YOLOv5使用二进制交叉熵和 Logits损失函数计算类概率和目标得分的损失。同时我们也可以使用fl _ gamma参数来激活Focal loss计算损失函数。YOLOv4使用 CIOU Loss作为bounding box的损失,与其他提到的方法相比,CIOU带来了更快的收敛和更好的性能。

YOLO-ALL

YOLO-ALL将各个版本的YOLO进行了对比,效果被很直观地展示

链接为:https://mp.weixin.qq.com/s/SaX9oB7lrrKF4nFX0Or2ww

YOLO与RCNN系列的不同

这个问题其实问的是one-stage和two-stage的不同

1.统一网络:YOLO没有显示求取region proposal的过程。Faster R-CNN中尽管RPN与fast rcnn共享卷积层,但是在模型训练过程中,需要反复训练RPN网络和fast rcnn网络.相对于R-CNN系列的"看两眼"(候选框提取与分类),YOLO只需要Look Once.
2. YOLO统一为一个回归问题,而R-CNN将检测结果分为两部分求解:物体类别(分类问题),物体位置即bounding box(回归问题)。

YOLO与SSD系列的不同

首先要明确SSD值介于YOLOv1和YOLOv2之间的产物,对比YOLO和SSD基本上就是对比SSD和YOLOv1,且YOLOv2很大程度上借鉴了SSD的一些思想

SSD使用了多尺度特征去做预测;SSD使用卷积去做预测而不是全连接去预测;SSD在YOLOv1和YOLOv2之间,使用了先验框

对了,我记得SSD还有一点比较特殊就是背景会算做一个类别,后续查一下是不是一个比较独特的操作

YOLOv1-v5的概括

每个版本的提升

v1版本是普通的划分网格、锚点落于区域负责判定,预测4个坐标值,1个置信度和一个类别;v2版本主要引入了BN(YOLOv1时还没有提出)、聚类得到的先验框(预测偏移比直接预测位置要容易)、多尺度训练和分层训练;v3版本引入多尺度预测 (引入FPN)、更好的基础分类网络(darknet-53, 类似于ResNet引入残差结构)、分类器不再使用Softmax,分类损失采用binary cross-entropy loss(二分类交叉损失熵)、锚框是不是由kmeans得到的而是学习到的;v4版本引入了很多的trick;v5版本更像是对v4版本工程化的剪枝与调参、倒是引入了作者之前提出的马赛克数据增强算是一个创新点。

如何提升YOLO对小目标检测的精度

这个问题要从不同版本的角度去分析,比如针对v1版本,可以说v2版本的聚类得到的先验框回归偏差可能会解决小目标检测问题。针对v2可以说v3的多尺度预测、更好的分类网络都能提升对小目标的检测准确率。针对v3可以说v4众多的trick的引入使得网络性能巨大的提升,自然就比v3小目标监测准确率高。

要是针对v5,或者说针对整个base YOLO的模型,那解决的方法就是类似SSD那样在每个尺度的特征图上抽样送入末端卷积层去处理,自然对小目标的检测率会提升,比如说base EfficiNet模型。

或者说效仿base Transformer模型将输入图片划分为多个patch,然后在末端去使用like RCNN去处理,有放大局部目标物体的作用。

为什么YOLO模型的准确率相对来说比较低

1.YOLO系列模型主要思路就是均匀地在input image上不同位置进行密集抽样,抽样时可以采用不同尺度和长宽比,然后利用backbone CNN提取特征后直接进行分类和回归,整个过程只需要一步,所以优势在于速度快,但是均匀密集采样的一个重要缺点就是训练比较困难,这主要是因为正样本和负样本极度不均衡,导致模型准确度比较低

要说怎么提升准确率和上面的答案差不多,基本就是按照每个版本的改进去说

2.对小目标检测的准确率较低

如何解决参照上面论述

reference

链接1:https://mp.weixin.qq.com/s/pIuRNS_ocllG5SOqpskBFA
链接2:https://blog.csdn.net/lemonbit/article/details/109281590