YOLO简介
YOLO(You Only Look Once)是一种目标检测的算法,他与之前的RCNN系列的算法有所不同,他舍弃了RCNN中生成proposal region的方法,而是对整张输入图片进行处理,类似于人眼对物体进行全局性的浏览,该算法的名字也因此而来。
RCNN系列算法由于都是基于region proposal方法,通过selected search等方法划分原始图像,并在不同的划分后的region分别训练使用分类器,这花费了巨大的时间,尽管fastCNN和fasterCNN共享了训练分类器的过程,但是生成proposal regions的过程任然消耗大量的时间。而YOLO算法则是直接对输入的图片划分为S*S的网格,在每个网格上回归得到B个回归框bounding boxes,即回归得到检测的目标框信息。由于这一原理特性,YOLO有着以下的优点:
YOLO的优点
- 训练和检测速度快:由于YOLO的网络结构是输入端到输出端端到端整合为一体的网络结构,而不是像RCNN或者FASTERRCNN或者其他滑窗sliding windows技术的算法一样是多个部分组合合成,需要分别训练。而且省去了proposal regions区域的时间。
- 能够考虑整张图片的整体信息:基于生成proposal regions操作的算法由于分类器都是在不同的regions上分别操作,是基于局部信息特征的提取,无法考虑整体图片全局的信息,这也是RCNN产生过多背景错误识别的原因。
YOLO v1的网络结构
将一幅图像分成SxS个网格(grid cell),如果某个object的中心 落在这个网格中,则这个网格就负责预测这个object。每个网格要预测B个bounding box,每个bounding box除了要回归自身的位置x、y、h、w之外,还要附带预测一个confidence值。 这四个位置信息都根据图片大小和网格大小归一到0到1的范围内。这个confidence代表了所预测的box中含有object的置信度,其值是这样计算的:
当网格中没有物体时,该confidence值为0,当有物体时,该值为IOU数值。
bounding box位置信息和confidence的信息如上图的中间图片的上半部分。每个网格还要预测一个类别信息,记为C类。即如图下半部分则SxS个网格,每个网格要预测B个bounding box还要预测C个categories。输出就是S x S x (5*B+C)的一个tensor。
注意:class信息是针对每个网格的,confidence信息是针对每个bounding box的。
在test的时候,每个网格预测的class信息和bounding box预测的confidence信息相乘,就得到每个bounding box的class-specific confidence score:
得到每个box的class-specific confidence score以后,设置阈值,滤掉得分低的boxes,对保留的boxes进行NMS处理,就得到最终的检测结果。
网络训练
YOLO v1网络结构图如图
每个网格回归得到一条关于bounding boxes的信息向量,通过计算预测的bounding boxes信息与训练集输出的信息求取误差,反馈更新权重。
作者简单粗暴的采用了sum-squared error loss来求取损失函数。
这种做法存在以下几个问题:
第一,8维的localization error和20维的classification error同等重要显然是不合理的;
第二,如果一个网格中没有object(一幅图中这种网格很多),那么就会将这些网格中的box的confidence push到0,相比于较少的有object的网格,这种做法是overpowering的,这会导致网络不稳定甚至发散。
解决办法:
更重视8维的坐标预测,给这些损失前面赋予更大的loss weight, 在训练中取5。
对没有object的box的confidence loss,赋予小的loss weight,在训练中取0.5。
有object的box的confidence loss和类别的loss的loss weight正常取1。
对不同大小的box预测中,相比于大box预测偏一点,小box预测偏一点肯定更不能被忍受的。而sum-square error loss中对同样的偏移loss是一样。
为了缓和这个问题,作者用了一个比较取巧的办法,就是将box的width和height取平方根代替原本的height和width。实际上是对原来的width和height进行了压缩。
一个网格预测多个box,希望的是每个box predictor专门负责预测某个object。具体做法就是看当前预测的box与ground truth box中哪个IoU大,就负责哪个。这种做法称作box predictor的specialization。
最终的loss function如图(该图片参考另外一个博客,具体见下面参考链接):
这个损失函数中:
- 只有当某个网格中有object的时候才对classification error进行惩罚。
- 只有当某个box predictor对某个ground truth box负责的时候,才会对box的coordinate error进行惩罚,而对哪个ground truth box负责就看其预测值和ground truth box的IoU是不是在那个cell的所有box中最大。
YOLO的缺点
- 由于每个网格只有固定的B个bounding boxes,对于临近的几个物体,检测效果不是很好。
- 由于第一个版本仅含有一个YOLO层,没有多尺度的操作,对于含有大小不一的物体的图片可能检测效果不好。
- 我们要知道,对于一个较大的物体,其预测结果与真实情况的小偏差是可以接受的,而对于一个较小的物体,其预测结果与真实情况的同样小的偏差却是相对较大的误差,由于loss function对尺寸大小不一样的物体的位置偏差的损失计算地位相同,这样的计算不是很准确。
YOLO与Faster RCNN的结合
作者通过分析,YOLO在背景误识别上表现得较好,而Faster RCNN则有较多的背景误识别,所以作者结合着两种算法,先用Faster RCNN对图片进行检测,然后在使用YOLO进行检测,结合两者得到的较为相近的bounding boxes,从而减少背景误识别。
参考链接
- 论文原文:YOLO v1
- 参考博客:Alanyannick
- 目标检测概要