Yolo系列知识点梳理(Yolov1-v5)

文章目录

  • 1 概述
  • 2 Yolo系列模型
    • 2.1 基石 - Yolov1
      • 2.1.1 Yolov1的网络结构
      • 2.1.2 Yolov1的feature map
      • 2.1.3 Yolov1的训练
      • 2.1.4 Yolov1的预测
      • 2.1.5 Yolov1小结
    • 2.2 Yolo9000 - Yolov2
      • 2.2.1 Better
        • 2.2.1.1 引入了Batch normalization
        • 2.2.1.2 高分辨率的分类器
        • 2.2.1.3 加入了anchor机制
        • 2.2.1.4 loss的改动
        • 2.2.1.5 Fine-Grained Features
        • 2.2.1.6 多尺度训练
      • 2.2.2 Faster
      • 2.2.3 Stronger
    • 2.3 一小步 - Yolov3
    • 2.4 技巧 - Yolov4
      • 2.4.1 网络结构的改进
        • 2.4.1.1 backbone中的激活函数改为Mish
        • 2.4.1.2 backbone中的残差模块改成了CSP
        • 2.4.1.3 detector中的新增了SPP模块
        • 2.4.1.4 detector中特征尺度的变化
      • 2.4.2 损失函数的改进
      • 2.4.3 nms的改进
      • 2.4.4 其他
    • 2.5 又一小步 - Yolov5
      • 2.5.1 网络结构的改进
      • 2.5.1.1 添加了CSP2模块
      • 2.5.2 其他
  • 3 结束语
  • 参考资料

1 概述

Yolo系列的模型是大多数做目标检测的图像算法工程师都在使用的,使用时经常也是先用了看看效果再说,如果效果不错,有时间再回头来研究一下模型,有时甚至就忘了回过头来细究。这篇文章就是一个回头的产物。

Yolo的每一个系列都令人惊艳,本文综合了原始论文和网上各家的一些说法,把Yolo每个系列究竟产出了一些什么做一个系统的梳理,也方便我以后的再回头。

如果Yolo之后有人继续更新下去,本文也会尽量做到继续更新。

文中的图片都出自参考资料,非本人原创。

2 Yolo系列模型

2.1 基石 - Yolov1

Yolov1是目标检测中one-stage方法的开山之作,它不同于two-stage需要先过一个RPN网络得到候选区域的方法,yolo直接在整张图的feature map上进行目标的定位和分类,因此速度也比当时正红的Fast R-CNN快很多。而且,也正是因为yolo看的是全局的信息,yolo把背景误判成目标的错误率比只看proposals的Fast R-CNN低很多。不过整体的准确率,还是Fast R-CNN高。

2.1.1 Yolov1的网络结构

Yolov1的网络结构如下图所示,并不复杂,输入是448×448×3448\times448\times3448×448×3的图片,输出是一个7×7×307\times7\times307×7×30的feature map。网络中共有24个全卷积和尾部的2个全连接,其中用到了大量的1×11\times11×1卷积用来改变通道数,当然也有融合通道之间特征的作用。这里最后用的两层全连接其实今天看来有点不解,后面的版本就没有用了。这个网络结构就是大名鼎鼎的Darknet。
yolov1-net-arch

图1 Yolov1网络结构示意图

网络的卷积层在ImageNet上用分类任务进行了预训练,使得卷积层可以抽到比较好的图像特征,但是预训练时的输入图像为224×224224\times224224×224的,这其实会有点问题,在训练检测模型时,输入为448×448448\times448448×448模型需要去适应这种分辨率的转换,对结果是有影响的,这个在之后的版本会优化。

2.1.2 Yolov1的feature map

我们再来看下Yolov1输出的7×7×307\times7\times307×7×30的feature map,其中7×77\times77×7是经过层层全卷积和全连接之后下采样得到的结果,每个grid对应着原图上相应位置的一块区域,可以理解为将448×448448\times448448×448的输入长宽都等分为了7份,共有49个grids。

每个grid都对应了一个长度为30的向量,准确来说应该是一个2×5+202\times5+202×5+20的向量,其中2表示2个预测框;5表示每个预测框的[xcenter,ycenter,w,h,confidence][x_{center}, y_{center}, w, h, confidence][xcenter,ycenter,w,h,confidence]confidenceconfidenceconfidence指的是这个预测框内目标的置信度Pr(Object)×IOUpredtruthPr(Object) \times IOU_{pred}^{truth}Pr(Object)×IOUpredtruth,当没有物体时,Pr(Object)=0Pr(Object)=0Pr(Object)=0confidence=0confidence=0confidence=0,当有物体时,confidence=IOUpredtruthconfidence=IOU_{pred}^{truth}confidence=IOUpredtruth;20表示20种目标类别的置信度,表示为Pr(Classi∣Object)Pr(Class_i|Object)Pr(ClassiObject)

在预测时,最终某个框内表示了某个目标的置信度为confidence×Pr(Classi∣Object)confidence \times Pr(Class_i|Object)confidence×Pr(ClassiObject)
Yolov1-feature_map

