YOLOv1
paper title:You only look once: Unified, real-time object detection
paper link:https://arxiv.org/pdf/1506.02640.pdf
oral presentation:https://www.youtube.com/watch?v=NM6lrxy0bxs
darknet YOLO: https://pjreddie.com/darknet/yolo/
YOLOv1 TensorFlow代码解析
YOLOv1(以下YOLO均指YOLOv1)实现了端到端的目标检测任务,无需进行候选框提取,速度很快。不同于R-CNN,Fast R-CNN将物体检测任务转化为分类问题,YOLO将物体检测看作一个回归问题,通过将图片划分为一些格子,使用网络预测在这些格子上的目标的Bounding box和类别。
。
基本思路:
YOLO将图片为成S*S
个格子,在每一个格子上预测目标的Bounding box和类别,每个格子上输出一个长度为B*5+K
的输出结果,其中B是每个格子上预测的Bbox的数目,包括五个维度x,y,w,h,C
,四个坐标值和一个分数,K
是分类目标的数目,最后的网络输出是S*S*(B*5+K)
的tensor。
在预测的Bbox的五个维度中x,y
是中心点坐标,这个中心点坐标指相对于格子左上角的相对坐标,并用格子的宽度进行归一化,也就是一个归一化的偏移量,;w,h
是Bbox的宽和高,是指用图像的宽和高进行归一化后的值;知道了Bbox坐标的这两个信息之后,就可以在预测时根据输出结果恢复Bbox在图像中的像素坐标位置。
C
是confidence score,这个分数体现了模型有多确定这个Bbox包含目标并且就是它要预测的那个。 当格子中包含物体的时候,希望这个分数等于预测的Bbox和truth Bbox 的IoU;当格子没有物体的时候,希望这个分数为0。
K
是分类的数目。K个值实际上对应目标物体属于每个类别的分数,YOLO文章中不管B为多少,即预测几个Bbox, 目标类别的分数只有一套。
网络结构:
YOLO的网络结构(参考了inceptionv1的网络结构,但是沒有使用inception模块,只是使用{3x3+1x1}的这样的结构):
最后网络输出的是一个7x7x30(dataset:Pascal VOC)的tensor, 7x7是一开始划分的格子的数目,30=(2*5+20),2个box,每个box有五个值x,y,w,h,C
,以及20个class。
网络训练: 在ImageNet 1000类的分类任务上对模型的前20个卷积层进行了预训练,预训练的时候卷积层后面接的是平均池化层和全连接层。网路使用Leaky ReLu(0.1x)作为激活函数;使用darknet框架进行训练;learning-rate的设置:第一个epoch从 1 0 − 3 10^{-3} 10−3缓慢升到 1 0 − 2 10^{-2} 10−2,然后使用 1 0 − 2 10^{-2} 10−2训练75个epoch,然后用 1 0 − 3 10^{-3} 10−3训练30个epoch, 1 0 − 4 10^{-4} 10−4训练30个epoch。Batch size 设置为64;使用momentum优化函数,参数设置为0.9;weight decay权重为0.005;
损失函数: 坐标损失[x,y,w,h
] + 目标信心(confidence)损失[C
] + 类别损失[p
]
L o s s ( x , y , w , h , C , p ) = λ c o o r d ∑ i = 0 s 2 ∑ j = 0 B 1 i j o b j [ ( x i j − x ^ i j ) 2 − ( y i j − y ^ i j ) 2 ] + λ c o o r d ∑ i = 0 s 2 ∑ j = 0 B 1 i j o b j [ ( w i j − w ^ i j ) 2 − ( h i j − h ^ i j ) 2 ] + ∑ i = 0 s 2 ∑ j = 0 B 1 i j o b j ( C i j − C ^ i j ) 2 + λ n o o b j ∑ i = 0 s 2 ∑ j = 0 B 1 i j n o o b j ( C i j − C ^ i j ) 2 + ∑ i = 0 s 2 1 i o b j ∑ c ∈ c l a s s ( p i ( c ) − p ^ i ( c ) ) 2 \begin{aligned} Loss(x,y,w,h,C,p) = &\lambda_{coord}\sum_{i=0}^{s^2}\sum_{j=0}^{B}1_{ij}^{obj}[(x_{ij}-\hat{x}_{ij})^2-(y_{ij}-\hat{y}_{ij})^2] \\ & +\lambda_{coord}\sum_{i=0}^{s^2}\sum_{j=0}^{B}1_{ij}^{obj}[(\sqrt{w_{ij}}-\sqrt{\hat{w}_{ij}})^2-(\sqrt{h_{ij}}-\sqrt{\hat{h}_{ij}})^2] \\ & +\sum_{i=0}^{s^2}\sum_{j=0}^{B}1_{ij}^{obj}(C_{ij}-\hat{C}_{ij})^2 \\ & +\lambda_{noobj}\sum_{i=0}^{s^2}\sum_{j=0}^{B}1_{ij}^{noobj}(C_{ij}-\hat{C}_{ij})^2 \\ & +\sum_{i=0}^{s^2}1_i^{obj}\sum_{c\in class}(p_i(c)-\hat{p}_i(c))^2 \end{aligned} Loss(x,y,w,h,C,p)=λcoordi=0∑s2j=0∑B1ijobj[(xij−x^ij)2−(yij−y^ij)2]+λcoordi=0∑s2j=0∑B1ijobj[(wij−w^ij)2−(hij−h^ij)2]+i=0∑s2j=0∑B1ijobj(Cij−C^ij)2+λnoobji=0∑s2j=0∑B1ijnoobj(Cij−C^ij)2+i=0∑s21iobjc∈class∑(pi(c)−p^i(c))2
其中:
通俗地说,在YOLO网络的输出结果中,每个格子会预测B个Bbox,比如2个,损失函数里的‘responsible predictor’ 是指在目标的中心落在的那个格子中,预测的B个Bbox中的与目标物体的truth Bbox的IoU最大的那个Bbox。例如下图中的左一,图片分成7*7的格子,图中狗的truth Bbox是红色的框,网络给出的预测是是绿色的那两个。如图左二,目标“狗”的中心落在绿色的格子里,这个绿色的格子就是文章中说的“responsible for detecting that object”的格子,‘Object appears’的格子就是绿色的这个格子(这只是其中一个目标物体的,还有自行车,汽车也有对应的格子)。训练的时候,这个格子会给出两个预测的Bbox,‘ “responsible” for that prediction ’就是左一图中较大的那个绿色框,它与目标的truth Bbox(红色的)的IoU最大。 计算损失的时候,坐标损失(包括中心坐标,宽,高)只算较大的绿色的那个Bbox;计算类别损失的时候,只计算左二图中绿色的那个格子的类别损失(也看到有代码实现中,计算类别损失时计算的是物体的truth Bbox覆盖到的那些格子,也就是右一图中红色的那些格子);计算Confidence损失的时候所有的Bbox都计算,但是分成两类,一类是之前用于计算坐标损失的那一个Bbox,另一类是其他所有Bbox的,两者权重有所不同,前者是5,后者是0.5。
YOLO的不足:
(1)每个格子只预测两个Bbox和一个类别,所以限制了对靠近在一起的物体的可预测的数目;另外对聚集在一起的小物体的检测效果不好;
(2)对不常见的宽高比的Bbox泛化能力较差;由于网络架构中使用了down sampling,所有用来预测box的特征也是相对粗糙的;
(3)损失函数中对不同大小的Bbox的损失误差是一样计算的,但是同样的误差对小的Bbox的IoU影响更大。
YOLOv2 & YOLO9000
title: YOLO9000:Better,Faster,Stronger
aiXiv:https://arxiv.org/pdf/1612.08242.pdf
conf & anthor: CVPR17, Redmon, Joseph, and Ali Farhadi.
arXiv submit v1: 2016.12 google citation:1699(2019.02.26)
intro:multi-scale traning, jointly training, wordTree
YOLOv2在YOLOv1的基础上从网络结构,训练方法等多方面进行了改进,得到YOLOv2,并在此基础上提出了一种在检测和分类数据集上联合训练的方法,构建了YOLO9000,可以完成超过9000类的物体的实时检测。
在YOLOv2中,作者使用了一系列的方法来改进YOLOv1的不足,包括:
(1) Batch Normalization:加快拟合,减少正则,mAP提升2%;
(2) High Resolution Classifier :首先在ImageNet上使用448*448的输入尺寸训练分类模型,然后在检测任务上进行fine-tuning;
(3) Convolution with Anchor Boxes :参照Faster R-CNN使用anchor boxes.使用了anchor box之后预测的box由原来的98个(7x7x2)增加到上千个,并实验发现recall增大了,但是mAP稍微有所下降(0.3mAP)。这时遇到两个问题,一是anchor box的尺寸和宽高比是手工设定的;二是模型在训练的早前的不稳定性,主要由模型预测的坐标的格式(归一化的偏移量)造成。针对这两个问题,文中分别给出了优化方案。对于手动设定的宽高比问题,作者采用K-means聚类来选择宽高比,BBox到聚类中心的距离 d ( b o x , c e n t r o i d ) = 1 − I o U ( b o x , c e n t r o i d ) d(box,centroid)=1-IoU(box,centroid) d(box,centroid)=1−IoU(box,centroid);对于预测的坐标格式问题,YOLOv2中没有使用Faster R-CNN中预测predict box相对于anchor box归一化的偏移量,而是按照YOLOv1中的做法,预测的是predict box中心相对于feature map 中cell左上角的偏移量。
(4) Fine-Grained Features:为了使网络能够检测出小物体,作者使用了细粒度的特征,即将最后anchor box所在的层的前一层的信息通过跨层连接整合到一起,如下图,将 L n − 1 L_{n-1} Ln−1相邻位置的特征拆分为到不同道的通道中去,然后与 L n L_{n} Ln层连接到一起,得到新的 L n ′ L_{n}^{'} Ln′。通过这样的操作使得网络可以使用细粒度的特征,提高检测效果。
(5) Multi-scale Training:作者希望YOLOv2能够在不同尺寸的图像上都能够稳定的进行检测,由于网络中只有卷积和池化层,所以作者就设计了在不同尺寸训练的图片上进行训练的方法,每10个mini-batch,改变输入的图片的尺寸,输入图片的尺寸最小为320,最大为608,每32为一个间隔。
(6) Hierarchical Classification:作者为了进行检测和分类的联合训练,需要对数据集进行合并,由于不同的数据集的标签的“广度”和“深度”并不相同,例如检测的数据集PASCAL VOC中有“dog”标签,但是ImageNet中有很多种不同品种的“dog”的标签,标签的“深度”不同,另外标签的数目也差距很大,这样在融合数据集的时候就需要使用适当的方法。作者采用的是从ImageNet的标签中构建有层级的树(WordTree)的方式来进行数据集的融合,从大的概念出发,随着树的生产,逐步细化到细的概念,如动物->哺乳动物->犬类->狗->拉布拉多犬。模型在进行分类预测的时候预测是WordTree上每一个相关的节点上的条件概率,如P(哺乳动物|犬类)。使用这种层级方式构建的WordTree,不同节点之间已经不是完全互斥的了,所以softmax,也改成了多个共父节点的softmax的组合。
(7) Joint classification and detection:使用WordTree对COCO和ImageNet数据集进行合并,最后有9418个类别。由于COCO数据集样本相对较少,所以进行了过采样,最后与ImageNet的样本数量比例约为1:4。在联合训练的时候,如果输入的是一个分类的样本,就只计算分类的损失并反向传播,如果是一个检测样本,就正常计算损失。基于合并的数据集,使用联合训练的方法,训练了YOLO9000
,可以实时检测超过9000类物体。