论文: You Only Look Once:Unified, Real-Time Object Detection.
项目主页: https://pjreddie.com/darknet/yolo/.
来源:CVPR 2016
注意:class信息是针对每个网格的,confidence信息是针对每个bounding box的。
回归问题:sum-squared error loss
L o s s = ∑ i = 1 S 2 L i = ∑ i = 1 S 2 ∣ ∣ T i p r e d − T i t r u t h ∣ ∣ 2 2 Loss=\sum_{i=1}^{S^2}L_i=\sum_{i=1}^{S^2}||T_i^{pred}-T_i^{truth}||_2^2 Loss=i=1∑S2Li=i=1∑S2∣∣Tipred−Titruth∣∣22其中,
T i p r e d = [ T i l o c , T i c o n f , T i p r o b ] T_i^{pred}=[T_i^{loc},T_i^{conf},T_i^{prob}] Tipred=[Tiloc,Ticonf,Tiprob] T i l o c = [ x i 1 , y i 1 , w i 1 , h i 1 , x i 2 , y i 2 , w i 2 , h i 2 ] T_i^{loc}=[x_i^1,y_i^1,w_i^1,h_i^1,x_i^2,y_i^2,w_i^2,h_i^2] Tiloc=[xi1,yi1,wi1,hi1,xi2,yi2,wi2,hi2] T i c o n f = [ c i 1 , c i 2 ] T_i^{conf}=[c_i^1,c_i^2] Ticonf=[ci1,ci2] T i p r o b = [ p i 1 , p i 1 , . . . , p i 20 ] T_i^{prob}=[p_i^1,p_i^1,...,p_i^{20}] Tiprob=[pi1,pi1,...,pi20] T i t r u t h T_i^{truth} Titruth是与 T i p r e d T_i^{pred} Tipred对应的30维真实标签。
改进1:
8维的定位损失和22维的分类损失同等重要显然是不合理的,解决办法是更重视8维的坐标预测,给定位损失赋予更大的loss weight,即设置 λ c o o r d = 5 \lambda_{coord}=5 λcoord=5,损失函数改进为:
L o s s = λ c o o r d ∑ i = 1 S 2 ∣ ∣ T i l o c − T ^ i l o c ∣ ∣ 2 2 + ∑ i = 1 S 2 ∣ ∣ T i c o n f − T ^ i c o n f ∣ ∣ 2 2 + ∑ i = 1 S 2 ∣ ∣ T i p r o b − T ^ i p r o b ∣ ∣ 2 2 Loss=\lambda_{coord}\sum_{i=1}^{S^2}||T_i^{loc}-\hat{T}_i^{loc}||_2^2+\sum_{i=1}^{S^2}||T_i^{conf}-\hat{T}_i^{conf}||_2^2+\sum_{i=1}^{S^2}||T_i^{prob}-\hat{T}_i^{prob}||_2^2 Loss=λcoordi=1∑S2∣∣Tiloc−T^iloc∣∣22+i=1∑S2∣∣Ticonf−T^iconf∣∣22+i=1∑S2∣∣Tiprob−T^iprob∣∣22
改进2:
输入图像中的ground truth通常是很少的,这使得很多网络没有object,对于这些没有object的网格,不需要给出20个类别概率,所以在损失函数中也不应该有这部分损失,所以引入指示函数 I i o b j {\mathbb I}_i^{obj} Iiobj,表示某个object的中心落入第 i i i个网格中,损失函数变成:
L o s s = λ c o o r d ∑ i = 1 S 2 ∣ ∣ T i l o c − T ^ i l o c ∣ ∣ 2 2 + ∑ i = 1 S 2 ∣ ∣ T i c o n f − T ^ i c o n f ∣ ∣ 2 2 + ∑ i = 1 S 2 I i o b j ∣ ∣ T i p r o b − T ^ i p r o b ∣ ∣ 2 2 Loss=\lambda_{coord}\sum_{i=1}^{S^2}||T_i^{loc}-\hat{T}_i^{loc}||_2^2+\sum_{i=1}^{S^2}||T_i^{conf}-\hat{T}_i^{conf}||_2^2+\sum_{i=1}^{S^2}{\mathbb I}_i^{obj}||T_i^{prob}-\hat{T}_i^{prob}||_2^2 Loss=λcoordi=1∑S2∣∣Tiloc−T^iloc∣∣22+i=1∑S2∣∣Ticonf−T^iconf∣∣22+i=1∑S2Iiobj∣∣Tiprob−T^iprob∣∣22
改进3:
在构造训练标签时,物体的中心落入哪个网格,就由该网格负责预测它,但具体是由该网格的哪个box来预测它,需要通过网络输出来确定,即该网格中的哪个box与该gt框的IoU大,则由该box负责预测它(事后确定,动态变化)。由于98个box是未知的,所以在构造真实位置标签时,同一个grid cell的两个box的位置标签是一样的,都是GT框中心相对于该网格中心的偏移量以及GT框宽高相对于图像宽高的比例。
这样子,无需负责预测任何object的box,将不产生loc损失。用指示函数 I i j o b j {\mathbb I}_{ij}^{obj} Iijobj,表示第 i i i个网格中的第 j j j个box负责预测某个object。如此一来,很多box都是不需要预测object的(这些box可以称为二分类中的negative),如此多的negative box虽然有助于二分类,但会淹没positive box的作用(正负样本不平衡),所以对negative box产生的conf损失添加一个权重因子 λ n o o b j = 0.5 \lambda_{noobj}=0.5 λnoobj=0.5,最终损失函数变成:
L o s s = λ c o o r d ∑ i = 1 S 2 ∑ j = 1 B I i j o b j ∣ ∣ T i j l o c − T ^ i j l o c ∣ ∣ 2 2 Loss=\lambda_{coord}\sum_{i=1}^{S^2}\sum_{j=1}^{B}{\mathbb I}_{ij}^{obj}||T_{ij}^{loc}-\hat{T}_{ij}^{loc}||_2^2 Loss=λcoordi=1∑S2j=1∑BIijobj∣∣Tijloc−T^ijloc∣∣22 + ∑ i = 1 S 2 ∑ j = 1 B I i j o b j ∣ ∣ c i j − c ^ i j ∣ ∣ 2 2 + λ n o o b j ∑ i = 1 S 2 ∑ j = 1 B I i j n o o b j ∣ ∣ c i j − c ^ i j ∣ ∣ 2 2 +\sum_{i=1}^{S^2}\sum_{j=1}^{B}{\mathbb I}_{ij}^{obj}||c_i^j-{\hat{c}}_i^{j}||_2^2+\lambda_{noobj}\sum_{i=1}^{S^2}\sum_{j=1}^{B}{\mathbb I}_{ij}^{noobj}||c_i^j-{\hat{c}}_i^{j}||_2^2 +i=1∑S2j=1∑BIijobj∣∣cij−c^ij∣∣22+λnoobji=1∑S2j=1∑BIijnoobj∣∣cij−c^ij∣∣22 + ∑ i = 1 S 2 I i o b j ∣ ∣ T i p r o b − T i ^ p r o b ∣ ∣ 2 2 +\sum_{i=1}^{S^2}{\mathbb I}_i^{obj}||T_i^{prob}-\hat{T_i}^{prob}||_2^2 +i=1∑S2Iiobj∣∣Tiprob−Ti^prob∣∣22
改进4:
对不同大小的box预测中,相比于大box预测偏一点,小box预测偏一点肯定更不能被忍受的。而sum-square error loss中对同样的偏移loss是一样。
为了缓和这个问题,作者用了一个比较取巧的办法,就是将box的width和height取平方根代替原本的height和width(已采用原图的宽和高归一化至[0,1])。这个参考下面的图很容易理解,小box的横轴值较小,发生偏移时,反应到y轴上相比大box要大。(也是个近似逼近方式)
最终损失函数变成:
L o s s = λ c o o r d ∑ i = 1 S 2 ∑ j = 1 B I i j o b j [ ( x i j − x ^ i j ) 2 + ( y i j − y ^ i j ) 2 ] Loss=\lambda_{coord}\sum_{i=1}^{S^2}\sum_{j=1}^{B}{\mathbb I}_{ij}^{obj}\left[\left ( x_{i}^j-\hat{x}_i^j \right)^2+\left ( y_{i}^j-\hat{y}_i^j \right)^2\right] Loss=λcoordi=1∑S2j=1∑BIijobj[(xij−x^ij)2+(yij−y^ij)2] + λ c o o r d ∑ i = 1 S 2 ∑ j = 1 B I i j o b j [ ( w i j − w ^ i j ) 2 + ( h i j − h ^ i j ) 2 ] +\lambda_{coord}\sum_{i=1}^{S^2}\sum_{j=1}^{B}{\mathbb I}_{ij}^{obj}\left[\left ( \sqrt{w_{i}^j}-\sqrt{\hat{w}_i^j} \right)^2+\left ( \sqrt{h_{i}^j}-\sqrt{\hat{h}_i^j} \right)^2\right] +λcoordi=1∑S2j=1∑BIijobj[(wij−w^ij)2+(hij−h^ij)2] + ∑ i = 1 S 2 ∑ j = 1 B I i j o b j ∣ ∣ c i j − c ^ i j ∣ ∣ 2 2 + λ n o o b j ∑ i = 1 S 2 ∑ j = 1 B I i j n o o b j ∣ ∣ c i j − c ^ i j ∣ ∣ 2 2 +\sum_{i=1}^{S^2}\sum_{j=1}^{B}{\mathbb I}_{ij}^{obj}||c_i^j-{\hat{c}}_i^{j}||_2^2+\lambda_{noobj}\sum_{i=1}^{S^2}\sum_{j=1}^{B}{\mathbb I}_{ij}^{noobj}||c_i^j-{\hat{c}}_i^{j}||_2^2 +i=1∑S2j=1∑BIijobj∣∣cij−c^ij∣∣22+λnoobji=1∑S2j=1∑BIijnoobj∣∣cij−c^ij∣∣22 + ∑ i = 1 S 2 I i o b j ∣ ∣ T i p r o b − T i ^ p r o b ∣ ∣ 2 2 +\sum_{i=1}^{S^2}{\mathbb I}_i^{obj}||T_i^{prob}-\hat{T_i}^{prob}||_2^2 +i=1∑S2Iiobj∣∣Tiprob−Ti^prob∣∣22
其他细节:
优点:
缺点:
论文: YOLO9000: Better, Faster, Stronger.
项目主页: https://pjreddie.com/darknet/yolo/.
时间:2016
与基于候选区域的两阶段目标检测算法(如Fast R-CNN)相比,YOLO存在以下两个问题:
作者针对YOLO存在的两个问题,进行了多方面的改进,最终得到了当时的SOTA目标检测算法:YOLOv2。
BN算法既能使网络更容易训练,又能防止模型过拟合,提高模型的泛化能力。BN算法有助于解决反向传播过程中的梯度消失和梯度爆炸问题,降低对一些超参数(比如学习率、网络参数的大小范围、激活函数的选择)的敏感性,并且每个batch分别进行归一化的时候,起到了一定的正则化效果(YOLOv2不再使用dropout),从而能够获得更好的收敛速度和收敛效果。具体原理请参考:BN算法。
作者在YOLO网络的所有卷积层上使用BN算法,并移除全连接层上的Dropout,该做法提高了2.4%的mAP。
YOLOv1在ImgeNet数据集上预训练了一个分辨率为 224 × 224 224\times224 224×224的网络(网络的分辨率指的是输入图像的分辨率),该预训练网络为Darknet-19(20 conv + 1 avg_pool + 1 fc),训练后移除1 avg_pool + 1 fc,并在20 conv后面加上4 conv + 2 fc,得到YOLOv1网络,接着在目标检测数据集上对YOLOv1网络进行训练,此时网络的分辨率由 224 × \times × 224 提高到 448 × \times × 448 。在训练时,YOLOv1网络在目标检测数据集上既要适应新的分辨率,又要完成检测任务,这可能影响目标检测的准确性。
针对以上问题,YOLOv2将适应新分辨率和进行目标检测这两项任务分开,即,先采用 224 × 224 224\times224 224×224 的ImageNet图像进行分类模型预训练(160个epoch),再采用 448 × 448 448\times448 448×448的高分辨率分类样本对分类模型进行微调(10个epoch),使网络特征逐渐适应 448 × 448 448\times448 448×448 的分辨率。修改网络后再使用 448 × 448 448\times448 448×448的检测样本进行训练,缓解了分辨率突然切换造成的影响。该做法又提高了4%的mAP。
使用卷积层代替全连接层:
YOLOv1全连接层的使用,即引入了大量的参数和计算量,又限制了网络的输入大小。YOLOv2借鉴了RPN和SSD的做法,只使用卷积层进行预测,使网络输入为任意大小。
YOLOv2移除了YOLO网络的全连接层,并去掉了网络中的一个pooling层,这让卷积层的输出能有更高的分辨率。此时输入图像分辨率为 416 × 416 416\times416 416×416,总的下采样率为32(5个下采样率均为2的最大池化层),最终得到 13 × 13 13\times13 13×13的特征图。
将图像分辨率由 448 × 448 448\times448 448×448减小为 416 × 416 416\times416 416×416的原因:
由于图片中的物体都倾向于出现在图片的中心位置,特别是那种比较大的物体,所以由一个单独位于物体中心的位置用于预测这些物体会比较好(而不是最中间的4个)。YOLOv2的总的下采样率为32, 416 × 416 416\times416 416×416的输入图像可以输出奇数的特征图尺寸 13 × 13 13\times13 13×13( 448 × 448 448\times448 448×448的输入图像可以输出偶数的特征图尺寸 14 × 14 14\times14 14×14)。
引入anchor:
借鉴Faster RCNN的做法,YOLOv2也尝试采用先验框(anchor)。在 13 × 13 13\times13 13×13的特征图上的每个grid预先设定一组不同大小和宽高比的边界框,来覆盖整个图像的不同位置和多种尺度的物体,这些先验框作为预定义的候选框在神经网络中将检测其中是否存在对象,以及微调边界框的位置。
之前YOLOv1并没有采用anchor,并且每个grid只预测2个bounding box,整个图像98个。YOLOv2每个grid采用5个anchor,则总共有 13 ∗ 13 ∗ 5 = 845 13*13*5=845 13∗13∗5=845个anchor。
最终结果:召回率大幅提升到88%,同时mAP轻微下降了0.2。
在Faster R-CNN和SSD中,anchor的数量、大小、宽高比都是手动选择的(或通过实验结果来确定),anchor的大小和宽高比越符合数据集,那么边界框回归会更容易,目标检测结果也会更好。因此,YOLOv2使用 k-means 聚类在训练集中自动聚类出 k k k个anchor(宽、高),再通过实验,由平均IoU指标来确定anchor的数量,如下所示:
通过平衡召回率和模型复杂度,最终确定 k = 5 k=5 k=5。此外,由图可以看出,COCO中物体尺寸的差异程度要比VOC大。
k-means聚类中用到了距离来度量相似性,在此问题中,如果采用欧式距离,大框产生的loss会比小框大,并且最终的聚类目标是找到最符合的anchor(IoU最小),但欧式距离小并不意味着IoU小,所以YOLOv2采用如下的相似性度量方法:
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)
由于设置了anchor,YOLOv2原本可以像Faster R-CNN一样,通过预测anchor boxes的坐标偏移量和置信度来预测 bounding box,而不是直接预测坐标值。但是,作者在实际应用中发现,在训练的早期阶段,预测中心点的偏移量会导致网络训练不稳定:
{ x = ( t x ∗ w a ) + x a y = ( t y ∗ h a ) + y a \left\{ \begin{aligned} x & = & (t_x*w_a)+x_a \\ y & = & (t_y*h_a)+y_a \\ \end{aligned} \right. { xy==(tx∗wa)+xa(ty∗ha)+ya其中, x , y x,y x,y是预测边界框的中心点坐标, x a , y a x_a,y_a xa,ya是anchor的中心点坐标, w a , h a w_a,h_a wa,ha是anchor的宽和高, t x , t y t_x,t_y tx,ty是网络的输出偏移量。
由于 t x , t y t_x,t_y tx,ty的取值没有任何约束,因此预测边框的中心可能出现在任何位置,训练早期阶段不容易稳定。YOLOv2调整了边界框中心点的预测公式,将预测边界框的中心约束在特定gird cell内。
{ b x = σ ( t x ) + c x b y = σ ( t y ) + c y b w = p w e x p ( e t w ) b h = p h e x p ( e t h ) \left\{ \begin{aligned} b_x & = & \sigma(t_x)+c_x \\ b_y & = & \sigma(t_y)+c_y \\ b_w & = & p_wexp(e^{t_w}) \\ b_h & = & p_hexp(e^{t_h}) \\ \end{aligned} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧bxbybwbh====σ(tx)+cxσ(ty)+cypwexp(etw)phexp(eth) P r ( o b j e c t ) ∗ I O U ( b , o b j e c t ) = σ ( t o ) P_r(object)*IOU(b,object)=\sigma(t_o) Pr(object)∗IOU(b,object)=σ(to)
注意:YOLOv2只修改边界框中心点坐标的预测公式,边界框宽高的预测公式与Faster R-CNN相同。
借鉴VGG的结构:conv不改变特征尺寸,只改变通道数;pooling不改变通道数,但将特征尺寸缩小一半;pooling之后的第一个conv都使通道数加倍。
借鉴Network in Network (NIN): 3 × 3 3\times3 3×3卷积之间使用 1 × 1 1\times1 1×1卷积来压缩特征图channles以降低模型计算量和参数,在最后使用全局池化层。
Darknet-19每个卷积层后面使用了BN层以加快收敛速度,降低模型过拟合。
YOLOv2的网络结构图为:
网络修改包括:移除最后一个卷积层、global avgpooling层以及softmax层,并且新增了三个 3 × 3 × 1024 3\times3\times1024 3×3×1024卷积层,同时增加了一个passthrough层,最后使用 1 × 1 1\times1 1×1卷积层输出预测结果,输出的channels数为: # a n c h o r \# anchor #anchor*(5+类别总数)$。由于anchors数为5,对于VOC数据集输出的channels数就是125,而对于COCO数据集则为425。
总结:
相对于YOLOv2,YOLOv3的改进之处:
Softmax使得每个框分配一个类别(score最大的一个),而对于Open Images这种数据集,目标可能有重叠的类别标签,因此Softmax不适用于多标签分类。
Softmax可被独立的多个logistic分类器替代,且准确率不会下降。
分类损失采用binary cross-entropy loss。
在Darknet-19的基础上添加更多的卷积层,并借鉴ResNet,引入残差结构,得到如下Darknet-53:
注: anchor的设计方式仍采用k-means聚类,得到9个聚类中心,将其按照大小均分给3个尺度,每种尺度预测3个box。
YOLOv4 在COCO上,可达43.5% AP,速度高达 65 FPS!
本文的主要贡献如下:
YOLOv4模型由以下部分组成:
YOLOv4的特点是集大成者,俗称堆料。但最终达到这么高的性能,一定是不断尝试、不断堆料、不断调参的结果。下面看看堆了哪些料:
其中YOLOv4用到相当多的技巧: