关于yolo3论文的学习

本文详细解读了YOLO3的性能改进,包括数据加载bug修复、多尺度输出处理、正负样本设定、预测框计算调整和lossfunction的变化。着重讨论了置信度和IoU在模型中的角色,并与Yolo2进行了对比。
摘要由CSDN通过智能技术生成

https://www.bilibili.com/video/BV1Vg411V7bJ?p=2&spm_id_from=pageDriverhttps://www.bilibili.com/video/BV1Vg411V7bJ?p=2&spm_id_from=pageDrivericon-default.png?t=M276https://www.bilibili.com/video/BV1Vg411V7bJ?p=2&spm_id_from=pageDriver

 

这就是这张经典的用以描述yolo3性能的图表,几乎还是老样子,快的没他准,准的没他快

在描述中,yolo3修复了yolo2中数据加载的一个bug,这提升了2%的map.这相对于Yolo2的其他组件,这个提升还是挺高的

这个加载数据的bug为什么会造成精度下降呢???难道是跟batch size有关系

 yolo3借鉴了很多其他网络的有效的想法,前一篇文章我们已经描述了yolo3的创新:

发展了细粒度特征这一点,yolo3的全卷积网络最终有三种分辨率的feature map输出

借鉴resnet,将之前的backbone darknet19换成了darknet53

继续沿用了yolo2当中分类网络和定位网络这样的思路,并发展了这种结构

 bounding box prediction:检测框的预测

预测框的位置和尺寸计算沿用的yolo2的思路

YOLO3中关于正负样本的设定

这是一个很关键的问题,在前两个版本的论文中根本没有专门提过这件事。最接近的也就是yolo2增加的anchor机制极大地提升了recall的数量

在说到正负样本之前,我们需要先讨论yolo3中在多尺度输出条件下的预测后处理啊。实际上和yolo之前版本的处理一摸一样。yolo3有三种尺度,13*13*85,26*26*85,52*52*85,按照yolo1的思路,所有的bounding box的全类别概率会先做横向比较,利用极大值抑制来清理冗余,再进行纵向对比,最终确定bbox的实际类别

 只不过是到了yolo3,预测框的数量变成了一万出头

从yolo1开始,loss function中就有一个参数叫做置信度标签,用来描述某个bbox是否有资格预测目标,它的值只有0,1,不像是confidence.我最初认为confidence只能是0,1,因为它是用来表征该bbox是否负责预测目标。之后才知道,在实际计算中,为了类别概率,置信度的值就是该bbox和标注框的IoU.

但如果是这样的话,我们说置信度的值是通过网络训练得到的吗??按照训练上的描述,置信度和bbox的中心坐标、宽高一样,都是通过网络训练得到的。但这里我觉得有些不通顺??

 这里说是用与标注框IoU最大的那个bbox来负责预测目标,yolo1每个grid cell只有两个预测框,yolo2有5个预测框

虽然yolo2没有讲这一点,他的论文甚至都没有提到关于loss function的设计,但我认为从结构上的相似性出发,yolo3应该是沿用了yolo2的处理方式,而且在理解方式上与我们从yolo1中得到没有出入

但是后面提到这个IoU的计算方式,要求中心点对齐??之前我认为应该是直接计算,这样置信度就有可能为0,如果是要求先进行中心点对齐,那么置信度就一定不为0

QUESTIONMARK:另外,我不知道是在处理loss function中的置信度标签的时候才以对齐中心点 的方式计算IoU,还是说置信度阶段就是以这种方式进行计算。诶,如果说置信度是通过网络训练得到的,他就不可能以这种方式计算啊???和上面的一个疑问连起来了

 我前面好像是理解错了,需要判断置信度的值和置信度标签值是不是一个东西。我在前文中认为置信度标签值是loss function的那个只有0,1两个值的参数,但似乎在这里他们是一个东西

这句话似乎就证明了我的判断 

在yolo3中同属于一个grid cell的预测框中负责拟合目标的预测框的置信度就是1,不再是像之前的两个版本,全都使用IoU来作为置信度。那么yolo3计算全类别概率的计算过程一定会发生改变

仔细想想,前面关于置信度的理解偏差似乎是来源于我对这个值有一种过分的信任,以至于我认为作为卷积网络一部分的置信度居然不是由网络训练的出的,这里可以明确地判断:置信度就是通过网络训练得出的

 这是Yolo1的loss function中关于置信度误差的部分