图2 Yolov1的feature map示意图

写一个一目了然版的就是某个grid的30维向量为
[xc1,yc1,w1,h1,confidence1,xc2,yc2,w2,h2,confidence2,cate1,...,cate20][x_{c1}, y_{c1}, w_1, h_1, confidence_1, x_{c2}, y_{c2}, w_2, h_2, confidence_2, cate_1, ..., cate_{20}] [xc1,yc1,w1,h1,confidence1,xc2,yc2,w2,h2,confidence2,cate1,...,cate20]

如果要知道某个grid第一个框表示cate1cate_1cate1这个目标的概率,则为confidence1×cate1confidence_1 \times cate_1confidence1×cate1

仔细一想,会发现每个grid只能表示一个物体,confidenceiconfidence_iconfidencei代表了有没有物体和用哪个预测框,cateicate_icatei表示了这个物体是哪个目标类别。也就是7×77\times77×7的feature map最多只能预测出49个目标,这对小目标和相邻多目标很不友好

2.1.3 Yolov1的训练

训练部分只讲和loss相关的内容,其他的和Yolo本身关系不大,都是标准的pipeline。

训练时,我们的label是每张图片多个检测框坐标和对应的物体类别。每个物体都会落在7×77\times77×7的feature map中的某一个格子里,落到哪个格子里,那么那个格子里就负责预测这个物体。而每个格子又有两个框,就取其中和真实物体的bbox的iou较大的那个预测框作为负责这个物体的预测框。这里负责的意思就是算loss的时候拿负责的框去算loss。

loss共由五个部分组成:
(1)中心定位误差

就是负责这个物体的检测框的中心点坐标和这个物体真实的中心点坐标差多少。

L1=∑i=0S2∑j=0BIijobj((xi−x^i)2+(yi−y^i)2)(2-1)L_1 = \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{I}_{ij}^{obj} ((x_i - \hat{x}_i)^2 + (y_i - \hat{y}_i)^2)\tag{2-1} L1=i=0S2j=0BIijobj((xix^i)2+(yiy^i)2)(2-1)

其中,S2S^2S2表示7×77\times77×7的feature map的格子的集合;BBB表示每个格子中bbox的集合;Iijobj\mathbb{I}_{ij}^{obj}Iijobj是一个指示函数,表示第iii个格子的第jjj个框负责预测真实物体时进行后面的计算,否则为0;xix_ixiyiy_iyi是ground truth的中心点坐标;x^i\hat{x}_ix^iy^i\hat{y}_iy^i是负责这个物体的预测框的中心坐标。

(2)宽高误差

就是负责这个物体的检测框的宽高和这个物体真实的宽高差多少。

L2=∑i=0S2∑j=0BIijobj((wi−w^i)2+(hi−h^i)2)(2-2)L_2 = \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{I}_{ij}^{obj} ((\sqrt{w_i} - \sqrt{\hat{w}_i})^2 + (\sqrt{h_i} - \sqrt{\hat{h}_i})^2)\tag{2-2} L2=i=0S2j=0BIijobj((wiw^i)2+(hih^i)2)(2-2)

其中,wiw_iwihih_ihi是ground truth的宽高;w^i\hat{w}_iw^ih^i\hat{h}_ih^i是负责这个物体的预测框的宽高。其他符号和L1L_1L1中相同。

(3)正样本confidence误差

保证负责物体的预测框的confidence接近1。

L3=∑i=0S2∑j=0BIijobj(Ci−C^i)2(2-3)L_3 = \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{I}_{ij}^{obj} (C_i - \hat{C}_i)^2\tag{2-3} L3=i=0S2j=0BIijobj(CiC^i)2(2-3)

其中,CiC_iCi表示这个格子内有物体中心的标签,C^i\hat{C}_iC^i表示这个格子内有物体中心的置信度。

(4)负样本confidence误差

保证不负责物体的预测框的confidence接近0。

L4=∑i=0S2∑j=0BIijnoobj(Ci−C^i)2(2-4)L_4 = \sum_{i=0}^{S^2} \sum_{j=0}^{B} \mathbb{I}_{ij}^{noobj} (C_i - \hat{C}_i)^2\tag{2-4} L4=i=0S2j=0BIijnoobj(CiC^i)2(2-4)

其中,Iijnoobj\mathbb{I}_{ij}^{noobj}Iijnoobj是一个指示函数,表示第iii个格子的第jjj个框负责预测真实物体时进行后面的计算,否则为0。

(5)类别误差

表示负责预测的格子内的类别误差。

L5=∑i=0S2Iiobj∑c∈classes(pi(c)−p^i(c))2(2-5)L_5 = \sum_{i=0}^{S^2} \mathbb{I}_{i}^{obj} \sum_{c \in classes}(p_i(c) - \hat{p}_i(c))^2\tag{2-5} L5=i=0S2Iiobjcclasses(pi(c)p^i(c))2(2-5)

