实时目标检测YOLO系列之YOLOv3

论文地址:https://arxiv.org/abs/1804.02767

Abstract:   

      2018年,作者 Redmon 又在 YOLOv2 的基础上做了一些改进。特征提取部分采用darknet-53网络结构代替原来的darknet-19,利用特征金字塔网络结构实现了多尺度检测,分类方法使用逻辑回归代替了softmax,在兼顾实时性的同时保证了目标检测的准确性。

      从YOLOv1到YOLOv3,每一代性能的提升都与backbone(骨干网络)的改进密切相关。在YOLOv3中,作者不仅提供了darknet-53,还提供了轻量级的tiny-darknet。如果你想检测精度与速度兼具,可以选择darknet-53作为backbone;如果你希望达到更快的检测速度,精度方面可以妥协,那么tiny-darknet是你很好的选择。总之,YOLOv3的灵活性使得它在实际工程中得到很多人的青睐!

      最后,YOLOv3 与 SSD 的变体性能相当,但是速度提高了 3 倍。不过,它仍比 RetinaNet 模型差一些。随着 IOU 阈值增大YOLOv3 的性能会有所下降,这是由于 B-box 与物体完美对齐的效果不那么好。过去,YOLO 不擅长检测较小的物体,如今这种情况已经改变,但是它在中等尺寸和更大尺寸的物体上的表现相对较差。当用 AP_50 指标表示精确度和速度时,可以看到 YOLOv3 与其他检测系统相比具有显着的优势。

1. 基本介绍

(1)介绍

       YOLOv3是基于回归的方式进行特征提取的实时目标检测算法之一,通过端到端的过程训练网络,最终在多尺度融合的特征层中回归出目标的类别与位置。端到端的训练方式使得分类与定位过程为一体。其两者共同的损失函数参与反向传播计算,在节约特征提取时间的同时又提升了精度,满足了目标检测的实时性需求。

      相较于YOLOv1-v2,YOLOv3 同样是先在 ImageNet 上预训练,然后改为检测网络训练。特征提取网络是 DarkNet-53,含有 52 个卷积和 1 个全连接。与 DarkNet-19 相比,层数多了不少,主要的改变在于

  1. 去掉了池化层,全部由一个步长为 2 的卷积层完成下采样。

  2. 最后的全连接层又回来了。

  3. 内部出现了类似于 ResNet 的残差连接。

(2)原理

输入 416*416*3 的图像,通过 Darknet53 网络得到 三种 不同尺度的预测结果,每个尺度都对应 N 个通道,包含着预测的信息:

1. 每个网格每个尺寸的 anchors 的预测结果 。

2. 对比下yolov1,有 7*7*2 个预测 ;

3. 对比下yolov2,有 13*13*5 个预测 ;

4. YOLOv3共有 13*13*3 + 26*26*3  + 52*52*3 个预测 ;

5. 每个预测对应85维,分别是4个坐标值、1个置信度分数、80个类别(coco数据集)。

(3)成就

       YOLOv3在 Pascal Titan X 上处理 608x608 图像速度达到 51 FPS,在 COCO test-dev 上 mAP 达到 57.9%,与RetinaNet(FocalLoss论文所提出的单阶段网络)的结果相近,并且速度快4倍。

YOLO v3的模型比之前的模型复杂了不少,可以通过改变模型结构的大小来权衡速度与精度。速度对比如下图所示:

                                       

                                                

(4)创新点

YOLOv3 最大的改进之处主要在于网络结构的改进:

与 darknet-19 对比可知,darknet-53 主要做了如下改进

  • 没有采用最大池化层,转而采用步长为2的卷积层进行下采样。
  • 为了防止过拟合,在每个卷积层之后加入了一个BN层和一个Leaky ReLU。
  • 引入了残差网络的思想,目的是为了让网络可以提取到更深层的特征,同时避免出现梯度消失或爆炸。
  • 将网络的中间层和后面某一层的上采样进行张量拼接,达到多尺度特征融合的目的。

另外在多尺度预测、Bounding Box预测 和 类别预测也有所改进。

2. 网络结构及trick分析

(1)检测流程

