Yolov1(You Only Look Once: Unified, Real-Time Object Detection)是2015年。
Yolov2(YOLO9000: Better, Faster, Stronger)是2017年文章。
Yolov3(YOLOv3: An Incremental Improvement)是2018年文章。
Yolo系列是一个集其他网络优点于一身的检测网络。
图像被划分为S×S的格子(S=7),每个格子设置B(B=2)个bounding box,因此输出为 S × S × ( ( 4 + 1 ) B + C ) S \times S \times ((4+1)B +C) S×S×((4+1)B+C)维向量,其中的1为置信度。C为类别数目。与fasterrcnn中region proposal network不同的是bounding box的大小以及形状并不是预先设定好的,需要训练过程中不断学习。回归网络部分使用全连接层作为输出,直接输出边框的坐标及宽高,最后对所有的bounding box使用NMS并按照置信度(confidence)排序,生成检测结果。
将分类也作为回归问题看待,损失函数由三部分组成:回归损失函数、置信度损失函数和类别损失函数,都是使用的均方误差损失函数。
获得2017年最佳论文。yolov2也叫yolo9000, yolo2与yolo9000是两个模型,结构相同只是训练方法不同,后者采用联合训练的方式使得检测物体超过9000种。yolov2主要是借鉴了许多优秀成果然后在yolov1上的改进,yolov2与其他优秀算法在数据集VOC2007上的比较如图1和图2所示。
图2中yolov2 288 × \times × 288表示测试图像的分辨率为288 × \times × 288,依次类推,模型本身是相同的。
从图1和图2中可以看到当测试图片的分辨率为416 × \times × 416及以上时,yolov2与faster-rcnn、ssd512的map相当,但是速度要快很多。在coco数据集上的比较如图3所示。
注:
coco数据集:包含80个类别,20多万张图片,评价指标中S:<32, M:32-96, S:>96,检测指标如下图所示。
voc2007和voc2012:包含20个类别,总共3万多张图片。
从图3中可以看到在coco数据集上yolov2的检测效果甚至不如ssd300,说明了当需要检测的类别数量很多时,只从map的角度看SSD512>Faster-rcnn>SSD300>YOLOV2.
创新点不多,大部分都是借鉴了其他优秀成果。
yolov2的思想是在保证速度的前提下通过使用一堆技术提升map,使用的技术如下图3所示.
在每一个卷积后加入batch norm,规范化数据,可以提升收敛速度也可以降低模型过拟合。MAP提升了2.4%。
解决预训练输入图片分辨率与训练图片分辨率不同的问题。首先在ImageNet分类数据集训练主体网络(特征提取器),数据集的分辨率为224 × \times × 224,小分辨率不利于检测,所以yolov1的办法是将检测图片的分辨率增加到448,微调模型。在不同的数据集上微调模型显然不如都在分类数据集上微调模型,yolov2具体的做法是在分类数据集上训练完模型后,将图片的分辨率调至448,微调模型10epoch。然后直接在检测模型上训练。MAP提高4%
借鉴了faster-rcnn的anchor,去掉了全连接层,使用卷积层代替,去掉一个pool层,检测网络的输入不是448 × \times × 448,而是采用416 × \times × 416,输出为13 × \times × 13,输出要尽可能为奇数,因为作者认为大的物体的中心落在特征图中心,奇数的特征图中心只有一个,正好负责预测该物体。因为网络下采样为32倍,所以输入为32的倍数。在yolov1中,一个格子(两个bounding box)负责类别预测,而yolov2中一个bounding box负责一个类别预测。召回率提升了7%而MAP略有下降,有可能是召回率提升了,所以MAP略有下降。
使用新的主体网络架构。MAP几乎不变,但是计算量减少约33%
回归网络中,在faster-rcnn中的预测方法为:给定anchor的宽为 w a w_a wa(其他类似),预测的宽为 w w w,宽的偏移值为 t w t_w tw,GT为 w g w_g wg,目的是使预测值 w w w接近GT值 w g w_g wg,对anchor进行平移和缩放,有(原论文中减号写错了):
x = ( t x ∗ w a ) + x a x=(t_x *w_a)+x_a x=(tx∗wa)+xa y = ( t y ∗ h a ) + y a y=(t_y *h_a)+y_a y=(ty∗ha)+ya w = w a ∗ e t w w=w_a*e^{t^w} w=wa∗etw h = h a ∗ e t h h=h_a*e^{t^h} h=ha∗eth 只要预测出偏移值 t x t y w a h a t_x t_y w_a h_a txtywaha即可,但是这种方法对x和y的值没有约束,因此x、y可以出现在图中的任意位置,而yolov2想要将x、y限制在一个格子内,所以在回归中心坐标时采用的方法为预测格子左上角与gt的距离,网络输出值经过函数sigmoid函数 σ ( x ) \sigma(x) σ(x) 转化为0-1的值。注意到此时并没有使用anchor中心点坐标值。在回归边框宽和高时采用的方法与faster-rcnn相同。
设 c x c_x cx表示格子左上角x坐标, b x b_x bx表示预测的边框x坐标, p w p_w pw表示anchor的宽。计算方法如下:
位置关系如图5所示。
当输入图像大小为416时输出大小为13,此时不能检测小物体,还需要更加精细特征,yolov2提出passthrough层来做获得图像细粒度特征。思想是将前面大的特征图连接到后面小的特征图当中,因此小的特征图就获得了更加精细的特征。比如将 26 × 26 × 512 26\times26\times512 26×26×512大小的特征图经过passthrough处理后变成 13 × 13 × 2048 13\times13\times2048 13×13×2048大小的特征图,特征图大小减小4倍通道增加4倍,如图6所示,然后再与后面的 13 × 13 × 512 13\times13\times512 13×13×512的特征图连在一起。MAP提升1%
由于yolov2中只有卷积和池化,因此可以输入不同尺寸的图片,采用的方法是每隔10 iteration后,改变输入图片的大小,因为yolov2下采样总共为32倍,因此图片大小为32的倍数(320…352…608…),当输入图片为320时,输出的特征图大小为10,不是奇数了,这个是一个疑问,
损失函数原文中并没有给出,参考链接:yolov2的原理与实现知乎,框的匹配原则与yolov1相同,只有一个框对对象负责,与yolov1不同点在于yolov2每一个anchor都有一个类别的预测,因此每一个框都可以检测一个对象,而yolov1中每一个格子预测一个类别概率,格子中的边框共享同一个类别概率,因此yolov2能够预测更多的对象。
与YoloV1损失函数公式相似,都是正例贡献所有三个部分的损失值,负例只贡献置信度部分的损失值,不同点在于
与YoloV2损失函数公式相似,都是正例贡献所有三个部分的损失值,负例只贡献置信度部分的损失值,不同点在于
通过阅读代码发现其中用到了许多技巧。
长方形训练,常见的训练方法是将训练图片裁剪到比如416*416的正方形,作者使用长方形的训练方法可以使检测速度提高1/3,具体的做法是按照原图像的比例缩放为最长边为416的图片,作为batch_shape(选择最大的),计算方法为
self.batch_shapes = np.ceil(np.array(shapes) * img_size / 32. + pad).astype(np.int) * 32
同样地缩放图片最长边为416,但是短边的计算方法为:
w=w0*416/max(h0,w0)
h=h0*416/max(h0,w0)
下面图片来源自博客
下图展示了U版yolov3-spp的结构图细化。
其中cat表示连接操作。Conv(channels, size, stride, pad)
从图中可以看出: