以前的算法:通过regioin proposal产生大量的可能包含待检测物体的potential bounding box,再用分类器去判断每个bounding box里是否含有物体及其所属类别的概率或置信度。(比如:R-CNN,Fast-R-CNN,Faster-R-CNN)
YOLO算法:把目标检测看做是一个regression问题来处理,通过一个神经网络,直接从一张图像中预测出bbox的坐标、包含物体的置信度和所属物体类别的概率。因为YOLO的物体检测流程是在一个神经网络中完成的所以可以end to end来优化物体检测性能。
DPM:要使用一个滑窗(sliding window)在整张图像上均匀滑动,用分类器评估是否有物体。
R-CNN:使用region proposal来生成整张图像中可能包含待检测物体的potential bounding boxes,然后用分类器来评估这些boxes,接着通过post-processing来改善bounding boxes,消除重复的检测目标,并基于整个场景中的其他物体重新对boxes进行打分。整个流程执行下来很慢,而且因为这些环节都是分开训练的,检测性能很难进行优化。
YOLO:将物体检测任务当做回归问题(regression problem)来处理,直接通过整张图片的所有像素得到bounding box的坐标、box中包含物体的置信度和class probabilities。通过YOLO,每张图像只需要看一眼就能得出图像中都有哪些物体和这些物体的位置。
如图所示,使用YOLO来检测物体,其流程是非常简单明了的:
1、将图像resize到448 * 448作为神经网络的输入
2、运行神经网络,得到一些bounding box坐标、box中包含物体的置信度和class probabilities
3、进行非极大值抑制,筛选Boxes
下图是各物体检测系统的检测流程对比:
YOLO的优点:
1.YOLO检测物体非常快。
因为没有复杂的检测流程,只需要将图像输入到神经网络就可以得到检测结果,YOLO可以非常快的完成物体检测任务。标准版本的YOLO在Titan X 的 GPU 上能达到45 FPS。更快的Fast YOLO检测速度可以达到155 FPS。而且,YOLO的mAP是之前其他实时物体检测系统的两倍以上。
2.YOLO可以很好的避免背景错误,产生false positives。
不像其他物体检测系统使用了滑窗或region proposal,分类器只能得到图像的局部信息。YOLO在训练和测试时都能够看到一整张图像的信息,因此YOLO在检测物体时能很好的利用上下文信息,从而不容易在背景上预测出错误的物体信息。和Fast-R-CNN相比,YOLO的背景错误不到Fast-R-CNN的一半。
3.YOLO可以学到物体的泛化特征。
当YOLO在自然图像上做训练,在艺术作品上做测试时,YOLO表现的性能比DPM、R-CNN等之前的物体检测系统要好很多。因为YOLO可以学习到高度泛化的特征,从而迁移到其他领域。
YOLO的缺点:
一张图分为S*S个格子,每个格子负责检测中心落在该格子中的物体。一个格子预测B个bbox,每个bbox有个置信度,一共有C个类别。这个置信度反应了模型对于这个格子的预测:该格子是否含有物体(用表示),以及这个bbox的坐标预测有多准。(用IOU来表示)
Conditional class probability信息是针对每个网格的,Confidence信息是针对每个bbox的。二者相乘得到了每个bbox中物体的具体类别的confidence score。
格子不存在物体:confidence=0
格子存在物体:confidence=IOU
YOLO对每个bounding box有5个predictions:x, y, w, h, confidence。
1.坐标x,y代表了预测的bounding box的中心与栅格边界的相对值。
2. 坐标w,h代表了预测的bounding box的width、height相对于整幅图像width,height的比例。
3.confidence就是预测的bounding box和ground truth box的IOU值。
在本文中,S=7,B=2,C=20。最后得到的prediction是一个7*7*30的Tensor(7*7*(B*5+C))。
Yolo采用卷积网络来提取特征,然后使用全连接层来得到预测值。网络结构参考GooLeNet模型,包含24个卷积层和2个全连接层。不同的是,YOLO未使用inception module而是主要使用1x1卷积来做channel reduction,然后紧跟3x3卷积。对于卷积层和全连接层,采用Leaky ReLU激活函数:max(x,0.1x)。但是最后一层却采用线性激活函数。除了上面这个结构,文章还提出了一个轻量级版本Fast Yolo,其仅使用9个卷积层,并且卷积层中使用更少的卷积核。
在训练之前,先在ImageNet上进行了预训练,其预训练的分类模型采用图8中前20个卷积层,然后添加一个average-pool层和全连接层。预训练之后,在预训练得到的20层卷积层之上加上随机初始化的4个卷积层和2个全连接层。由于检测任务一般需要更高清的图片,所以将网络的输入从224x224增加到了448x448。整个网络的流程如下图所示:
损失函数的设计目标就是让坐标(x,y,w,h),confidence,classification 这个三个方面达到很好的平衡。
简单的全部采用了sum-squared error loss来做这件事会有以下不足:
a)8维的localization error和20维的classification error同等重要显然是不合理的。
b) 如果一些栅格中没有object(一幅图中这种栅格很多),那么就会将这些栅格中的bounding box的confidence 置为0,相比于较少的有object的栅格,这些不包含物体的栅格对梯度更新的贡献会远大于包含物体的栅格对梯度更新的贡献,这会导致网络不稳定甚至发散。
解决方案如下:
更重视8维的坐标预测,给这些损失前面赋予更大的loss weight, 记为 λcoord ,在pascal VOC训练中取5。(上图红色框)
对没有object的bbox的confidence loss,赋予小的loss weight,记为 λnoobj ,在pascal VOC训练中取0.5。(上图绿色框)
有object的bbox的confidence loss (上图橙色框) 和类别的loss (上图蓝色框)的loss weight正常取1。
对不同大小的bbox预测中,相比于大bbox预测偏一点,小box预测偏相同的尺寸对IOU的影响更大。而sum-square error loss中对同样的偏移loss是一样。
为了缓和这个问题,作者用了一个巧妙的办法,就是将box的width和height取平方根代替原本的height和width。 如下图:small bbox的横轴值较小,发生偏移时,反应到y轴上的loss(下图绿色)比big box(下图红色)要大。
在 YOLO中,每个栅格预测多个bounding box,但在网络模型的训练中,希望每一个物体最后由一个bounding box predictor来负责预测。
因此,当前哪一个predictor预测的bounding box与ground truth box的IOU最大,这个predictor就负责predict object。
这会使得每个predictor可以专门的负责特定的物体检测。随着训练的进行,每一个 predictor对特定的物体尺寸、长宽比的物体的类别的预测会越来越好。
https://blog.csdn.net/hrsstudy/article/details/70305791?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase
https://blog.csdn.net/shengyan5515/article/details/84036734
https://blog.csdn.net/shuiyixin/article/details/82533849
https://zhuanlan.zhihu.com/p/68308825
代码
非极大值抑制(Non maximum suppression)
并交比(IOU)与非极大值抑制的代码实现