YOLOv3框架如下图所示。

                         

        图中 DBL 结构是 YOLOv3 的基本组件,由卷积层,批量标准化与激活函数构成,如上图左下角所示。res unit 指的是残差组件,由两个卷积层和一个快捷链路组成。resn 结构为 YOLOv3 中的主要组成部分,n 代表数字,表示这个 res_block 里含有多少个 res_unit。该结构中包括零填充与残差结构,如上图右下角所示。图中用红色虚线框出的部分是骨干网络 Darknet53,该网络用于提取图像特征。concat:张量拼接。将darknet中间层和后面的某一层的上采样进行拼接,达到多尺度特征融合的目的。拼接的操作和残差层 add 的操作是不一样的,拼接会扩充张量的维度,而 add 只是直接相加不会导致张量维度的改变。

                                                    

       对于输出预测结果的三个特征图,特征图上每个像素点格子预测 3 个框,每个框都预测中心坐标 x,  y,高宽 h, w,存在物体的置信度c,k个类别的得分值(COCO数据集中 k 为80,VOC数据集中 k 为 20)。三层特征图一共输出 (13×13×3+26×26×3+52×52×3)个预测框。最后,将通过非极大值抑制(NMS)算法筛选出的预测框作为最终的检测框。再看最后输出的 255 个通道是怎么回事,255 = 3 × (80 + 5),首先这里是以 COCO 为基准,所以是 80。5 就是从 v1 一直延续来的;3 指的是三个 Anchors,在 v2 里是五个,而 v3 实际用了 9 个,平均分在三级预测上。

(2)Backbone

      Darknet-53主要由 1×1 和 3×3 的卷积层组成,每个卷积层之后包含一个批量归一化层和一个 Leaky ReLU,加入这两个部分的目的是为了防止过拟合。卷积层、批量归一化层以及 Leaky ReLU 共同组成 Darknet-53 中的基本卷积单元 DBL 。因为在Darknet-53 中共包含 53 个这样的 DBL ,所以称其为 Darknet-53 。YOLOv3 特征提取网络如下图所示。

                                                                   

       该结构以 416×416 图片作为输入,大量使用 1×1 3×3的卷积层进行堆砌,并使用残差网络,将浅层信息传递到深层,可在增加网络深度的同时不引起梯度爆炸等问题,上图中最左边的数字即代表所重复的残差网络模块的个数;Yolov3 结构在检测方面采用的是多尺度检测策略,使用 13×1326×2652×52 三个不同尺寸的特征图进行检测输出。最终使用 logistic 回归,对每个预测框进行目标性评分,根据目标性评分来选择满足需求的目标框,并对这些目标框进行预测。

        Darknet53 比 Darknet19 强大得多,而且比 ResNet-101 或 ResNet-152 更高效。Darknet-53 也可以实现每秒最高的测量浮点运算。以下是在 ImageNet 上的结果:BFLOP/s (billion floating point operations per second)

                                           