预测值:就是通过训练得到的置信度的值

标签值:这个值肯定与标注框有关系,而且是通过计算得到的。计算该bbox与标注框的IoU

哪,从最开始学习损失函数的结构,我可能就先验地认为标注值是不可能和预测值发生关联的,他们是两不相交的两个部分。但是在这里,标签值需要计算bbox和标注框的IoU,这确实是没有想到

但是还有一点

这个p(object)的值怎么得到???从哪里来的???

从相应地损失函数的机构来看,这个值应该是默认为1,前面还有一个0,1参数,用来判断该bbox是否负责预测目标

那么bbox是否负责拟合目标的判断依据是什么???

难道是直接比较训练出来的,属于同一个grid cell的两个预测框的置信度的值?谁更高,谁就负责拟合目标

 那么,综合上述最新的判断,在yolo3中,每个预测框的置信度仍然是通过网络训练得出的,但是在计算相应的置信度误差的时候,就不再像yolo1或yolo2那样,使用IoU作为标签,而是直接将其变成一个取值0,1的参数

所以说这个改动并不会影响全类别概率的计算,全类别概率仍然是通过网络计算得出的置信度和条件类别概率相乘得到的,影响的只是损失函数的计算

 相对于yolo2,这里补充了一点,怎么还原预测框的中心坐标,需要乘上下采样的倍数。预测框的宽高就是实际宽高,不需要还原

这里有说明了一次,和之前的两个版本一样,预测框的中心坐标都是被限制在其所属的grid cell里面

这个忽略影响的是什么??预测后处理??还是像前面关于置信度标签值的改动,影响的是loss function的计算??

 注意这句话,如果能够以这句话为依据,那么基本可以判断,影响的是loss function的计算

这条改动参考的是faster RCNN

yolo3又有和faster RCNN不同的地方,他设置了一个IoU的阈值,高于这个阈值且是最大值得bbox负责拟合目标,只有他一个作为正样本

相当于每个标注框只有一个与其IoU最大的标注框负责拟合。yolo1中因为只有两个预测框,肯定只有一个预测狂负责拟合标注框,到了yolo2,每个grid cell有5个预测框,在计算loss function的时候,有几个预测框会产生贡献呢???一个???

注意啊,不管是哪个版本得yolo,计算loss function都是要遍历所有得预测框。yolo1一共有49个grid cell, 98个预测框,最终产生贡献的预测框是49个

yolo2一共有169个grid cell,845个预测框,根据yolo2得loss function,最终产生贡献得预测框是多少个???

中间得那些bbox全部忽略。这个唯一的正样本,将对loss function中得分类、定位、置信度误差全部产生影响,即贡献

IoU小于这个阈值得bbox就会被判定为负样本,负样本只对置信度误差产生贡献

 

 到yolo3的时代,根据以上一系列得描述,每个grid cell最终只有一个预测框负责拟合目标,那么产生贡献得预测框应该是13*13 + 26*26 + 52*52 = 3549

 这里甚至说明了,一个grid cell是允许没有预测框负责拟合目标的

关于正负样本得再讨论:

之前我并不清楚为什么要去做正负得设定,而且在yolo得前两个版本得论文中,并没有讨论过正负样本得使用问题。在这里,通过前文的一系列描述,正负样本与loss function得计算时直接相关得。他决定了那些样本要去做那些计算

可能以前我自己认为每个样本得输出肯定都需要送进loss function中去计算每一个项,但通过yolo3得描述,只有正样本才会计算loss function中得每一项,负样本是不需要得,而介于正负样本之间得样本是不需要进行任何误差计算得

class prediciton:多类别标注与分类

这个地方说的挺复杂,但是提到了softmax和交叉熵,所以我判断这又是一个在loss function上得改动

什么叫多类别分类标签,multilable classificaiton??

loss function中有个分类误差, 这里提到不再使用softmax,而是使用二分类交叉熵损失

一说到分类误差,我想起来,从yolo2开始,就提到网络训练分成两个阶段,网络结构在两个阶段也是不一样得,那么两个阶段得loss function会有什么不同呢???

至少有一点,分类预训练阶段应该会删掉loss function 中得定位误差,置信度误差。那等到定位网络得训练的时候,使用得是不是完全体的loss function呢???很有可能

由另一篇文章的分析,我们具体谈一谈在正负样本背景下模型的迭代过程:

