YOLOv1学习笔记

reference:

https://zhuanlan.zhihu.com/p/32525231

https://blog.csdn.net/tangwei2014/article/details/50915317

与R-CNN网络的区别:

比较流行的算法可以分为两类:

  • 一类是基于Region Proposal的R-CNN系算法(R-CNN,Fast R-CNN, Faster R-CNN),它们是two-stage的,需要先使用启发式方法(selective search)或者CNN网络(RPN)产生Region Proposal,然后再在Region Proposal上做分类与回归。算法准确度高一些,但是速度慢
  • 另一类是YOLO,SSD这类one-stage算法,其仅仅使用一个CNN网络直接预测不同目标的类别与位置。算法的速度快,但是准确性要低一些。

设计理念/核心思想:

YOLO的核心思想就是:YOLO将物体检测作为一个回归问题进行求解,利用整张图作为网络的输入,直接在输出层回归bounding-box的位置和bounding-box所属的类别

虽然faster RCNN中也直接用整张图作为输入,但是faster-RCNN整体还是采用了RCNN那种 proposal+classifier的思想,只不过是将提取proposal的步骤放在CNN中实现了。

                                            

具体实现:

<<1>>

将一幅图像分成SxS个网格(grid cell),如果某个object的中心 落在这个网格中,则这个网格就负责预测这个object。 如下图所示,可以看到狗这个目标的中心落在左下角一个单元格内,那么该单元格负责预测这个狗。

 

                                                              

<<2>>

每个单元格会预测 B 个边界框大小和位置(bounding box)以及边界框的置信度(confidence score)。

边界框的大小与位置可以用4个值来表征: (x, y,w,h) ,其中 (x,y) 是边界框的中心坐标,与grid cell对齐(即相对于当前grid cell的偏移值),使得范围变成0到1;而 wh 是边界框的宽与高,w和h进行归一化(分别除以图像的w和h,这样最后的w和h就在0到1范围)。

所谓置信度其实包含两个方面:

  • 一是这个边界框含有目标的可能性大小,记为 Pr(object) ,当该边界框是背景时(即不包含目标),此时 Pr(object)=0 。而当该边界框包含目标时, Pr(object)=1
  • 二是这个边界框的准确度,边界框的准确度可以用预测框与实际框(ground truth)的IOU(intersection over union,交并比)来表征,记为 \text{IOU}^{truth}_{pred}

因此置信度可以定义为 Pr(object)*\text{IOU}^{truth}_{pred} 。很多人可能将Yolo的置信度看成边界框是否含有目标的概率,但是其实它是两个因子的乘积,预测框的准确度也反映在里面。

总结每个bounding box都对应一个confidence score,如果grid cell里面没有object,confidence就是0,如果有,则confidence score等于预测的box和ground truth的IOU值,见上面公式。所以如何判断一个grid cell中是否包含object呢?答案是:如果一个object的ground truth的中心点坐标在一个grid cell中,那么这个grid cell就是包含这个object,也就是说这个object的预测就由该grid cell负责。 

<<3>>

每个边界框的预测值实际上包含5个元素: (x,y,w,h,c) ,其中前4个表征边界框的大小与位置,而最后一个值是置信度。其中坐标的x,y用对应网格的offset归一化到0-1之间,w,h用图像的width和height归一化到0-1之间对于每一个单元格其还要给出预测出 C 个类别概率值,其表征的是由该单元格负责预测的边界框其目标属于各个类别的概率。但是这些概率值其实是在各个边界框置信度下的条件概率,即 Pr(class_{i}|object)不管一个单元格预测多少个边界框,其只预测一组类别概率值,这是Yolo算法的一个缺点,在后来的改进版本中,Yolo9000是把类别概率预测值与边界框是绑定在一起的。

注意:class信息是针对每个网格的,confidence信息是针对每个bounding box的。

在test的时候,每个网格预测的class信息和bounding box预测的confidence信息相乘,就得到每个bounding box的边界框类别置信度(class-specific confidence scores):   Pr(class_{i}|object)*Pr(object)*\text{IOU}^{truth}_{pred}=Pr(class_{i})*\text{IOU}^{truth}_{pred}