其中,Iiobj\mathbb{I}_{i}^{obj}Iiobj是一个指示函数,表示第iii个格子的负责预测真实物体时进行后面的计算,否则为0;pi(c)p_i(c)pi(c)表示第iii个格子第ccc个类别的标签;p^i(c)\hat{p}_i(c)p^i(c)表示第iii个格子第ccc个类别的置信度。

综合,(2−1)−(2−5)(2-1)-(2-5)(21)(25)就有

L=λcoordL1+λcoordL2+L3+λnoobjL4+L5(2-6)L = \lambda_{coord}L_1 + \lambda_{coord}L_2 + L_3 + \lambda_{noobj}L_4 + L_5 \tag{2-6} L=λcoordL1+λcoordL2+L3+λnoobjL4+L5(2-6)

其中,λcoord\lambda_{coord}λcoordλnoobj\lambda_{noobj}λnoobj是可以用来调整的超参数,也就是各个loss的权重。不难看出Yolov1把目标检测看成了一个回归问题。

2.1.4 Yolov1的预测

预测部分没啥说的,就是对得到的98个预测框进行一个阈值的筛选之后,再做nms。

2.1.5 Yolov1小结

优点:
(1)速度快
(2)考虑图片的全局特征,precision较高

缺点:
(1)每个格子只能预测一个物体,对密集型的物体检测不友好
(2)下采样次数多,最终所使用的特征比较粗糙

2.2 Yolo9000 - Yolov2

Yolov2在Yolov1的基础上有很大的改动,这一节就针对改进部分依次说明。

2.2.1 Better

2.2.1.1 引入了Batch normalization

BN是一个非常有用的模块,其有点如下:

  • 加快收敛
  • 改善梯度,远离饱和区
  • 允许大的学习率
  • 对初始化不敏感
  • 相当于正则化,使得有BN层的输入都有相近的分布

有了BN之后,就可以不用dropout了,或者说不能像原来一样用dropout了,这会导致训练和测试的方差偏移,可以参看文献[5]。

2.2.1.2 高分辨率的分类器

Yolov1当中对backbone做预训练的时候,用的是224×224224\times224224×224的输入,而yolov1为了高分辨率用的是448×448448\times448448×448的输入,这样就导致了模型要去适应这个分辨率的转换。于是,Yolov2干脆直接用448×448448\times448448×448的输入预训练backbone了。这样带来了几乎4%mAP的提升。这种简单而高效且不用增加预测负担的方法是我们最喜欢的。

2.2.1.3 加入了anchor机制

在Yolov1中没有anchor的概念,所以7×77\times77×7的feature map中预测的两个预测框都是野蛮生长的,这两个预测框很有可能就长的差不多,而且这样去学习不同形状的物体,对模型来说是比较困难的。

所以,Yolov2删去了最后的全连接层,引入了anchor机制。Yolov2的输入变成了416×416416 \times 416416×416,feature map大小为13×1313\times1313×13,每个格子有5个anchors,每个anchor的长宽大小和比例不同,各司其职,负责不同形状的物体。有了anchor之后,模型就不需要直接去预测物体框的长宽了,只需要预测偏移量就可以了,这相对来说降低了难度。

这里提一句,之所以从448×448448 \times 448448×448变成416×416416 \times 416416×416就是为的使得feature map的size是一个奇数。这样的好处是,许多图片的中心点都是某个物体的中心,奇数保证中间是一个格子,而不是偶数那样四个格子抢占中心点。

anchor

图3 Yolov2的anchor形状示意图

不过引入anchor也有不好的地方,本来不用anchor的时候,预测出来只有98个框,现在有845个框了,从最终结果来看,precision略有下降了,不过recall变高了许多。

anchor

图4 Yolov2的anchor输出示意图

Yolov1的输出是一个7×7×307 \times 7 \times 307×7×30的,Yolov2的输出是一个13×13×12513 \times 13 \times 12513×13×125,其中125=(5+20)×5125 = (5 + 20) \times 5125=(5+20)×5。括号里的555表示xi,yi,wi,hi,confix_i,y_i,w_i,h_i,conf_ixi,yi,wi,hi,confi,202020表示每个类别的概率,共20个类别,最后的555表示555个预测框。图4表示的非常清楚了。

可以看出,同一个格子里的每个预测框的类别是可以不同的,一个格子可以预测5个物体了。

anchor cluster

图5 Yolov2的anchor聚类示意图

那么这5个anchor的预锚框是怎么确定的呢?甚至为什么是5个呢?根据论文中所述,anchor的形状是在VOC 2007和COCO数据集上聚类得到的,聚类的类别个数从1到15都试过,最终在效果和性能的权衡之下选择了5个类聚出来的锚框形状,示意图如上图5所示。

anchor

图6 Yolov2的anchor编码示意图

说了半天,模型究竟是怎么计算offset的呢?如上图6所示,yolov2的anchor编码在二阶段的检测模型的基础上做了改进。图6中cxc_xcxcyc_ycy是每个格子的左上角坐标,txt_xtxtyt_yty是模型预测锚框中心点坐标时的输出参数,加了σ\sigmaσ就把中心点的偏移量限定在了这个格子里,这样不管模型怎么预测,中心点都飞不出这个格子。pwp_wpwphp_hph是预锚框的初始宽高,twt_wtwtht_hth是模型预测锚框宽高的输出参数,这里就没有限制最终锚框的形状。bxb_xbxbyb_ybybwb_wbwbhb_hbh是最终的预测框的中心点坐标和宽高。我把图中的公式抄一份下来就是(2−7)(2-7)(27)

bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=pheth(2-7)\begin{aligned} b_x &= \sigma (t_x) + c_x \\ b_y &= \sigma (t_y) + c_y \\ b_w &= p_w e^{t_w} \\ b_h &= p_h e^{t_h} \\ \end{aligned} \tag{2-7} bxbybwbh=σ(tx)+cx=σ(ty)+cy=pwetw=pheth(2-7)

除此之外,还有一个东西叫做tot_ototot_oto是用来给出有物体的置信度的。

Pr(object)IOU(b,object)=σ(to)(2-8)P_r(object)IOU(b, object) = \sigma(t_o) \tag{2-8} Pr(object)IOU(b,object)=σ(to)(2-8)

2.2.1.4 loss的改动

Yolov2的loss我直接拿子豪兄做的图了,这个也是网友们根据源码整理出来的,论文中并没有说这件事。
yolov2 loss

图7 Yolov2的loss示意图

前面的三个求和就是指的下面的所有操作都是对每个格子每个预测框分别做的;IMaxIOU<Thresh\mathbb{I}_{MaxIOU<Thresh}IMaxIOU<Thresh表示845个框分别和所有的ground truth求IOU,如果最大的IOU也小于阈值Thresh的话,就认为这个框是背景,其输出的置信度bijkob_{ijk}^obijko要越小越好;It<12800\mathbb{I}_{t<12800}It<12800表示前12800次迭代,也就是模型训练的早期时候,这里让模型的预测锚框接近预锚框,有点先重置一下的意思,不让初始的锚框太横七竖八;Iktruth\mathbb{I}_k^{truth}Iktruth表示对负责预测ground truth的锚框进行的loss计算。所有的Loss也都是回归运算。

2.2.1.5 Fine-Grained Features

增加了细粒度的特征,方法就是把浅层的26×26×51226 \times 26 \times 51226×26×512这层的输出分成四份之后concat到原来的特征上。26×26×51226 \times 26 \times 51226×26×512分成四份并concat就变成了13×13×204813 \times 13 \times 204813×13×2048,这个和13×13×102413 \times 13 \times 102413×13×1024的特征concat到一起变成了13×13×307213 \times 13 \times 307213×13×3072
passthrough

图8 Yolov2的pass through示意图

四分的方式有点空洞卷积的意思,如下图9所示。
pass through

图9 Yolov2的pass through切分方式示意图

2.2.1.6 多尺度训练

Yolov2每10个batches就会换一下输入的尺度,使得模型泛化于不同尺度的输入,这得益于adaptive pooling层。高分辨率的输入速度慢,但是对小目标的检测效果要好很多,低分辨率的输入速度快。
多尺度训练

图10 Yolov2的多尺度训练示意图

2.2.2 Faster

这部分没啥说的,就是把backbone给换成了Darknet-19,都是卷积层和pooling层,更加轻量了。

2.2.3 Stronger

这部分是作者对超多分类的一次尝试,但估计效果没有那么好,只是一个设想。

用来训练检测模型的数据集coco有80个类别,10万的图片,但用来分类的数据集imagenet有22k个类别,140万的数据。作者想要把imagenet的数据和类别拿来用,于是就相处了层级分类这个办法,如下图11所示。
wordnet

图11 Yolov2的层级分类示意图

imagenet中的每个类别并不是完全两两互斥的,它们之间是有层级关系的,所以作者借助wordnet把类别进行了分层,同一层的类别分别进行softmax,这样就做到了多层级的分类。检测模型的类别都是包含在这些类别之中的,再将其应用到检测模型即可。

这只是一个设想,了解一下即可。

2.3 一小步 - Yolov3

Yolov3相对于Yolov2没有太多大的改进,用作者的话说就是"I managed to make some improvements to YOLO. But, honestly, nothing like super interesting, just a bunch of small changes that make it better."

作者对backbone的网络结构进行了改进,将Darknet19结合Resnet,变成了Darknet53。作者把残差块轻量化了一下,如下图12所示。
resnet

图12 Yolov3的残差块轻量化示意图

除此之外,还增加了多尺度训练机制,增加了多尺度训练的网络结构示意图如下图13所示。输出三个尺寸的feature map,分别是13×1313 \times 1313×1326×2626 \times 2626×2652×5252 \times 5252×52。大尺寸的feature map是小尺寸的feature map上采样并结合浅层特征得到的。
netword structure

图13 Yolov3的网络结构示意图

每个尺寸的feature map各司其职,13×1313 \times 1313×13负责大目标物体,26×2626 \times 2626×26负责中目标物体和52×5252 \times 5252×52负责小目标物体。原因很简单,越深层的信息越抽象,越浅层的越粗糙,浅层还保留着小物体的信息,深层就不一定还在了。

