YOLOv4目标检测算法——通俗易懂的解析

一.前沿
  前三篇文章我们讲了下关于YOLOv1、YOLOv2、YOLOv3的原理,有不懂的小伙伴可以回到前面再看看:

  • YOLOv1目标检测算法——通俗易懂的解析
  • YOLOv2目标检测算法——通俗易懂的解析
  • YOLOv3目标检测算法——通俗易懂的解析
      YOLO系列作者Joseph Redmon在看到YOLOv3被用于军方之后,基于伦理道德的问题Joseph Redmon将从YOLOv3开始不在更新YOLO系列,俄罗斯的Alexey Bochkovskiy大神接过了YOLO的大旗,于2020年提出了YOLOv4,真是疫情都阻挡不了大佬们对科研的热情。
      前面我们在讲解YOLOv3的时候说过目前新提出的YOLO系列并没有什么惊人的创新,基本上都是在YOLOv3的基础上进行缝缝补补。所以YOLOv4也是一样,只是对YOLOv3存在的一些不足之处进行了重新的设计,整体思想还是基于YOLOv3,性能提升了不少。在YOLOv4论文中作者做了相当多的实验。下面我们只讲下作者最终所采取了结构,对YOLOv3做了哪些改进。主要分为两个部分:网络结构+优化策略

YOLOv4网络结构:

  • Backbone:SCPDarknet53。
  • 颈部网络:SPP,PAN。
  • Head:仍然采用YOLOv3的设计,多了一些细节的改进。

YOLOv4的优化策略:

  • Eliminate grid sensitiy。
  • Mosaic data augmentation。
  • IoU Threshold。
  • Optimizered Anchors。
  • CIoU。
    二.YOLOv4模型及优化策略
      下面我们分别讲下YOLOv4的网络结构和他的优化策略。
    2.1.YOLOv4网络结构
      观察下面的YOLOv4的网络结构可以发现YOLOv4比YOLOv3多了CSP和PAN结构。YOLOv4使用CSPDarknet53作为backbone,加上SPP模块、PANet作为网络的颈部,Head部分仍采用YOLOv3的结构。
    总结一下YOLOv4的基本组件,总共5个:
  • CBM:YOLOv4的网络结构中最小的组件,由Conv+Bn+Mish激活函数组成(下图绘制了几种常用的激活函数)。
  • CBL:由Conv+Bn+Leaky_relu激活函数组成。
  • Res unit:残差结构,类似Resnet
  • CSPX:由三个卷积层和X个Res unit模块concate组成
  • SPP:采用 1 × 1 , 5 × 5 , 9 × 9 , 13 × 13 1\times1,5\times5,9\times9,13\times13 1×15×59×913×13的最大池化方式,进行多模融合。
  • YOLOv4目标检测算法——通俗易懂的解析_第1张图片

YOLOv4目标检测算法——通俗易懂的解析_第2张图片
  既然YOLOv4的网络结构的backbone改成了CSPDarknet53,下面我们来讲下什么是CSP,CSP结构是在CSPNet里面提出的,那么为什么要用CSP结构呢,他的优点是什么?YOLOv4的作者给出了三个优点:

  • 增强CNN的学习能力
  • 移除计算瓶颈
  • 减少显存开销

  总结一句话就是CSP能够加快网络的推理速度、减少对显存的使用、提升网络的学习能力,所以作者选择了CSP结构。
  我们看下CSPNet的结构,如下图所示CSPDenseNet。对于输入的特征层分成两个部分,一部分经过part1得到一个输出特征层,一部分经过part2在经过一系类的block(论文中使用的是DenseBlock),然后再经过Transition,得到另一个特征层。将得到的两个特征层进行concat通道拼接,然后再通过一个Transition模块。注意:在CSPDeseNet原文输入的特征层是按照通道进行均分的,但是在YOLOv4里面并不是按照通道均分操作。YOLOv4里面是在CPS模块之前先进性下采样,下采样之后将其输出依次通过两个 1 × 1 的卷积层 1\times1的卷积层 1×1的卷积层,他们的输出通道的个数都是输入特征层的通道个数的一半。然后再通过一系列的ResBlock,接着在通过CBM(就是CSP里面的Transition结构)。然后就是通道拼接,最后在通过一个CBM。