等式左边第一项就是每个网格预测的类别信息,第二三项就是每个bounding box预测的confidence。这个乘积即预测的box属于某一类的概率,也有该box准确度的信息。边界框类别置信度表征的是该边界框中目标属于各个类别的可能性大小以及边界框匹配目标的好坏。

总结一下,每个单元格需要预测 (B*5+C) 个值。如果将输入图片划分为 S\times S 网格,那么最终预测值为 S\times S\times (B*5+C) 大小的张量。举例说明: 在PASCAL VOC中,图像输入为448x448,取S=7,B=2,一共有20个类别(C=20)。则输出就是7x7x30的一个tensor。 

<<4>>

test时候,每个bounding box的confidence和每个类别的score相乘,得到每个bounding box属于哪一类的confidence score。

最后会得到20*(7*7*2)=[20*98]的score矩阵,括号里面是bounding box的数量,20代表类别。接下来的操作都是20个类别轮流进行:在某个类别中(即矩阵的某一行),将得分少于阈值(0.2)的设置为0,然后再按得分从高到低排序。最后再用NMS算法去掉重复率较大的bounding box(NMS:针对某一类别,选择得分最大的bounding box,然后计算它和其它bounding box的IOU值,如果IOU大于0.5,说明重复率较大,该得分设为0,如果不大于0.5,则不改;这样一轮后,再选择剩下的score里面最大的那个bounding box,然后计算该bounding box和其它bounding box的IOU,重复以上过程直到最后)。最后每个bounding box的20个score取最大的score,如果这个score大于0,那么这个bounding box就是这个socre对应的类别(矩阵的行),如果小于0,说明这个bounding box里面没有物体,跳过即可。

总结得到每个box的边界框类别置信度(class-specific confidence score)以后,设置阈值,滤掉得分低的boxes,对保留的boxes进行NMS处理,就得到最终的检测结果。

网络设计:

YOLO采用卷积网络来提取特征,然后使用全连接层来得到预测值。网络结构参考GooLeNet模型,包含24个卷积层和2个全连接层。对于卷积层,主要使用1x1卷积来做channle reduction,然后紧跟3x3卷积。对于卷积层和全连接层,采用Leaky ReLU激活函数: max(x, 0.1x) ,解决ReLU死亡问题。但是最后一层却采用线性激活函数

可以看到网络的最后输出为 7\times 7\times 30 大小的张量。对于每一个单元格前20个元素是类别概率值然后2个元素是边界框置信度,两者相乘可以得到类别置信度,最后8个元素是边界框(x, y,w,h) 。边界框为什么把置信度 c(x, y,w,h) 都分开排列,而不是按照 (x, y,w,h,c) 这样排列?其实纯粹是为了计算方便,因为实际上这30个元素都是对应一个单元格,其排列是可以任意的。但是分离排布,可以方便地提取每一个部分。这里来解释一下,首先网络的预测值是一个二维张量 P ,其shape为 [batch, 7\times 7\times 30] 。采用切片,那么 P_{[:,0:7*7*20]} 就是类别概率部分,而 P_{[:,7*7*20:7*7*(20+2)]} 是置信度部分,最后剩余部分 P_{[:,7*7*(20+2):]} 是边界框的预测结果。这样,提取每个部分是非常方便的,这会方面后面的训练及预测时的计算。

损失函数:

Yolo算法将目标检测看成回归问题,所以采用的是均方差损失函数sum-squared error loss。但是对不同的部分采用了不同的权重值。

定位误差分类误差

均方差损失函数做法存在以下几个问题: 

  1. 8维的localization error和20维的classification error同等重要显然是不合理的; 
  2. 如果一个网格中没有object(一幅图中这种网格很多),那么就会将这些网格中的box的confidence push到0,相比于较少的有object的网格,这种做法是overpowering的,这会导致网络不稳定甚至发散。 
  3. 对不同大小的box预测中,相比于大box预测偏一点,小box预测偏一点肯定更不能被忍受的。而sum-square error loss中对同样的偏移loss是一样。