(3)Bounding Box Prediction

        在 Yolov3 目标检测框架中 anchor 十分重要,它是由当前数据集通过 kmeans 聚类算法统计出来的,合适的 anchor 值能够降低网络架构的损失值,加快收敛。在原始的 Yolov3 网络层中,依据 anchor boxes 的大小分成三组,将每组三个 anchor boxes均匀分布在预测层特征图上,最后通过网络预测出每个 anchor boxes的偏移量。如果真实框( ground truth ) 中某个物体的中心坐标落在 grid cell 里,就由该 grid cell 预测该物体,并且每个 grid cell 预测的边界框大小由 anchor 值决定,然后对预测的边界框与真实框的交互比( IoU ) 来选出超过 IoU 值的边界框去进行检测,为进一步减少不必要的检测次数,使用设置目标置信度的方法,当预测框的置信度小于该设定值就不再去检测该框。边界框回归如下图所示:

                                                           

       使用 dimension clusters 作为 anchor boxes

       该网络为每个B-box预测了4个坐标,tx、ty、tw、th。如果单元格与图像左上角的偏移量为(cx,cy);而先验B-box的宽度和高度为pw、ph,则预测对应:

                                                                        

        训练中,使用平方和误差损失,即GT值减去预测值(通过反求可以很容易地计算出这个GT值)。

        YOLOv3使用逻辑回归(sigmoid)预测每个B-box的目标得分。如果B-box与GT目标的重叠量大于任何其他B-box先验框,则score为1。如果先前的边界框不是最好的,但确实与GT目标重叠超过某个阈值,将会忽略该预测。如 Faster R-CNN一样,使用0.5 作为阈值。但与Faster R-CNN不同,本系统仅为每个GT目标分配一个B-box。如果先前的B-box未分配给一个ground truth 对象,则不会对坐标或类别预测造成损失,只会造成目标损失。

         在COCO数据集的实验中,每个尺度预测3个 box,因此tensor为 N×N× [3×(4 + 1 + 80)],4个边界框offset,1 对象预测,以及80个类别预测。接下来从之前的2个层中取得特征图,并对其进行2倍上采样。还从网络获取特征图,并使用 concatenation 将其与上采样特征进行合并。这种方法能够从上采样的特征和早期特征映射的细粒度信息中获得更有意义的语义信息。然后,添加几个卷积层来处理这个组合的特征图,并最终预测出一个相似的 Tensor。

         然后再次执行相同操作来对最终的scale预测 box。因此,对第3个scale的预测将从所有之前的计算中获益,并从早期的网络中获得精细的特征。这里仍然使用 k-means 聚类来确定bounding box priors。选择9个clusters和3个scales,然后在整个scales上均匀分割clusters。在COCO数据集上,9个cluster分别为(10×13),(16×30),(33×23),(30×61),(62×45),(59×119),(116×90),(156×198),(373×326)。

(4)Class Prediction

       每个框使用多标签分类来预测边界框可能包含的类。这里不使用softmax,因为它对于性能没有影响,而只是使用独立的逻辑分类器。在训练过程中使用二元交叉熵损失来进行类别预测。这个公式有助于转向更复杂的领域,如 Open Images 数据集。在这个数据集中有许多重叠的标签(例如,Woman 和 Person)。可以使用softmax 强加一个假设,即每个box只包含一个类别,但通常情况并非如此。多标签方法可以更好地模拟数据。

(5)Predictions Across Scales

                                             

       YOLOv3 在前两版本的基础上,采用了三种不同尺度的特征图来进行目标检测,可以看到卷积网络在第 79 层之后,经过 32 stride下采样之后得到 13×13 大小的特征图,卷积网络为了实现更细粒度的检测,在79层进行了上采样卷积,并返回去与第 61 层特征图融合,这样第 91 层特征图会有更加细粒的特征度。

        YOLOv3 用上采样的方法来实现这种多尺度的 feature map。在 Darknet-53 得到的特征图的基础上,经过六个 DBL 结构和最后一层卷积层得到第一个特征图谱,在这个特征图谱上做第一次预测。Y1 支路上,从后向前的倒数第 3 个卷积层的输出,经过一个 DBL 结构和一次(2,2)上采样,将上采样特征与第 2 个 Res8 结构输出的卷积特征张量连接,经过六个 DBL 结构和最后一层卷积层得到第二个特征图谱,在这个特征图谱上做第二次预测。Y2支路上,从后向前倒数第 3 个卷积层的输出,经过一个DBL 结构和一次(2,2)上采样,将上采样特征与第1个 Res8 结构输出的卷积特征张量连接,经过六个 DBL 结构和最后一层卷积层得到第三个特征图谱,在这个特征图谱上做第三次预测。

3. 损失函数设计

                                 

其中:

      网格共有K × K个,每个网格产生 个候选框 anchor,每个 anchor 经过网络会得到相应的 bounding box ,最终形成 K×K×M 个 bounding box,如果 box 内 noobj ,则只计算该 box 的置信 loss

1. 回归 loss 会乘以一个 (2 - w×h) 的比例系数,用来加大对小 box 的损失。

2. 置信度 loss 损失函数采用交叉熵,分为两部分:obj 和 noobj,其中 noobj 的 loss 还增加了权重系数 lambda,这是为了减少noobj 计算部分的贡献权重。

