YOLO v2算法详解+YOLO9000介绍

YOLO9000是继YOLO之后的又一力作,本篇论文,其实作者在YOLO v2上并没有特别多的创新的方法,更多的是将现有的多种方法使用在自己的YOLO中以提高识别效果,不过YOLO9000倒是很有创新点,利用ImageNet与COCO数据,使得网络可以检测9000类数据,下面简要介绍一下这两个网络:

首先介绍YOLO v2都使用了哪些方法:

Batch Normalization

这个不多说了,确实是有效果的。,提高了2%。

High Resolution Classifier

作者先在224大小上训练,然后在448上进一步fine-tune得到更好的效果。这里我们做过实验,在自己的数据上,如果只是单纯的扩大图像,在224的预训练模型进行训练,分类精度不会提高,反而降低了。

加anchor

加入anchor并没有提高map,但是提高了recall,作者在paper中表示,没加anchor前,map为69.5,recall为81%,加入anchor后,map为69.2,recall为88%。

这里引入一张引入anchor之后与yolo v1算法的不同:

一目了然,以前是每个点预测30,现在是每个anchor预测25

http://i.imgur.com/gqYMaEH.png

利用k-means代替手动设计anchor

距离设计中,作者并没有使用均方误差,而是使用IOU作为距离,公式如下:
d(box,centroid)= 1- IOU(box,centroid)

bounding box loss

paper并没有使用类似于faster rcnn以及ssd的边框预测方法,,在faster rcnn中的计算方式如下图,其中$x_a,y_a,w_a,h_a$分别代表anchor的坐标,$x,y,w,h$代表预测值,带星的为bounding box的坐标,所以faster rcnn实际计算的是与anchor的偏移值。

yolo v2并没有计算与anchor的偏移值,作者解释说计算偏移的方法由于偏移范围比较大,计算的时候不稳定,所以yolo v2采用了计算anchor与图像左上角的位置偏移以及anchor长宽的缩放的方法,如下公式所示,$c_x,c_y$分别为anchor相对于左上角点的坐标。作者使用sigmoid函数,将ground truth变换到0-1的范围,以增加算法的稳定性。
b x = σ ( t x ) + c x
b y = σ ( t y ) + c y
b w = p w e t w
b h = p h e t h
P r ( o b j e c t ) I O U ( b , o b j e c t ) = σ ( t o )
上面的描述可能不清楚,我们看下面的图像,yolo网络将416*416大小的输入,经过卷积缩小32倍,得到13*13的输出,如下图中Cx,Cy便代表cell相对于图像左上角的偏移,注意这里每个cell的宽度为1,sigmoid(tx)与sigmoid(ty)在0-1之间,这样就保证了中心点的偏移仍然在当前cell内,bw与bh是相对于pw于ph的缩放,pw与ph代表anchor的长宽,至于为什么在e上进行计算,这里我暂时觉得与faster rcnn中的log作用类似

https://img-blog.csdn.net/20170913081810622?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxNDM4MDE2NQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast

Fine-Grained Features

