YOLO
核心思想:从
R-CNN
到
Fast R-CNN
一直采用的思路是
proposal
+分类 (
proposal
提供位置信息, 分类提供类别信息)精度已经很高,但是速度还不行。
YOLO
提供了另一种更为直接的思路: 直接在输出层回归
bounding box
的位置和
bounding box
所属的类别(整张图作为网络的输入,把
Object Detection
的问题转化成一个
Regression
问题)。
YOLO
的主要特点:
- 速度快,能够达到实时的要求。在
Titan X
的GPU
上能够达到45帧每秒。 - 使用全图作为
Context
信息,背景错误(把背景错认为物体)比较少。 - 泛化能力强。
大致流程:
-
Resize成
448*448
,图片分割得到7*7
网格(cell
) -
CNN提取特征和预测:
卷积部分负责提特征。
全链接部分负责预测:a)
7*7*2=98
个bounding box(bbox)
的坐标 和是否有物体的 。b)7*7=49
个cell
所属20个物体的概率。 -
过滤
bbox
(通过NMS
)
1. 网络设计
网络结构借鉴了GoogLeNet
。24个卷积层,2个全链接层。(用1×1 reduction layers
紧跟3×3 convolutional layers
取代Googlenet
的 inception modules
)
2. 训练
预训练分类网络: 在 ImageNet 1000-class competition dataset
上预训练一个分类网络,这个网络是Figure3
中的 前20个卷积网络 + average-pooling layer
+ fully connected layer
(此时网络输入是224*224
)。
训练检测网络:转换模型去执行检测任务,**《Object detection networks on convolutional feature maps》**提到说在预训练网络中增加卷积和全链接层可以改善性能。在他们例子基础上添加4个卷积层和2个全链接层,随机初始化权重。检测要求细粒度的视觉信息,所以把网络输入也又224*224
变成448*448
。见Figure3
。
一幅图片分成7x7
个网格(grid cell
),某个物体的中心落在这个网格中此网格就负责预测这个物体。
最后一层输出为 (7*7)*30
的维度。每个 1*1*30
的维度对应原图7*7
个cell中的一个,1*1*30中含有类别预测和bbox坐标预测。总得来讲就是让网格负责类别信息,bounding box
主要负责坐标信息(部分负责类别信息:confidence
也算类别信息)。具体如下:
(1) 每个网格(1*1*30维度对应原图中的cell)要预测2个bounding box (图中黄色实线框)的坐标
,其中:中心坐标的
相对于对应的网格归一化到0-1
之间,
,
用图像的
和
归一化到0-1
之间。 每个bounding box
除了要回归自身的位置之外,还要附带预测一个
值。 这个confidence代表了所预测的box中含有object的置信度和这个box预测的有多准两重信息:
。其中如果有ground true box
(人工标记的物体)落在一个grid cell
里,第一项取1,否则取0。 第二项是预测的bounding box
和实际的ground truth box
之间的IOU
值。即:每个bounding box
要预测
共5个值 ,2个bounding box
共10个值,对应 1*1*30
维度特征中的前10个。
(2) 每个网格还要预测类别信息,论文中有20类。7x7
的网格,每个网格要预测2个bounding box
和 20个类别概率,输出就是 7x7x(5x2+20)
。 (通用公式: SxS
个网格,每个网格要预测B个bounding box
还要预测C个categories
,输出就是SxSx(5*B+C)
的一个tensor
。 注意:class信息是针对每个网格的,confidence信息是针对每个bounding box的)。
损失函数设计:
损失函数的设计目标就是让坐标
这个三个方面达到很好的平衡。简单的全部采用了sum-squared error loss
来做这件事会有以下不足: a) 8维的localization error
和20维的classification error
同等重要显然是不合理的; b) 如果一个网格中没有object
(一幅图中这种网格很多),那么就会将这些网格中的box
的confidence
push到0,相比于较少的有object
的网格,这种做法是overpowering
的,这会导致网络不稳定甚至发散。 解决方案如下:
- 更重视8维的坐标预测,给这些损失前面赋予更大的
loss weight
,记为 ,在pascal VOC
训练中取5。(上图蓝色框) - 对没有
object
的bbox
的confidence loss
,赋予小的loss weight
,记为 ,在pascal VOC
训练中取0.5。(上图橙色框) - 有
object
的bbox
的confidence loss
(上图红色框) 和类别的loss
(上图紫色框)的loss weight
正常取1。 - 对不同大小的
bbox
预测中,相比于大bbox
预测偏一点,小box
预测偏一点更不能忍受。而sum-square error loss
中对同样的偏移loss
是一样。 为了缓和这个问题,作者用了一个比较取巧的办法,就是将box
的width
和height
取平方根代替原本的height
和width
。 如下图:small bbox
的横轴值较小,发生偏移时,反应到y轴上的loss
(下图绿色)比big box
(下图红色)要大。
- 一个网格预测多个
bounding box
,在训练时我们希望每个object(ground true box)
只有一个bounding box
专门负责(一个object
一个bbox
)。具体做法是与ground true box(object)
的IOU
最大的bounding box
负责该ground true box(object)
的预测。这种做法称作bounding box predictor
的specialization
(专职化)。每个预测器会对特定(sizes,aspect ratio or classed of object)
的ground true box
预测的越来越好。(个人理解:IOU
最大者偏移会更少一些,可以更快速的学习到正确位置)。
3. 测试
Test的时候,每个网格预测的class信息 和bounding box预测的confidence信息
相乘,就得到每个bounding box
的class-specific confidence score
。
- 等式左边第一项就是每个网格预测的类别信息,第二三项就是每个
bounding box
预测的confidence
。这个乘积即encode
了预测的box
属于某一类的概率,也有该box
准确度的信息。
- 对每一个网格的每一个
bbox
执行同样操作:7x7x2 = 98 bbox
(每个bbox
既有对应的class
信息又有坐标信息)
- 得到每个
bbox
的class-specific confidence score
以后,设置阈值,滤掉得分低的boxes
,对保留的boxes
进行NMS
处理,就得到最终的检测结果。
缺陷:
YOLO
对相互靠的很近的物体(挨在一起且中点都落在同一个格子上的情况),还有很小的群体检测效果不好,这是因为一个网格中只预测了两个框,并且只属于一类。- 测试图像中,当同一类物体出现的不常见的长宽比和其他情况时泛化能力偏弱。
- 由于损失函数的问题,定位误差是影响检测效果的主要原因,尤其是大小物体的处理上,还有待加强。
本文图片很多来自PPT:
内容主要参考如下博客:
RCNN学习笔记(6):You Only Look Once(YOLO):Unified, Real-Time Object Detection