相对于以RCNN,Fast R-CNN和Faster R-CNN为代表的基于region proposal的两阶段检测模型,单阶段的物体检测用一个end-to-end的全卷积神经网络完成从原始图像的输入到Bounding box和box中物体类别的输出。在实时检测方面优于上述的区域推荐,而准确率方面则相对较差。
以RCNN为代表的传统的物体检测方法通过region proposal产生大量的可能包含待检测物体的 potential bounding box,再用分类器去判断每个 bounding box里是否包含有物体,预测物体所属类别的 probability,以及bounding box的坐标;而YOLO将物体检测任务当做一个regression问题来处理,使用一个全卷积神经网络,直接从一整张图像来预测出bounding box 的坐标、box中包含物体的置信度和物体类别的probabilities;相比R-CNN算法,YOLO是一个统一的框架,其速度更快,而且Yolo的训练过程也是end-to-end的。
YOLO V1论文:You Only Look Once: Unified, Real-Time Object Detection
地址:https://arxiv.org/abs/1506.02640
核心思想:利用整张图作为网络的输入,直接在输出层输出 bounding box(边界框) 的位置及其所属的类别
1、将图像resize到448 * 448作为神经网络的输入
2、通过一个全卷积神经网络,得到一些bounding box坐标、box中包含物体的置信度和class probabilities
3、进行非极大值抑制(NMS),筛选Boxes
1.将一幅图像分成 SxS 个网格(grid cell),每个网格负责检测中心落在该格子中的物体:
其中每个网格的label tensor长度为(B * 5 + C)
每个网格要预测 B 个 bounding boxes,每个 bounding box 除了要回归自身的位置(用于修正以接近ground truth)之外,还要附带预测一个 confidence 值(用于表示这个box中含有object的置信度和box的坐标预测的准确度,公式定义如下)
其中如果有 object 的中心落在一个 grid cell 里,第一项取 1,表示该网格负责该object的预测,否则取 0。 第二项是预测的 bounding box 和实际的 groundtruth 之间的 IoU 值。所以如果这个网格中不存在一个 object,则confidence score应该为0;相反,confidence score则为 predicted bounding box与 ground truth box之间的 IOU(intersection over union),bounding box regression仅需对confidence不为0的label Tensor上进行。
举例说明:在PASCAL VOC中,图像输入为 448x448,取 S=7,B=2,一共有20 个类别(C=20),则输出就是 7x7x30 的一个 tensor,网络结构如下
其中,卷积层(利用ImageNet 1000-class的分类任务数据集Pretrain)用来提取图像特征,全连接层用来预测图像位置和类别概率值
由上可得,YOLO对每个网格所负责的bounding box有5个predictions:x, y, w, h和confidence score
每个bounding box的预测值 | 含义 |
---|---|
坐标x,y | bounding box的中心与网格边界的相对值 |
坐标w,h | bounding box的width、height相对于整幅图像width,height的比例 |
confidence | 预测的bounding box和ground truth box的IOU |
除此以外,每一个栅格还要预测C个 conditional class probability(条件类别概率):Pr(Classi|Object)(在一个栅格包含一个Object的前提下,它属于某个类的概率)。
注意,conditional class probability信息是针对每个网格的。 confidence信息是针对每个bounding box的。
在测试阶段,将每个栅格的conditional class probabilities与每个 bounding box的 confidence相乘:
等式右边可以得到每个bounding box具体类别的confidence score,包含了box中预测类别的信息,也反映了bounding box是否含有object和bounding box预测坐标的准确度。得到每个 box 的 class-specific confidence score 以后,设置阈值,滤掉得分低的 boxes,对保留的 boxes 进行 NMS 处理,就得到最终的检测结果。
YOLO V1网络的损失函数需要考虑的有bounding box的坐标(x,y,w,h)和confidence score以及网格的classification;设计损失函数时考虑以下两个问题:
(1)8维的localization error和20维的classification error权重不应该相等;
(2)如果一些网格中没有object(一幅图中占绝大多数),那么就会将这些网格中的bounding box的confidence score置为0,相比于较少的有object的网格,这些不包含物体的网格对梯度更新的贡献会远大于包含object的网格对梯度更新的贡献,这会导致网络不稳定甚至发散;
(3)对不同大小的bbox预测中,相比于大bbox预测偏一点,小box预测偏相同的尺寸对IOU的影响更大。
对于上述问题,YOLO V1的解决思路如下:
1.坐标预测更为重要,给这些损失前面赋予更大的loss weight, 记为 λcoord ,在pascal VOC训练中取5(蓝色框);
2.没有object的bbox(图中占大多数)的confidence loss,赋予小的loss weight,记为 λnoobj ,在pascal VOC训练中取0.5(黄色框);
3.有object的bbox的confidence loss (红色框) 和类别的loss (紫色框)的loss weight正常取1
4.location损失中将box的width和height取平方根代替原本的height和width(没有根本解决小物体 IOU 误差问题)
注:
只有当某个网格中有 object 的时候才对 classification error 进行惩罚。
只有当某个 box predictor 对某个 ground truth box 负责的时候,才会对 box 的 coordinate error 进行惩罚,而对哪个 ground truth box 负责就看其预测值和 ground truth box 的 IoU 是不是在那个 cell 的所有 box 中最大。
(1)YOLO 对相互靠的很近的物体,还有很小的群体检测效果不好,这是因为一个网格中只预测了两个框,并且只属于一类。
(2)同一类物体出现的新的不常见的长宽比和其他情况时,泛化能力偏弱。
(3)由于损失函数的问题,定位误差是影响检测效果的主要原因。尤其是大小物体的处理上,还有待加强。
YOLOv2论文:YOLO9000: Better, Faster, Stronger
地址:https://arxiv.org/abs/1612.08242
为了解决YOLOv1定位错误多,召回率低等问题,YOLOv2在YOLOv1的基础上进行以下改进:
BN(Batch Normalization)层对网络的每一层的输入都做了归一化,这样网络就不需要每层都去学数据的分布,收敛会快点。作者在YOLOv2中为每个卷积层都添加了BN层,BN是类似于Dropout的一种防止过拟合的正则化表达方式,所以不用Dropout也能达到相当的效果,所以加入BN后就把dropout去掉了,实验证明添加了BN层可以提高2%的mAP。关于Batch Normalization的理论可以在论文《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》中了解。
YOLOv1在预训练的时候用的是224 * 224的输入,一般预训练的分类模型都是在ImageNet数据集上进行的,然后在检测的时候采用448 * 448的输入。这会导致从分类模型切换到检测模型的时候,模型还要适应图像分辨率的改变。
YOLOv2中将预训练分成两步:先用224 * 224的输入从头开始训练网络,大概160个epoch,然后再将输入调整到448 * 448,再训练10个epoch(两步都是在ImageNet数据集上操作)最后再在检测的数据集上fine-tuning,也就是检测的时候用448 * 448的图像作为输入就可以顺利过渡了,这一做法使得v2的mAP提高了4%。
(1)删掉全连接层和最后一个pooling层,使得最后的卷积层可以有更高分辨率的特征;
(2)缩减网络,用416 * 416大小的输入代替原来448 * 448。这样做是希望希望得到的特征图都有奇数大小的宽和高,奇数大小的宽和高会使得每个特征图在划分cell的时候就只有一个中心cell。因为大的目标一般会占据图像的中心,所以希望用一个中心cell去预测,而不是4个中心cell。网络最终将416 * 416的输入下采样32倍变为13 * 13大小的feature map输出,查看.cfg文件可以看到有8个pooling层;
(3)YOLOv1中将输入图像分成7 * 7的网格,每个网格预测2个bounding box,一共只有7 * 7 * 2=98个box,利用全连接层直接预测bounding box的坐标;YOLOv2中借鉴了Faster R-CNN的思想,引入anchor boxes,输出feature map大小为13 * 13,每个cell有5个anchor box预测得到5个bounding box,一共有13 * 13 * 5=845个box。增加box数量是为了提高目标的定位准确率。
Faster R-CNN中anchor box的大小和比例是按经验设定的,然后网络会在训练过程中调整anchor box的尺寸。
如果一开始就能选择到合适尺寸的anchor box,那肯定可以帮助网络更好地预测。所以作者采用k-means的方式对训练集的bounding boxes做聚类,试图找到合适的anchor box。
作者发现采用标准的k-means(即用欧式距离来衡量差异),在box的尺寸比较大的时候其误差也更大,而我们希望的是误差和box的尺寸没有太大关系。所以通过IOU定义了距离函数,使得误差和box的大小无关:
设置先验框的主要目的是为了使得预测框与ground truth的IOU更好,所以聚类分析师使用box与聚类中的box之间的IOU值作为距离指标。
YOLOv2借鉴RPN网络使用anchor boxes来预测bounding box相对先验框的offsets,但弃用其预测方式,选择沿用YOLOv1的方法,就是预测bounding box中心点相对于对应cell左上角位置的相对偏移值
网络在最后一个卷积层输出13 * 13的feature map,有13 * 13个cell,每个cell有5个anchor box来预测5个bounding box,每个bounding box预测得到5个值:tx、ty、tw、th(4个offsets)和to(类似YOLOv1的confidence)
由于预测的边界框很容易向任何方向偏移,为了将bounding box的中心点约束在当前cell中,使用sigmoid函数将偏移值tx、ty归一化处理,将值约束在0~1,由于sigmoid函数的处理,边界框的中心位置会约束在当前cell内部,这使得模型训练更稳定,根据边界框预测的4个offsets可以按如下公式计算出bounding box的实际位置和大小
注:其中,bx,by标记了bounding box的中心点(相对位置,b-box中心点相对于网格单元左上角的相对坐标),bw,bh表示bounding box的长与宽;cx,cy是网格的坐标偏移量,pw,ph是预设的anchor box的边长.最终得到的边框坐标值是,网络学习目标是tx,ty,tw,th.
作者直接添加了一个passthrough layer(直通层) 得到2626的细粒度的特征。然后将2626512的feature map的resize 变为 1313* 2048(经passthrough层处理)。与后面的13131024特征图连接在一起形成13133072的特征图,最后在该特征图上卷积做预测,这样就得到了多尺度的信息,mAP提高了1%。
YOLOv2中只有卷积层和池化层,因此不需要固定的输入图片的大小。
为了让模型更有鲁棒性,作者引入了多尺度训练。就是在训练过程中,每迭代一定的次数,改变模型的输入图片大小。如作者使用{320, 352, …, 608}的不同尺度的图片进行训练,每经过10个epoch以后,都会选择新的尺寸图片训练,这样可以是网络对不同尺度的图片都可以预测的较好
注意:这一步是在检测数据集上fine-tuning时候采用的,不要跟前面在Imagenet数据集上的两步预训练分类模型混淆。
大多数目标检测的框架都是基于VGG-16/Google-Net等,这些网络的速度严重制约着检测的速度,为了实现更快的实时性检测,作者提出了Darknet-19:
在ImageNet上进行预训练:
第一阶段:在ImageNet分类数据集上从头开始预训练Darknet-19,训练160个epoch。输入图像的大小是224224,初始学习率为0.1。另外在训练的时候采用了标准的数据增加方式比如随机裁剪,旋转以及色度,亮度的调整等。
第二阶段:将网络的输入调整为448448,继续在ImageNet数据集上fine-tuning分类模型,训练10个epoch。参数的除了epoch和learning rate改变外,其他都没变,这里learning rate改为0.001。
修改Darknet-19分类模型为检测模型,并在检测数据集上继续fine-tuning网络:
(1)移除预训练好的分类模型的最后一个卷积层、global avgpooling层以及softmax层;
(2)新增了三个3 * 3 * 2014卷积层,同时增加了一个passthrough层,最后使用1 * 1卷积层输出预测结果,其通道数和label Tensor长度一样:对于VOC数据,每个cell预测5个bounding box,每个bounding box有5个坐标值和20个类别值,所以每个cell有125个filter。即:filter_num = num * (classes + 5) = 5 * (20 + 5) = 125
1.遍历Imagenet的所有视觉名词;
2.对每一个名词,在Wordnet找到从它所在位置到根节点的路径,加入到层次树结构中;
3.对于有多条路径到根节点的情况,选用经过边数较少的路径;
4.最终形成一颗WordTree
5.WordTree执行分类时,预测每一个节点的条件概率
论文:YOLOv3: An Incremental Improvement
地址:https://pjreddie.com/media/files/papers/YOLOv3.pdf
YOLOv3的网络组成如下:
层 | 数目 |
---|---|
Add | 23 |
BatchNormalization | 72 |
Concatenate | 2 |
InputLayer | 1 |
LeakyRelu | 72 |
Upsampling | 2 |
ZeroPadding | 5 |
Total | 252 |
注:
YOLOv2直接预测出(tx,ty,tw,th,to),然后通过前面所说的公式计算出bounding box绝对的(x, y, w, h, c),而v3对b-box进行预测的时候,采用了logistic regression,logistic回归用于对anchor包围的部分进行一个目标性评分(objectness score),即这块位置是目标的可能性有多大,这一步是在predict之前进行的,可以去掉不必要anchor,可以减少计算量,不同于faster R-CNN的是,yolo_v3只会对1个prior进行操作,也就是那个最佳prior。而logistic回归就是用来从9个anchor priors中找到objectness score(目标存在可能性得分)最高的那一个。
单阶段检测模型的实时检测会成为标配。但目前所谓的“实时”,工业界是不认可的。为什么呢,因为学术圈的人,验证模型都是建立在TitanX或者Tesla这类强大的独立显卡上,而实际的潜在应用场景中,例如无人机/扫地/服务机器人/视频监控等,是不会配备这些“重型装备”的。所以,在嵌入式设备中,如FPGA,轻量级CPU上,能达到的实时,才是货真价实的。
模型小型化成为重要分支。类似于tiny YOLO的模型分支会受到更多关注。模型的小型化是应用到嵌入式设备的重要前提。而物联网机器人无人机等领域还是以嵌入式设备为主的。模型剪枝/二值化/权值共享等手段会更广泛的使用。
最后附上YOLOv3的keras实现:
https://github.com/wait1ess/keras-yolo3-1