1. Introduction
- yolo从v1-v2-v3做了一步步迭代,从速度、精度、强度都有了显著的提高。yolo的核心思想在v1中提出,在v2中结合其他研究者的工作做了各方面的改进,在v3中使用了许多技巧进一步优化。
- yolo将以往目标检测的two stage方法缩减成one stage,它将以往region proposal的过程融合到后续的分类任务中,将目标的定位和分类用一个end to end的神经网络作为回归问题求解。
- 效果与其他网络对比起来,很快,背景误判率低,通用性强,但定位精准性稍差。
2. yolov1
总体流程
yolo先将图像切分成个grid(单元格),让每一个grid负责检测中心点落入该格的目标,预测出B个bounding box定位目标并给出目标类别。
- bounding box中有一个5维坐标,分别代表框的位置、宽高、置信度。
- x,y是bounding box中心位置相对于当前格子位置的偏移值,并且被归一化到0-1;
- w和h是用原图的宽高进行归一化到0-1;
- 置信度反映当前框是否包含物体以及位置的准确性,计算为,IOU也归一化到0-1。
- 整个模型输入是image,输出是的张量。
结构
yolo网络由24个卷积层和2个全连接层组成。卷积层用于提取特征,全连接层用于定位和分类。
它借鉴了googleNet的结构,但是未使用inception模块,仅用11和33卷积核简单替代,减小了模型的复杂度。
Loss
它的loss很简单又很巧妙,使用误差平方和(sum-square error)
。
由于定位误差和分类误差对网络的loss的贡献值是不同的,因此加上了坐标误差权值,给无物体的IOU误差权值;
又因为宽高错误对大物体的影响应该小于小物体的影响,所以给宽高加上了根号,但并不能完全解决这个问题。最后得到一个形式稍复杂一点的loss公式。
训练过程
- 预训练,使用前20个conv和1个ave pool和1个全连接做预训练。
- 用预训练得到的20层conv初始化yolo的前20层,为了提高精度,将输入图像从224*224 resize到448*448
- 使用了leaky ReLU,dropout,data augmentation
- 调整学习率。第一个epoch从0.001到0.01,然后0.01持续75epoch,0.001持续30epochs,0.0001持续30epochs
缺陷:
- 由于输出为全连接,所以输入图像分辨率大小都要一致
- 有很强的空间约束,每个格子只能预测一个目标。每个格子虽然有B个bounding box,但是只选择IOU最高的bounding box做预测,所以有B*5个坐标值,只有C个类别概率,输出为(B*5+C),而不是B*(5+C)。
- 对小物体的预测不好
- 对于长宽比例的适应性不是太强
3. yolov2
yolov2提高了精度、速度、广泛度。
精度的提高主要表现在对recall的提高。做了以下的修改。
加上BN,并去除了其他正则化方法如dropout,保证不过拟合。
使用高分辨率的图像分类器,将预训练的图像从224*224直接转为448*448。
[图片上传中...(image.png-1ced27-1555252428685-0)]-
加上了anchor机制
移除了最后的全连接(使用conv和GAP替代)和一个池化层(为了使分辨率不减小一半),使recall从81%加到了88%。将图像从448改成416,因为该网络最后是将图像缩小了32倍,416除32会得到一个奇数13,这样可以使每个grid有一个唯一的中心点而不是像偶数有4个。
-
由于传统anchor的大小比例是手动设置为(8,16,32)*(1:2,1:1,2:1)共9个,而如果能直接使用更好的anchor肯定会对网络效果有利。这里使用了一种改进的k-means算法来自动产生prior anchor(先验框)。在选择kmeans的距离时发现,L2距离在这个任务中不太适用。因为box尺寸大时其误差也会变大,而我们希望和尺寸关系较小,而和是否吻合ground truth较大,所以将距离函数设置为 d=1-IOU。在k定为5时,就取得了传统的9个anchor的效果;k=9时则远超传统anchor。
-
引入了anchor后,训练变得不稳定。改进了anchor的坐标公式,之前r-cnn中是全局的偏移,这里改成预测相对于grid的偏移。使用坐标公式:xy=该grid左上角相对于图片的偏移cxcy+预测的xy。wh=先验框的宽高*e^twth
为了得到细粒度特征,类似resnet的shortcut引入了passthrough层,直接将高像素特征和低像素特征concatenate,使多级别的特征在最后的预测中都起到效果,提高了小物体的正确率。
采用多尺度图片训练。把原先固定输入图片大小改成了动态调整输入图像大小,每10个batch就在range(320,608,32)中随机选出一个大小训练。这个操作强制让网络学习多个分辨率的图像,提高了适应性。
速度上,
提出了darknet19模型,19*卷积层+5max pooling+1GAP(global average pooling),取得了很快的速度。
广泛度
主要体现在yolo9000可以对超过9000个类别的目标进行检测。引入了分层预测的机制,把类别标签从imagenet的横向改成了wordnet的图式构造。在预测一个物体时,逐层预测,使用条件概率,增加准确性。
4. yolov3
yolov3是增量式改动,也借鉴了他人的诸多工作,提出了darknet53模型。几个重点是:
1、多分类;2、多尺度;3、引入resnet。
定位上使用logistic regression
对anchor包围的部分进行评分,判定该位置是目标的可能性有多大。这一步是在predict之前进行的,可以去掉不必要anchor,可以减少计算量。
logistic回归就是用曲线对prior相对于 objectness score映射关系的线性建模。如果先验边界框与真实框的重叠度比之前的任何其他边界框都要好,则该值应该为1。 如果先验边界框不是最好的,但确实与真实对象的重叠超过某个阈值(这里是0.5),那么就忽略这次预测。YOLOv3只为每个真实对象分配一个边界框,如果先验边界框与真实对象不吻合,则不会产生坐标或类别预测损失,只会产生物体预测损失。
分类上不使用softmax,而采用logistic
支持多标签的预测,而非单标签。当一张图像经过特征提取后的某一类输出经过sigmoid函数约束后如果大于0.5,就表示属于该类。在loss函数中使用了二分类交叉熵。
多尺度预测(FPN)
将高维的特征和低维的特征连接,得到3层特征,对这三层特征分别做预测。每一个scale都输出替代了之前的,将v2中提到的k-means的k改成了9。
基于yolov2的结构,提出了darknet53
使用了residual block。用了更少的浮点运算,并且每秒浮点运算更高。
整个v3中,取消了池化层,图像缩小是通过改变卷积核步长实现的,想缩小一半边长,就设stride=2。在最后的输出层,借鉴了FPN(feature pyramid networks)采用多尺度对不同size的目标进行检测。