解决办法:

  1. 更重视8维的坐标预测,给这些损失前面赋予更大的loss weight, 记为\lambda _{coord}=5,在pascal VOC训练中取5。
  2. 对没有object的box的confidence loss,赋予小的loss weight,记为\lambda _{noobj}=0.5在pascal VOC训练中取0.5。
  3. 有object的box的confidence loss类别的loss的loss weight正常取1。
  4. 为了缓和这个问题,作者用了一个比较取巧的办法,就是将box的width和height取平方根代替原本的height和width。即预测值变为 (x,y,\sqrt{w}, \sqrt{h}) 

【注】由于每个单元格预测多个边界框。但是其对应类别只有一个。那么在训练时,如果该单元格内确实存在目标,那么只选择与ground truth的IOU最大的那个边界框来负责预测该目标,而其它边界框认为不存在目标。这样设置的一个结果将会使一个单元格对应的边界框更加专业化,其可以分别适用不同大小,不同高宽比的目标,从而提升模型性能。大家可能会想如果一个单元格内存在多个目标怎么办,其实这时候Yolo算法就只能选择其中一个来训练,这也是Yolo算法的缺点之一。要注意的一点时,对于不存在对应目标的边界框,其误差项就是只有置信度,坐标项误差是没法计算的。而只有当一个单元格内确实存在目标时,才计算分类误差项,否则该项也是无法计算的。

总结:

对于定位误差,即边界框坐标预测误差,采用较大的权重 \lambda _{coord}=5 。然后其区分不包含目标的边界框与含有目标的边界框的置信度,对于前者,采用较小的权重值 \lambda _{noobj}=0.5 。其它权重值均设为1。

                               

其中第一项是边界框中心坐标的误差项, 1^{obj}_{ij} 指的是第 i 个单元格存在目标,且该单元格中的第 j 个边界框负责预测该目标(IoU较大的边框负责预测该目标)。第二项是边界框的高与宽的误差项第三项是包含目标的边界框的置信度误差项第四项是不包含目标的边界框的置信度误差项。而最后一项是包含目标的单元格的分类误差项, 1^{obj}_{i} 指的是第 i 个单元格存在目标。这里特别说一下置信度的target值 C_i ,如果是不存在目标,此时由于 Pr(object)=0,那么 C_i=0 。如果存在目标, Pr(object)=1 ,此时需要确定 \text{IOU}^{truth}_{pred} ,当然你希望最好的话,可以将IOU取1,这样 C_i=1 ,但是在YOLO实现中,使用了一个控制参数rescore(默认为1),当其为1时,IOU不是设置为1,而就是计算truth和pred之间的真实IOU。不过很多复现YOLO的项目还是取 C_i=1 ,这个差异应该不会太影响结果吧。

训练与测试:

训练的时候:输入N个图像,每个图像包含M个objec,每个object包含4个坐标(x,y,w,h)和1个label。然后通过网络得到7*7*30大小的三维矩阵。每个1*30的向量前5个元素表示第一个bounding box的4个坐标和1个confidence,第6到10元素表示第二个bounding box的4个坐标和1个confidence。最后20个表示这个grid cell所属类别。注意这30个都是预测的结果。然后就可以计算损失函数的第一、二 、五行。至于第二三行,confidence可以根据ground truth和预测的bounding box计算出的IOU和是否有object的0,1值相乘得到。真实的confidence是0或1值,即有object则为1,没有object则为0。 这样就能计算出loss function的值了。

测试的时候:输入一张图像,跑到网络的末端得到7*7*30的三维矩阵,这里虽然没有计算IOU,但是由训练好的权重已经直接计算出了bounding box的confidence。然后再跟预测的类别概率相乘就得到每个bounding box属于哪一类的概率。
 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Yolov5是一个目标检测算法,它采用了和Yolov4一样的Mosaic数据增强方式,该方式由Yolov5团队的成员提出。Mosaic数据增强使用了随机缩放、随机裁剪和随机排布的方式进行拼接,对于小目标的检测效果很不错。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [YOLOv5 学习笔记](https://blog.csdn.net/W1995S/article/details/118114221)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [YOLOv5学习笔记](https://blog.csdn.net/qq_54809548/article/details/125403163)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [YOLOv5 自学笔记(持续更新)](https://blog.csdn.net/Mr_wjjianyan/article/details/128475887)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值