权重的更新值是由loss function的导函数得出的,要带入某样本的输出值

注意,这里的正负样本中的样本和我们训练说的样本不是一个意思。前者的样本指的是每个训练样本生成的那10000多个bbox,所以应该说的是每个训练样本的loss function的结构是不同的,因为每个训练样本的bbox划分正负样本的数量是不同的

自然,每个样本对应的loss function的导函数的结构就是不同的,虽然实际的结构是不同的,但是带上0,1参数,结构就是统一的,服从同一套计算方法

class prediciton:多类别标注与分类

 这里说softmax经过实验,对于实验结果并没有那么多的正向作用

 这里提到使用逻辑回归,就是sigmoid函数

突然提到多类别标注与分类,我是比较懵逼的。只能先验地给一个抓手,这东西最终还是为了改进loss function

 这里提到softmax会假设所有类别都是互斥的,即我们的标注必须是样本中的每个目标必须是独立的唯一的类别

但是,yolo3采用了多类别标签的思路,一个目标可能有多个类别,这种方式的好处是可以更好地建模组织

 在之前的两个版本中,模型训练的出每个预测框的条件类别概率,通过与网络训练的出的置信度可以求出每个预测框的全类别概率。yolo3的这种求解是怎么回事

在进行分类与训练的时候,不需要输出类别概率

进行定位网络fine tuning 的时候,没有见到相应的逻辑回归部件????

predictions across scales:多尺度目标检测

yolo2当中提到的多尺度是多尺度融合训练,是指在分类网络的预训练阶段向网络输入不同尺度的图像,以让网络适应不同尺度的特征。为了实现这一点,设置了全局平均池化层,同时要求设计的网络必须保证全局平均池化层的输入的channel是相等的,feature map的分辨率可以不同

到了定位网络fine tuning 的阶段,是不需要再进行这样的训练

yolo2中融合不同处理阶段特征的部分很容易被误解为多尺度。融合特征这种操作应该叫做fine grained training,细粒度特征训练

yolo3的多尺度指的就是fine tune阶段全卷积网络输出的三种分辨率的feature map ,13*13,26*26,52*52

 

在说道yolo3的时候,提到一个数量关系,下采样的倍数就是第一层卷积层输出的feature map的边长

淦,我一直理解错了,我以为filter的尺寸叫做感受野,一直把feature map的尺寸用的分辨率,还可以用尺度

yolo3的下采样倍数是固定的三个值:8,16,32

K均值聚类在coco数据集上的聚类结果,一共是9个anchor.如果要做一些改进的话,可以使用knn++聚类算法生成。在yolo2,anchor机制带来的map的提升是最大的

feature extractor:特征提取,即backbone的改进

新的backbone基于yolo2的darknet19,融合了resnet

  这个网络结构实际上是用于分类预训练的分类网络,等到进行定位fine tuning 的时候,需要去掉分类头以及细粒度特征融合部件,换上定位网络需要的定位头,最终进行推断的时候使用的就是训练好的定位网络

之前还没有注意到这个细节,用于下采样的池化层用的是一个stride = 2的3*3卷积替代了

之前我还说必须要学会推断卷积操作后feature map的尺寸,因为这是设计网络的一个必备技能

这里的计算显示,按照步长为1的3*3卷积,输出的feature map的尺寸还对不上。这就意味着在实际的程序中,是少算了一圈卷积的

再论网络结构

受到yolo2的影响,其实yolo3的定位网络是可以输出任意尺度的feature map的,它的兼容性更好了。当然这得益于从yolo2就是用的全卷积网络思想,直接将feature map作为输出了

在最开始学习CNN的时候,我认为是必须要在CNN后面加上FC层的,在RCNN论文中也提到,CNN提取的更多是通用特征,FC可以提取特定领域的特征,他做了大量的对比试验去证明pool5, fc6, fc7的作用,对模型性能的贡献

yolo3相对于yolo2的定位网络做了一个三叉的分支,由此输出三种尺度的feature map

其实我一直想搞清楚模型是如何减少运算量的??在我们平时写的程序中,要想优化某些计算,至少要减少重复计算,增加已经计算出的结果的复用率,或者是优化计算公式

这里将到resnet152之所以慢,很大程度上是因为网络太深了,虽然resnet解决了网络衰减的问题

yolo3的训练:

 yolo3在训练上没有采用RCNN用的难例挖掘,我记得在之前那个商业项目上也是用了难样本挖掘的方案以提升模型的精度。子豪兄说,难样本挖掘就是做了一个记录,将某些Loss特别离谱的样本记录下来,增加他们的权重

呐,实际上hard negative mining和BN层、anchor机制、多尺度训练、细粒度特征融合等措施一样,最终都是为了让模型更准,因此,他不一定是必要的。况且,对于yolo这套统一的训练算法来说,难样本挖掘会破坏这种统一

mAP50的计算:

 

这里提到了两个阈值,一个称之为置信度阈值p_thresh,一个是iou_thresh。基准是预测框和标注框的交并比,如果不涉及非极大值抑制,那怎么产生的这两个阈值呢????

因为AP的计算涉及到PR曲线,因此也就涉及到precision 和 recall的计算

这里可以再重复一下关于混淆矩阵的知识:

true positive:正确 正例 正例

true negative:正确 反例 反例

false positive:错误 反例 正例

false negative:错误 正例 反例

注意啊,这里说的是与标注框的关系,不是在预测后处理那个位置

我们首先要确定正例是什么??在子豪兄这里,正例是波磨,反例就是其他类别。tp+fp就是所有预测为正例的情况,其总数可以引申为所有预测框吗???

tp+fn应该是表示真正的正例的数量。既然是真正的正例,自然可以由标注框的数量来确定

从数量上来看,precision肯定是要比recall小的,因为他们分子相同,而预测框的数量肯定是大于标注框的数量

我先假设p_thresh就是在预测后处理阶段设置的那个置信度阈值

mAP不是简单地对多个类别的AP求平均,如果是简单平均,就应该叫做macro-recall以及macro-precision

子豪兄这里说,每一套置信度阈值生成一组混淆矩阵,就是tp,tn,fp,fn的取值不同;然后每一套混淆矩阵算一组recall 和 precision

一个AP的计算是基于一个置信度阈值,mAP后面的0.5表示选取的iou阈值为0.5,这里对两个阈值的作用还是不清楚???

AP的计算公式,但是积分函数的这个形式很容易产生误解,最重要的还是这个r的含义,r就是置信度阈值,积分范围前面就说了0,1之间,积分函数肯定是关于置信度阈值的一个函数,这个函数由recall、precision和置信度阈值的函数关系来确定

经过一番激烈的头脑风暴,我想我已经想通了置信度阈值和iou阈值究竟是什么了

首先,我将这两个阈值用来和预测后处理阶段的两个阈值做类比是完全可行的,而且他们两个的思路也是比较一致的

要先确认一点,预测后处理是一种处理,计算AP也是一种处理

预测后处理的置信度阈值是用来判断预测框能否是一个预测框

计算AP的置信度阈值是用来初步判断这个预测框是混淆矩阵的哪一类

预测后处理的nms阈值由预测框和标注框的iou,用来清除冗余

计算AP的iou阈值也是由预测框和标注框的iou,用来最终确定预测框是混淆矩阵的哪一类

那么综上所述:分为两种计算流程

1.只计算AP:确定好置信度阈值,混淆矩阵的判定标准就不再包含iou阈值

2.AP50:此时已经确定iou阈值为0.5,遍历0-1的置信度阈值,确定相应的混淆矩阵

从yolo1以来,yolo一直都在致力于解决精度问题,yolo1对于小目标、密集目标识别能力差,yolo2增加了预测框的数量以及anchor机制来改善定位问题,到了yolo3仍然存在定位能力相对更差的问题。其他的目标检测算法也在发展,他们更注重于在保证精度的前提下怎么提速 

 

 数据显示,相较于其他目标检测算法,yolo3把小目标的精度提升了,但是中等和大目标的精度又被其他算法超过了,真是一个问题叠着一个问题啊

一些不太奏效的tricks 

这里又提到了难样本挖掘,子豪兄说负样本从某种意义上看和难样本就是等价的,那么难样本的评价标准是什么???负样本的标准就是那些连iou_thresh阈值都达不到的样本

faster-RCNN采用双iou阈值来做正负样本的分离。但在yolo中这是不奏效的

yolo为什么会缺少高质量的负样本??还有哪些算法缺少负样本??什么是高质量的负样本

imagenet的作者russakovsky教授说,人类对于iou的细微差别是很难分辨的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值