从图13中可以看到feautre map的输出channel变成了256,这个是因为Yolov3的anchor变成了9个,每个尺度的feature map有3个,然后类别变成了80类,所以每个尺度的feature map有256=3×(4+1+80)256=3 \times (4+1+80)256=3×(4+1+80)
在这里插入图片描述

图14 Yolov3的多尺度示意图

Yolov3就这些重要的改进。

2.4 技巧 - Yolov4

Yolov4可以说是目标检测各种小技巧的大总结,它将技巧分为了bag of freebies(BoF)和bag of specials(BoS)两种,BoF指的是只增加训练的成本而不增加推理的成本的技巧,通常是前后处理;BoS指的是只增加一点推理成本却可以显著提高模型效果的技巧,通常是结构上的变化。

不同的BoF和BoS面对不同的问题和数据集有不同的效果,根据需求选择即可。

BoF和BoS都有一大堆,要在这里全讲完太费时间,也与这篇文章的目的相悖。这里只讲一些重要的,且最终的Yolov4用上的技巧。下图15是Yolov4真正用到的一些改进。
yolov4 improvement

图15 Yolov5的技巧选择示意图

这里不会把上面的所有改进都讲了,只挑一些重要的讲。

2.4.1 网络结构的改进

2.4.1.1 backbone中的激活函数改为Mish

Yolov3中的卷积快都是CBL的结构,Yolov4改成了CBM,也就是把激活函数给改成了Mish,其示意图如下图16所示。
cbl2cbm

图16 CBL变为CBM示意图

Leaky Relu激活函数是(aaa是很小的常数)