作者考虑到,模型最终输出是13*13,对于小物体的预测可能精度不够高,所以同样采用了类似于SSD的多个特征图的特征,但是作者不是像SSD那样直接对每个特征图进行分类与预测边界框,而是搞了一个passthrough layer,这个是怎么搞的呢?举例说明,作者对上一分辨率的输出(大小为:26*26*512),通过passthrough变换为13*13*2048大小,如何变换的如下图所示:作者利用pooling操作,将4*4的区域变换成4个channel,利用这样的方法,将特征图边长缩小一倍,但是channel数增大4倍,然后将2048维的13*13与原本的1024维的13*13进行concat,得到3072维度的特征图。(另,备注,这里可以采用1*1进行512维度的降维,比如降到64,这样passthrough之后就只有64*4=256维了,而不是2048那么大了
作者说这种方法,将精度提高了1%。

https://pic2.zhimg.com/80/v2-c94c787a81c1216d8963f7c173c6f086_hd.jpg

Multi-Scale Training

为了使yolo v2适应多种不同的尺度,作者采用了多尺度对yolo v2进行训练,作者每10个batches自动选择缩放的尺度,从[320:608:32]进行选择,最小的是320*320,最大的是608*608,为什么选择32呢?因为yolo v2的缩放是32倍,这样可以成倍的减少。

在测试阶段,不同的输入size可以产生不同的速度,作者的测试的mAP以及速度的结果如下:

https://pic3.zhimg.com/80/v2-71f001caa2968d5fb9196250d80f7b82_hd.jpg

YOLO V2使用技巧的提升效果如下图所示:
https://upload-images.jianshu.io/upload_images/4998541-c9351cd377d82589.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700

darkNet-19

为了提高模型的速度,作者没有采用yolo v1的inception结构或者vgg结构作者base net,而是设计了darkNet-19作为基础网络,darkNet-19采用与vgg相似的3*3卷积,并且没有采用全连接层,借鉴了NIN网络的思想,利用global average pooling替代了全连接层,使得参数进一步的减少,并且使用了bn等,使得梯度更加的稳定,dark-net在imagenet上的表现可以达到top1:72.9%, top5: 91.2%, darkNet-19的网络结构图,如下所示:

https://pic1.zhimg.com/v2-b23fdd08f65266f7af640c1d3d00c05f_r.jpg

具体参数为:

http://ww1.sinaimg.cn/large/87675bbbgy1fsq0r6ybmuj20b60fwwfi.jpg

训练过程

1.分类的训练

对于分类的训练,作者并没有什么特殊的方式,首先利用ImageNet训练160个epoch,采用梯度下降方法,采用多项式方法衰减学习率,weight decay 0.0005, momentum 0.9, 使用随机裁剪,旋转,亮度变换等方式进行数据增强。为了达到更好的效果,作者在448*448分辨率上进一步fine-tune网络10,做10个epoch,初始学习率为0.001。

2.检测的训练

对于检测网络,作者去掉最后一个卷积层,接3个1024*3*3的卷积层,然后接1*1的卷积层,输出维度为(num_anchor*(class + 5)),用于预测每个anchor的类别以及4个坐标加上置信度。同样检测迭代160个epoch,初始学习率为0.001,在60,90调整学习率为原来的0.1,weight decay为0.0005,momentum为0.9

Loss Function

https://pic2.zhimg.com/80/v2-58f1eec5594de9e887f22ac590b33062_hd.jpg

首先说明一下,YOLO中一个ground truth只会与一个先验框进行匹配,匹配原则是IOU最大这里不同于SSD以及RPN,其每个ground-truth会与多个IOU进行匹配

下面说一下这个损失函数,第一项loss是计算backgroud的置信度偏差,第二项是计算anchor与预测框的误差,第三项是计算ground truth与预测框的偏差以及置信度偏差和分类偏差。,比较复杂可以参考下面的链接,写的比较详细。
参考链接:https://towardsdatascience.com/training-object-detection-yolov2-from-scratch-using-cyclic-learning-rates-b3364f7e4755

YOLO9000

其实这是这篇文章最大的创新点,算是一个开创性的方法

YOLO9000的最大创新点在于不仅使用检测数据,同时使用了ImageNet分类数据,检测数据,使用带bounding box的损失函数,分类数据使用不带bounding box的损失函数,但是这样做遇到一个问题:imagenet数据有1000类,而voc只有20类,比如一个狗,imagenet中分为好多种,这样便存在包含关系,便无法使用softmax进行分类了,该如何解决呢?作者采用了一种层次分类的方法,如下图所示:

https://pic3.zhimg.com/80/v2-bda21cf48f8127c48fede60d81c4d97e_hd.jpg

在计算某个节点的类别概率时,遍历path,然后计算path上各个节点的概率之积。

作者在论文中提到为构建这颗树,将1000类增加中间节点到1369类,比如Norfold terrier即会label成dog同时会label成mammal

融合分类与检测同步进行训练

作者使用full ImageNet(top 9000 classes)以及COCO数据集进行训练,首先构建WordTree,共包含9418个类节点,每个节点都是一个softmax,由于ImageNet过大,这样分类和检测的数据严重不平衡,所以作者采用对COCO过采样的方式进行数据集扩增,扩增到ImageNet的1/4.

另外作者,使用3个anchor替代原来的5个,以减少网络的输出(由于这里类别数太多,而对于每个anchor,网络都会预测所属类别,所以减少2个anchor可以减少很多的网络输出,现在每个位置是3*(4+1+9418),原来是5*(4+1+9418))如果是待检测就用正常的yolo v2的损失,对于分类部分,只返回相应level的loss为什么呢?因为如果预测是狗,检测数据集并没有标注这是什么狗,你怎么返回具体是什么狗的loss呢~如果是遇到了一张分类的图像,首先返回分类的loss,就利用前面predict tree的计算方法(概率乘积),

这里有一块没懂:We also assume that the predicted box overlaps what would be the ground truth label by at least 0.3IOU and we backpropagate objectness loss based on this assumption.

总之作者总结到,这种方法就是:

Using this joint training, YOLO9000 learns to find objects in images using the detection data in COCO and it learns to classify a wide variety of these objects using data from ImageNet.

猜你喜欢

转载自blog.csdn.net/Chunfengyanyulove/article/details/80860870