YOLOv4目标检测算法——通俗易懂的解析_第3张图片
  backbone部分的改变我们讲完了,然后我们再看下YOLOv4的颈部的设计。下面我们分别讲下SPP和PANet。
SPP:
  SPP的结构如下图所示,对输入的特征层依次通过一个卷积核大小为 5 × 5 , 9 × 9 , 13 × 13 5\times5,9\times9,13\times13 5×59×913×13的最大池化下下采样层,然后将这单个输出的特征层和原始的输入的特征层进行通道拼接。通过SPP结构能够在一定程度上解决多出尺度的问题。具体结构如下图所示。
YOLOv4目标检测算法——通俗易懂的解析_第4张图片

PAN:
  下面我们在讲下PAN结构,PAN来自于PANet(Path Aggregation Network),如下图所示。最左边的蓝色部分就是FPN结构,把FPN的输出特征再从低层向高层进行融合,把 P 2 到 P 5 P_{2}到P_{5} P2P5 N 2 到 N 5 N_{2}到N_{5} N2N5看成一个结构就是PAN结构。实际上就是在原来的FPN结构上又加上了一个从低层到高层的融合。注意:在FPN里面的特征融合是相加,在YOLOv4里面的特征融合采用的是concat通道拼接。
YOLOv4目标检测算法——通俗易懂的解析_第5张图片
  上面我们讲完了CSP、SPP、PAN结构再回过头来看YOLOv4的结构是不是简答多了。网络结构的改进我们讲完了,下面我们来讲下YOLO4的优化策略。

Eliminate grid sensitiy
  首先我们来讲下消除网格敏感程度的问题。我们知道YOLOv3中网络输出的三个特征层,针对每个预测特征层最后都是通过一个 1 × 1 1\times1 1×1的卷积层进行预测的。对于每个特征层,通过 1 × 1 1\times1 1×1的卷积层每滑动到一个grid中就会预测当前的grid的所对应的三个anchor的一系列的输出值(边界框回归参数,置信度,每个类别的条件类别概率)。但是在预测边界框回归参数的时候会有一个问题,观察下面的图以及 b x , b y 的公式 b_{x},b_{y}的公式 bxby的公式,因为sigmoid的值最大只能接近1和0,所以最终的$b_{x},b_{y}的值不可能取到每个gird的边界上面,那么如果ground truth的中心点正好落在了边界上了怎么办呢,这个时候不就出现根本无法拟合ground truth的情况吗,于是YOLOv4的作者又重新设计了这公式,如下所示。
b x = ( σ ( t x ) ⋅  scale  x y −  scale  x y − 1 2 ) + c x b y = ( σ ( t y ) ⋅  scale  x y −  scale  x y − 1 2 ) + c y \begin{aligned} &b_{x}=\left(\sigma\left(t_{x}\right) \cdot \text { scale }_{x y}-\frac{\text { scale }_{x y}-1}{2}\right)+c_{x} \\ &b_{y}=\left(\sigma\left(t_{y}\right) \cdot \text { scale }_{x y}-\frac{\text { scale }_{x y}-1}{2}\right)+c_{y} \end{aligned} bx=(σ(tx) scale xy2 scale xy1)+cxby=(σ(ty) scale xy2 scale xy1)+cy
  目前比较主流的方法是将 s c a l e scale scale设置成2,于是有:
b x = ( 2 ⋅ σ ( t x ) − 0.5 ) + c x b y = ( 2 ⋅ σ ( t y ) − 0.5 ) + c y \begin{aligned} &b_{x}=\left(2 \cdot \sigma\left(t_{x}\right)-0.5\right)+c_{x} \\ &b_{y}=\left(2 \cdot \sigma\left(t_{y}\right)-0.5\right)+c_{y} \end{aligned} bx=(2σ(tx)0.5)+cxby=(2σ(ty)0.5)+cy
  我们看下这两个函数的曲线,黄色的是原始的sigmoid函数曲线,蓝色的是对sigmoid改进版的函数曲线。可以看到通过缩放之后,改进版的sigmoid在相同的 x x x范围之内他可以去到的 y y y的范围更广, y y y的值对 x x x的变化更敏感了。预测值也比较容易到达0和1的值了,即此时即使groun truth的值在边界也是可以预测的。
YOLOv4目标检测算法——通俗易懂的解析_第6张图片
Mosaic:
  下面我们再来讲下YOLOv4的另一个优化策略Masaic数据增强。简单总结一句话就是将四张图像按照一定的规则拼接在一起,得到一张新的图片,通过masaic可以增加样本的多样性。

IoU threshhold
  在讲这个问题之前,我们先回顾下在YOLOv3里面是怎么匹配正样本的?在YOLOv3让每个anchor去和ground truth进行匹配, I o U IoU IoU最大的记为正样本, I o U IoU IoU不是最大,但是大于某一阈值被抛弃, I o U IoU IoU小于某一阈值记为负样本。在计算 I o U IoU IoU的时候是让anchor和ground truth的左上角进行对齐,然后再计算。你有没有发现这样做有一个很严重的缺陷,这样的话正负样本也太不平衡了吧,就一个正样本,那么多负样本。于是在YOLOv4里面作者对其进行了改进,匹配机制仍然是跟上面一样,只不过正样本不再是 I o U IoU IoU最大的那个了,而是用多个grid的anchor去负责一个GT,就是说只要anchor与ground truth的 I o U IoU IoU大于某一阈值就记为正样本,这就相当于你anchor框的数量没变,但是选择的正样本的比例增加了,就缓解了正负样本不均衡的问题。那么在YOLOv4里面作者是怎么做的呢?在YOLOv4里面如果ground truth的中心点落在了某一个grid的左上角,假设该grid产生的anchor2负责预测ground truth。那么该grid的左边一个grid和上面一个grid所对应的anchor2模板都会记为正样本。同理如果ground truth的中心点落在了右上角,那么该grid的右边一个grid和上面一个grid所对应的anchor2模板也记为正样本,同理左下和右下。这里会有个特殊情况,如果ground truth的中心点正好落在了该grid的中心点呢?这个时候只会利用当前的grid所对应的anchor模板。总结一下这个地方YOLOv4的做法,ground truth的中心点落在哪个grid里面,该grid的上,下,左,右四个grid产生的anchor都有机会被记为正样本,左上角,右上角,左下角,右下角的grid不会被使用。这样做就解决了正负样本不平衡的问题。这个地方之所以能用三个grid产生的anchor去拟合ground truth,就是因为作者改进了 b x , b y b_{x},b_{y} bxby的公式。

anchor:
  下面我们再来看下YOLOv4的anchor优化部分。YOLOv4里面的anchor的尺寸从新调整了下,YOLOv5又改回了YOLOv3的尺寸,有点费解,改来改去又改回来了。

CIOU:
  最后再讲下定位损失计算的部分,这里之前看我的另一篇博文就行了: I o U IoU IoU的进化之路
  至此,关于YOLOv4的内容基本上也讲完了,YOLOv5等我的下片文章吧,在此附一个总结:
YOLOv1目标检测算法——通俗易懂的解析
YOLOv2目标检测算法——通俗易懂的解析
YOLOv3目标检测算法——通俗易懂的解析
YOLOv5目标检测算法——通俗易懂的解析
欢迎各位大佬批评指正!

你可能感兴趣的:(目标检测,目标检测,算法,计算机视觉)