f(x)={ax,ifx<0x,otherwise(2-9)f(x) = \begin{cases} ax, &if \ x<0 \\ x, &otherwise \end{cases} \tag{2-9} f(x)={ax,x,if x<0otherwise(2-9)

Mish激活函数就是

f(x)=x⋅tanh(log(1+ex))(2-10)f(x) = x \cdot tanh(log(1+e^x)) \tag{2-10} f(x)=xtanh(log(1+ex))(2-10)

这里顺便来说说常用的激活函数的优缺点。

sigmoid两端很容易饱和,会造成梯度消失的问题,中间梯度很大,会造成梯度爆炸问题。用sigmoid做激活函数,神经网络不太好训练。但是sigmoid的非线性表达能力很强,因为它不管怎么高阶求导仍旧是非线性的。

tanh和sigmoid很像,不过它是以0为中心。

relu的问题是,它的负半轴没梯度了,正半轴求个导是常数,非线性表达能力很弱。但是它快。所以用relu的网络一般网络层数很深,以此来弥补relu非线性能力表达弱的缺陷。

leaky relu负半轴做了优化,但还是非线性表达能力弱。

mish结合了relu和tanh的优点。它无上限,这样可以保证没有饱和区域,不会梯度消失。有下限,能够保证具有一定的正则能力。同时非线性表达能力也不错。

2.4.1.2 backbone中的残差模块改成了CSP

Yolov3中的残差模块如下图17所示,resX中的X表示的是有X个Res unit。
resX

图17 Yolov3残差模块示意图

Yolov4则是将残差模块替换为了CSP模块,如下图18所示,其中的CSPX中的X表示有X个Res unit。
cspx

图18 Yolov4残差模块示意图

可以看出CSPX效仿残差块,额外加了一路,并且这一路中多了一个CBM,最后的add也变成了concat。相当于一堆残差的外面再残差了一遍。这里加个CBM直观上是为了改变特征的shape,使其可以顺利concat。除此之外,资料[8]中的猜想是,这是为了平衡上下两路的信息,相当于加了个电阻。每个这个电阻,就是个短路的状态,信息都从下面走了,有了这个电阻,就可以尽可能平衡上下路的信息。这只是个猜想。

2.4.1.3 detector中的新增了SPP模块

SPP的作用是增大感受野。它很简单,就是一堆MaxPooling,每个MaxPooling的kernel size大小不同,就有不同感受野的结果,最后再全都concat起来即可,其示意图如下图19所示。
SPP

图19 Yolov4的SPP示意图

SPP之所以不放在backbone是因为这会造成大量的信息丢失,而放在detector里却起到了降维的作用。

2.4.1.4 detector中特征尺度的变化

Yolov4还读detector中的尺度特征做了很大的修改,如下图20和图21分别是yolov3和yolov4的网络结构图。
yolov3 structure

图20 Yolov3网络结构图

yolov4 structure

图21 Yolov4网络结构图

不难看出Yolov3是19×1919 \times 1919×19 -> 38×3838 \times 3838×38 -> 76×7676 \times 7676×76的,而Yolov4是反过来的,这主要是为了增加特征融合性,也就是feature map中融合了更多层的信息。特别是19×1919 \times 1919×19这个feature map,融合的特征最多了,也就是对大目标的检测效果更好了。应该说不管大小目标,总体都有提升。

2.4.2 损失函数的改进

(1)变为smoth_L1
之前Yolo的损失函数当中有大量的L2损失,在Yolov4中改成了smooth L1。smooth L1结合了L1和L2损失的优点。先来看下L1和L2损失的公式

L1=1n∑i=1n∣f(xi−yi)∣L2=1n∑i=1n(f(xi)−yi)2(2-11)L1 = \frac{1}{n} \sum_{i=1}^{n} |f(x_i - y_i)| \\ L2 = \frac{1}{n} \sum_{i=1}^{n} (f(x_i) - y_i)^2 \tag{2-11} L1=n1i=1nf(xiyi)L2=n1i=1n(f(xi)yi)2(2-11)

L1的优点是倒数很稳定,但是是一个阶段函数,在(0,0)(0,0)(0,0)处是一个折线。L2的优点是在(0,0)(0,0)(0,0)处是可导的,但是离(0,0)(0,0)(0,0)越远,导数越大,会产生爆炸。所以就有了结合L1和L2的smooth L1出现

smoothL1={0.5x2if∣x∣<1∣x∣−0.5otherwise(2-12)smooth\ L1 = \begin{cases} 0.5x^2 & if\ |x| < 1 \\ |x| - 0.5 & otherwise \end{cases}\tag{2-12} smooth L1={0.5x2x0.5if x<1otherwise(2-12)

(2)iou loss改进
这里主要参考了文献[10]

在Yolov3中的IOU loss就直接是(1−IOU)2(1-IOU)^2(1IOU)2。这里的iou就是交集比上并集,如下图22所示。

iou

图22 iou示意图

这里的IOU的计算方法优点缺点,且看下图23。缺点一就是左图所示,当预测框与真实框完全没有交叠时,不管预测框离真实框多远,IOU都是一样的,但其实离真实框近的比离真实框远的要好一些。缺点二就是中图和右图所示,当交集和并集一致时,不同方向的预测框得到的iou是一样的,但其实右图比中图要好一点,因为中图的中心点对齐需要预测框的水平和垂直都发生比较大的变化,而右图只需要水平平移即可。
iou缺点

图23 IOU缺点

为了解决上述的两个缺点,有了GIOU,如图24所示。
giou

图24 GIOU示意图

GIOU的公式为

GIOU=IOU−差集/最小外接矩形(2-13)GIOU = IOU - 差集/最小外接矩形 \tag{2-13} GIOU=IOU/(2-13)

最小外接矩形和差集的意思就是图24中的左图和中图,不难看初,刚才提到的两个缺点在这里已经解决了。不过还有一个问题,如图25所示。
Giou缺点

图25 GIOU缺点

当预测框在真实框内部的时候,不管预测框在那个位置,GIOU都是一样的,但是图25的中图显然是优于左图和右图的,因为中图的水平和垂直方向的坐标已经对齐了,只需要改变长宽即可。

这个时候,就又出现了一种DIOU,如图26所示。
diou

图26 DIOU示意图

DIOU的公式为

DIOU=IOU−(Distance_2)/(Distance_C)(2-14)DIOU = IOU - (Distance\_2) / (Distance\_C) \tag{2-14} DIOU=IOU(Distance_2)/(Distance_C)(2-14)

其中,Distance_CDistance\_CDistance_C是最小外接矩形的对角线距离,Distance_2Distance\_2Distance_2是预测框和真实框中心点的欧氏距离。

这样一来就解决了图25的缺点。但是,别急,还有一个缺点。DIOU没有考虑长宽比。
diou缺点

图27 DIOU缺点

图27中当预测中心点距离真实中心点一样时,预测框的长宽比与真实框接近的,显然是更优的。于是,就有了终极版的CIOU

CIOU的公式为

CIOU=IOU−Distance_22Distance_C2−v21−IOU+v(2-15)CIOU = IOU - \frac{Distance\_2^2}{Distance\_C^2} - \frac{v^2}{1 - IOU + v} \tag{2-15} CIOU=IOUDistance_C2Distance_221IOU+vv2(2-15)

其中,vvv是长宽比的一致性参数,定义为

v=4π(arctanwgthgt−arctanwpredhpred)2(2-16)v = \frac{4}{\pi}(arctan\frac{w_{gt}}{h_{gt}} - arctan\frac{w_{pred}}{h_{pred}})^2 \tag{2-16} v=π4(arctanhgtwgtarctanhpredwpred)2(2-16)

至此,iou经历了这么多版本,最终确定为CIOU。

2.4.3 nms的改进

在训练的时候用的是CIOU,但是在做nms的时候,用了diou-nms。用diou-nms可以把一些重叠度很高的框,但表示不同物体的给保留下来。至于为什么不用CIOU,我觉得是没有必要,且会增加计算复杂度。我不太同意文献[10]中说的CIOU在做nms时没有真实框,vvv没法计算的说法,两个框做对比,把置信度高的当成真实框即可。

2.4.4 其他

其他比较重要的可能就是cutout,mosaic之类的数据增强的方法了,这个这里就不细讲了。

2.5 又一小步 - Yolov5

Yolov5和Yolov4差不多可以说没有做太多的改进,不过工程上更友好了一些,使用起来也更加方便。

2.5.1 网络结构的改进

2.5.1.1 添加了CSP2模块

下图28时Yolov5的网络结构图,和Yolov4几乎时一摸一样,做了一点点改进。

(1)把CBM换回了CBL,可能是为了提升速度。
(2)设计了CSP2模块,如图28的左下角所示,就是把之前CSP中的残差块改成了CBL。
(3)添加了Focus模块。这个其实就是Yolov2中的pass through。
yolov5网络结构

图28 Yolov5网络结构图

2.5.2 其他

还有就是一些零零碎碎的东西,这里简单列几个比较有用的吧。

(1)添加了训练前自动计算最佳预锚框的模块。
(2)自适应图片缩放,就是padding的时候,去掉一些没用的黑边。

3 结束语

这里根据网上各家的资料总结了很多,其中也有一些自己的理解,对我自身了解Yolo有很大的帮助,也希望给看到这篇博客的人有一些帮助。

参考资料

[1] You Only Look Once: Unified, Real-Time Object Detection
[2] 【子豪兄】YOLOV1目标检测,看我就够了
[3] YOLO9000: Better, Faster, Stronger
[4] 【精读AI论文】YOLO V2目标检测算法
[5] Understanding the Disharmony between Dropout and Batch Normalization by Variance Shift
[6] YOLOv3: An Incremental Improvement
[7] YOLO系列算法之YOLOv3算法精讲
[8] 2021最新人工智能深度学习YOLOv4与YOLOv5教程
[9] YOLOv4: Optimal Speed and Accuracy of Object Detection
[10] 深入浅出Yolo系列之Yolov3&Yolov4&Yolov5&Yolox核心基础知识完整讲解
[11] 深入浅出Yolo系列之Yolov5核心基础知识完整讲解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二十二、PHP框架Laravel学习笔记——集合的使用

一&#xff0e;创建集合 什么是集合&#xff1f;即&#xff1a;它是一种更具读取性和处理能力的数组封装&#xff1b;比如&#xff0c;我们从数据库得到的数据列表&#xff0c;它就是一种集合&#xff1b;数据集合&#xff0c;提供了大量的方法方便我们进行各种操作&#xff1…

二十三、PHP框架Laravel学习笔记——集合的常用方法

一&#xff0e;常用方法 all()方法&#xff0c;转换为属性形式输出&#xff0c;使用 dd 方法看类型&#xff1b; $collection collect([1, 2, 2, 3, 4, 4, 4]); dd($collection->all()); PS&#xff1a;$collection->dd()方法可以以 dd()模式输出&#xff0c;还有 du…

mac看图软件哪个好用_细数Mac上那些好用且免费的软件(三)

许多朋友购买了Mac电脑之后发现很多软件都没有&#xff0c;而且苹果商店好多软件都是收费的。那有没有免费的软件也能满足日常的需求呢&#xff1f;macw小编就为大家推荐一些免费且超级好用的软件&#xff0c;赶快来看看有没有你需要的吧&#xff01;细数Mac上那些好用且免费的…

图像表格实线和虚线检测

文章目录1 背景简述2 camelot中的方法2.1 二值化2.2 腐蚀膨胀2.3 轮廓检测2.4 结果展示3 基于霍夫直线检测的方法3.1 霍夫直线检测原理3.2 概率霍夫直线检测3.3 霍夫直线应用参考资料1 背景简述 图像中的表格结构化是一个比较热门的话题&#xff0c;其输入是一张图片&#xff…

二十四、PHP框架Laravel学习笔记——模型的数据集合

一&#xff0e;数据集合 数据集合&#xff0c;就是已经将模型方法 get()获取到的数据再进行处理&#xff1b;比如&#xff1a;map()方法&#xff0c;通过它可以实现类似访问器一样对字段进行处理的效果&#xff1b; $users User::get(); //使用集合方法 map 可以对输出的字…

论文阅读 - AUTOVC: Zero-Shot Voice Style Transfer with Only Autoencoder Loss

文章目录1 概述2 模型架构3 模块解析3.1 获取梅尔频谱3.2 speaker encoder3.3 AutoVC3.4 Vocoder4 关键部分参考资料1 概述 voice conversion这个任务的目标是输入两个音频&#xff0c;其输入是两段音频&#xff0c;一段音频称为content_audio&#xff0c;另一段称为speaker_a…

二十五、PHP框架Laravel学习笔记——模型的一对一关联

一&#xff0e;关联概念 关联模型&#xff0c;即&#xff1a;两张或以上的表进行一定规则的绑定关联&#xff1b;比如&#xff1a;一个学生(学生表)对应一张个人信息卡(信息表)&#xff0c;这种就是一对一&#xff1b;再比如&#xff1a;一篇博文(帖子表)对应多个评论(评论表)…

小工具:基于颜色的视频和图片切割

文章目录1 前言2 方案简述3 效果1 前言 最近做一个短视频相关的项目的时候&#xff0c;发现输入的视频有很多是有黑边的&#xff0c;有些可能是白边或者其他颜色的边。这对下游的模型处理有很大的影响。于是就写了一个自动判断填充边的颜色&#xff0c;并根据该颜色自动切割视…

二十六、PHP框架Laravel学习笔记——模型的一对多关联

二&#xff0e;一对多关联 一对多关联&#xff0c;本质上使用方法和一对一关联类似&#xff0c;内部实现略有不同&#xff1b; 创建另一个模型&#xff1a;book.php&#xff0c;我们看下这个表数据&#xff1b; PS&#xff1a;这里 user_id19 有三个&#xff0c;也就是蜡笔小…

论文阅读 - An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale

文章目录1 概述2 方法简述2.1 encoder之前2.2 encoder之后3 实验结果参考资料1 概述 这篇论文是一篇将tranformer引入到图像领域的里程碑式的文章。因为这是第一次在处理图像时&#xff0c;将所有的卷积模块统统抛弃&#xff0c;只使用attention。并且实验证明了只用attention…

python五子棋人机对战_Python:游戏:五子棋之人机对战

原标题&#xff1a;Python&#xff1a;游戏&#xff1a;五子棋之人机对战 开端 画棋盘 首先肯定是要画出棋盘来&#xff0c;用 pygame 画出一个 19 19 或 15 15 的棋盘并不是什么难事&#xff0c;这在之前的文章中已经多次用到&#xff0c;就不赘述了。 画棋子 需要说一下的是…

二十七、PHP框架Laravel学习笔记——模型的多对多关联

二&#xff0e;多对多关联 多对多关联&#xff0c;比前面两种要复杂一些&#xff0c;需要一张中间表&#xff0c;共三张&#xff1b; (1) .users&#xff1a;用户表&#xff1b; (2) .roles&#xff1a;权限表&#xff1b; (3) .role_user&#xff1a;中间表&#xff1a;默…

论文阅读 - Is Space-Time Attention All You Need for Video Understanding?

文章目录1 概述2 模型结构2.1 模型输入2.2 attention模块2.3 分类模块3 模型分析3.1 不同attention方式3.2 不同的输入3.3 不同的模型3.4 不同的预训练数据3.5 不同的数据量3.6 position embedding的影响3.7 长输入时长3.8 不同的transformer3.9 不同的patch size3.10 attentio…

iOS中常见的6种传值方式,UIPageViewController

通过属性传值、方法传值、代理传值、Block传值、单例传值、通知传值6种方式进行不同视图之间的传值。不同方式只需要在AppDelegate中更改下UINavigationController的根控制器即可。使用很简单的实例让你很快理解不同的传值方式。 UIPageViewController(上传者&#xff1a;JoneJ…

websocket 获取ip_Spark+Kafka+WebSocket+eCharts实时分析-完全记录(1)

本系列内容&#xff1a;Kafka环境搭建与测试Python生产者/消费者测试Spark接收Kafka消息处理&#xff0c;然后回传到KafkaFlask引入消费者WebSocket实时显示版本&#xff1a;spark-2.4.3-bin-hadoop2.7.tgzkafka_2.11-2.1.0.tgz------------------------第1小节&#xff1a;Kaf…

二十八、PHP框架Laravel学习笔记——模型的关联查询

二&#xff0e;关联查询 前几篇博文&#xff0c;了解了三种基础的关联模型&#xff0c;并简单的进行查询&#xff1b;本节课&#xff0c;我们详细的了解更多的查询方案&#xff1b; //下面两种查询是一样的&#xff1b; $books User::find(19)->book; $books User::fin…

搞懂CRF

文章目录1 前言2 Log-linear model3 MEMM3.1 模型概述3.2 label bias问题4 CRF4.1 模型概述4.2 模型训练4.3 模型解码4.4 小结参考资料1 前言 条件随机场(conditional random field, CRF)是在建立序列模型时的常用模块&#xff0c;它的本质就是描述观测到的序列xˉ\bar{x}xˉ对…

skywalking 安装_SkyWalking全链路追踪利器

随着目前系统架构的复杂度越来越高(中台、微服务)&#xff0c;并且线上应用的多级监控覆盖到了通讯、应用处理过程监控并且实现端到端的应用监测&#xff0c;线上性能故障的快速定位修复&#xff1b;而传统的监控分析方式已经无法满足我们的需求&#xff0c;因此许多强大的APM工…

二十九、PHP框架Laravel学习笔记——Debugbar 调试器

二&#xff0e;安装使用 通过 composer 在项目中安装 Debugbar&#xff0c;命令如下&#xff1a; composer require barryvdh/laravel-debugbar 生成一个配置文件&#xff0c;给用户配置&#xff0c;可以根据需求进行配置&#xff1b; php artisan vendor:publish --provider…

论文阅读 - Video Swin Transformer

文章目录1 概述2 模型介绍2.1 整体架构2.1.1 backbone2.1.2 head2.2 模块详述2.2.1 Patch Partition2.2.2 3D Patch Merging2.2.3 W-MSA2.2.4 SW-MSA2.2.5 Relative Position Bias3 模型效果参考资料1 概述 Vision Transformer是transformer应用到图像领域的一个里程碑&#x…