3. 分类 loss 损失函数采用交叉熵,当第 个网格的第 个 anchor box 负责某一个真实目标时,那么这个 anchor box 所产生的bounding box 才会去计算分类损失函数。

 1         # K.binary_crossentropy is helpful to avoid exp overflow.
 2         xy_loss = object_mask * box_loss_scale * K.binary_crossentropy(raw_true_xy,  \
           raw_pred[...,0:2], from_logits=True)
 3         wh_loss = object_mask * box_loss_scale * 0.5 * K.square(raw_true_wh-  \
             raw_pred[...,2:4])
 4         confidence_loss = object_mask * K.binary_crossentropy(object_mask, \
            raw_pred[...,4:5], from_logits=True)+ \
 5             (1-object_mask) * K.binary_crossentropy(object_mask, raw_pred[...,4:5],  \
                from_logits=True) * ignore_mask
 6         class_loss = object_mask * K.binary_crossentropy(true_class_probs,   \                  
           raw_pred[...,5:], from_logits=True)
 7 
 8         xy_loss = K.sum(xy_loss) / mf
 9         wh_loss = K.sum(wh_loss) / mf
10         confidence_loss = K.sum(confidence_loss) / mf
11         class_loss = K.sum(class_loss) / mf
12         loss += xy_loss + wh_loss + confidence_loss + class_loss
13         if print_loss:
14             loss = tf.Print(loss, [loss, xy_loss, wh_loss, confidence_loss, class_loss,\
               K.sum(ignore_mask)], message='loss: ')
15         return loss

4. 训练与测试

(1)训练结果

上述数据统一在 TitanX 下测试,最后一项 BFLOP/s 意味着 Darknet 对 GPU 的利用更好。

(2)测试结果

                    

       从上表可以看出,YOLOv3 在 COCO 上的结果以及到了和 ResNet-FasterRCNN 接近的水平,但是时间仅需 51ms,比后者少三倍多。同时,在 AP_50 指标上 YOLO 表现得很好,说明很大一部分的问题来自于框的位置的不准确。

5. 尝试过没有效果

  1.  Anchor box  x、y 偏移量预测。尝试使用常规的anchor box预测机制,可以使用线性激活将x,y的偏移预测为box的宽度或高度的倍数。但是发现这种方法降低了模型的稳定性,并且效果不佳。
  2.  Linear x,y 预测代替逻辑预测。尝试使用线性激活来直接预测 x,y 的偏移,而不是用逻辑激活。这导致了mAP的下降。
  3.  Focal loss。尝试使用 Focal loss。这一方法使 mAP 降低了2 点左右。YOLOv3 Focal loss 解决的问题可能已经很强健,因为它具有单独的对象预测和条件类别预测。因此,对于大多数例子来说,类别预测没有损失?或者其他原因?这点还不完全确定。

6. 总结

       YOLOv3 的损失函数是在 YOLOv2 基础上改动的,最大的变动是分类损失换成了二分交叉熵,这是由于 YOLOv3 中剔除了softmax 改用 logistic不过在不同的框架中具体的修改不一致。

       大多数分类器认为目标分类是互斥的,所以 YOLOv2 用的是 softmax,全部分类的概率之和为 1。但是 YOLOv3 使用了多标签分类。比如,标签可能既是行人也可能是小孩。YOLOv3为每个分类使用独立的logistic分类器以计算输入属于特定分类的概率。yolov3 给每个分类用的是二分交叉熵,而非 MSE。此举同时降低了计算复杂度。为实现多标签分类就需要用逻辑分类器来对每个类别都进行二分类。逻辑分类器主要用到了 sigmoid 函数,它可以把输出约束在 0 到 1,如果某一特征图的输出经过该函数处理后的值大于设定阈值,那么就认定该目标框所对应的目标属于该类。

7. 参考文献

https://blog.csdn.net/leviopku/article/details/82660381

https://www.cnblogs.com/ywheunji/p/10809695.html

https://tangh.github.io/articles/yolo-from-v1-to-v4/

https://blog.csdn.net/wjinjie/article/details/107509243?utm_source=app

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值