​论文名称:YOLOv3: An Incremental Improvement
论文下载地址: https://arxiv.org/abs/1804.02767

如果不想看文章的可以看下我在bilibili上的视频讲解:

  1. YOLO系列理论视频合集
  2. YOLOv3 SPP网络源码讲解(Pytorch版)
  3. YOLOv3 SPP网络代码仓库(Pytorch版)



相信阅读了YOLO v3论文的小伙伴们会发现为什么这次的论文篇幅这么少?除去参考文献就四面?Excuse me?我是下了篇假文献吧。读完后感觉内容确实不多,而且总感觉写的不够细致,很多地方都比较模糊,可能是作者想让大家去观摩他的代码吧。

本人是小白,看后表示有点蒙。于是在Github上搜了大牛们基于Tensorflow搭建的YOLOv3模型进行分析(本人没接触过caffe,所以就不去看caffe的源码了)。接下来我会根据我阅读的代码来进一步分析网络的结构。Github YOLOv3大牛代码链接

1 Darknet-53 模型结构

在论文中虽然有给网络的图,但我还是简单说一下。这个网络主要是由一系列的1x1和3x3的卷积层组成(每个卷积层后都会跟一个BN层和一个LeakyReLU)层,作者说因为网络中有53个convolutional layers,所以叫做Darknet-53(2 + 12 + 1 + 22 + 1 + 82 + 1 + 82 + 1 + 4*2 + 1 = 53 按照顺序数,最后的Connected是全连接层也算卷积层,一共53个)。下图就是Darknet-53的结构图,在右侧标注了一些信息方便理解。(卷积的strides默认为(1,1),padding默认为same,当strides为(2,2)时padding为valid)


看完上图应该就能自己搭建出Darknet-53的网络结构了,上图是以输入图像256 x 256进行预训练来进行介绍的,常用的尺寸是416 x 416,都是32的倍数。下面我们再来分析下YOLOv3的特征提取器,看看究竟是在哪几层Features上做的预测。


2 YOLOv3 模型结构

作者在论文中提到利用三个特征层进行边框的预测,具体在哪三层我感觉作者在论文中表述的并不清楚(例如文中有“添加几个卷积层”这样的表述),同样根据代码我将这部分更加详细的分析展示在下图中。注意:原Darknet53中的尺寸是在图片分类训练集上训练的,所以输入的图像尺寸是256x256,下图是以YOLO v3 416模型进行绘制的,所以输入的尺寸是416x416,预测的三个特征层大小分别是52,26,13。


​在上图中我们能够很清晰的看到三个预测层分别来自的什么地方,以及Concatenate层与哪个层进行拼接。注意Convolutional是指Conv2d+BN+LeakyReLU,和Darknet53图中的一样,而生成预测结果的最后三层都只是Conv2d。通过上图小伙伴们就能更加容易地搭建出YOLOv3的网络框架了。


3 目标边界框的预测

YOLOv3网络在三个特征图中分别通过 ( 4 + 1 + c ) × k (4+1+c) \times k (4+1+c)×k个大小为 1 × 1 1 \times 1 1×1的卷积核进行预测,k为预设边界框(bounding box prior)的个数(在每个预测特征层中k默认取3),c为预测目标的类别数,其中4k个参数负责预测目标边界框的偏移量,k个参数负责预测目标边界框内包含目标的概率,ck个参数负责预测这k个预设边界框对应c个目标类别的概率。下图展示了目标边界框的回归过程。图中虚线矩形框为Anchor模板(这里只用看 ( p w , p h ) (p_w, p_h) (pw,ph)信息),实线矩形框为通过网络预测的偏移量(相对Grid Cell的左上角)计算得到的预测边界框。其中 ( c x , c y ) (c_x, c_y) (cx,cy)为对应Grid Cell的左上角坐标, ( p w , p h ) (p_w, p_h) (pw,ph)为Anchor模板映射在特征层上的宽和高, ( t x , t y , t w , t h ) (t_x, t_y, t_w, t_h) (tx,ty,tw,th)分别为网络预测的边界框中心偏移量 ( t x , t y ) (t_x, t_y) (tx,ty)以及宽高缩放因子 ( t w , t h ) (t_w, t_h) (tw,th) ( b x , b y , b w , b h ) (b_x, b_y, b_w, b_h) (bx,by,bw,bh)为最终预测的目标边界框,从 ( t x , t y , t w , t h ) (t_x, t_y, t_w, t_h) (tx,ty,tw,th)转换到 ( b x , b y , b w , b h ) (b_x, b_y, b_w, b_h) (bx,by,bw,bh)的公式如图右侧所示,其中 σ ( x ) \sigma(x) σ(x)函数是sigmoid函数其目的是将预测偏移量缩放到0到1之间(这样能够将每个Grid Cell中预测的边界框的中心坐标限制在当前cell当中,作者说这样能够加快网络收敛)。


​下图给出了三个预测层的特征图大小以及每个特征图上预设边界框的尺寸(这些预设边界框尺寸都是作者根据COCO数据集聚类得到的):


4 损失函数的计算

关于YOLOv3的损失函数文章中写的很粗略,比如坐标损失采用的是sum of squared error损失,类别损失采用的是二值交叉熵损失,本人在github上也找了很多YOLO v3的公开代码,有的采用的是YOLOv1或者YOLOv2的损失函数,下面给出本人认为正确的损失函数。

YOLOv3的损失函数主要分为三个部分:目标定位偏移量损失 L l o c ( t , g ) L_{loc}(t,g) Lloc(t,g),目标置信度损失 L c o n f ( o , c ) L_{conf}(o,c) Lconf(o,c)以及目标分类损失 L c l a ( O , C ) L_{cla}(O,C) Lcla(O,C) λ 1 , λ 2 , λ 3 \lambda _{1},\lambda _{2},\lambda _{3} λ1,λ2,λ3其中是平衡系数。
L ( O , o , C , c , t , g ) = λ 1 L c o n f ( o , c ) + λ 2 L c l a ( O , C ) + λ 3 L l o c ( t , g ) L(O,o,C,c,t,g)=\lambda_1 L_{conf}(o, c) + \lambda_2 L_{cla}(O, C) + \lambda_3 L_{loc}(t, g) L(O,o,C,c,t,g)=λ1Lconf(o,c)+λ2Lcla(O,C)+λ3Lloc(t,g)

4.1目标置信度损失

目标置信度可以理解为预测目标矩形框内存在目标的概率,目标置信度损失 L c o n f ( o , c ) L_{conf}(o,c) Lconf(o,c)采用的是二值交叉熵损失(Binary Cross Entropy),其中 o i ∈ { 0 , 1 } o_{i}\in \{0,1\} oi{0,1},表示预测目标边界框i中是否真实存在目标,0表示不存在,1表示存在。 c i ^ \hat{c_{i}} ci^表示预测目标矩形框i内是否存在目标的Sigmoid概率(将预测值 c i c_{i} ci通过sigmoid函数得到)。
L c o n f ( o , c ) = − ∑ ( o i l n ( c i ^ ) + ( 1 − o i ) l n ( 1 − c i ^ ) ) c i ^ = S i g m o i d ( c i ) \begin{array}{l} L_{conf}(o, c) = -\sum(o_i ln(\hat{c_i}) + (1-o_i)ln(1-\hat{c_i})) \\ \\ \hat{c_i}=Sigmoid(c_i) \end{array} Lconf(o,c)=(oiln(ci^)+(1oi)ln(1ci^))ci^=Sigmoid(ci)

4.2目标类别损失

目标类别损失 L c l a ( O , C ) L_{cla}(O,C) Lcla(O,C)同样采用的是二值交叉熵损失(采用二值交叉熵损失的原因是,作者认为同一目标可同时归为多类,比如猫可归为猫类以及动物类,这样能够应对更加复杂的场景),注意论文中作者说了只有正样本才有目标类别损失。其中 O i j ∈ { 0 , 1 } O_{ij}\in \{0,1\} Oij{0,1},表示预测目标边界框i中是否真实存在第j类目标,0表示不存在,1表示存在。 C i j ^ \hat{C_{ij}} Cij^表示网络预测目标边界框i内存在第j类目标的Sigmoid概率(将预测值 C i j C_{ij} Cij通过sigmoid函数得到)。
L c l a ( O , C ) = − ∑ i ∈ P o s ∑ j ∈ c l a ( O i j l n ( C i j ^ ) + ( 1 − O i j ) l n ( 1 − C i j ^ ) ) C i j ^ = S i g m o i d ( C i j ) \begin{array}{l} L_{cla}(O,C)=-\sum_{i\in Pos}\sum_{j\in cla}(O_{ij}ln(\hat{C_{ij}}) + (1-O_{ij})ln(1-\hat{C_{ij}})) \\ \\ \hat{C_{ij}}=Sigmoid(C_{ij}) \end{array} Lcla(O,C)=iPosjcla(Oijln(Cij^)+(1Oij)ln(1Cij^))Cij^=Sigmoid(Cij)


4.3目标定位损失

目标定位损失采用的是Sum of Squared Error Loss,注意只有正样本才有目标定位损失。对应原论文中的图:


​​
其中 ( t x , t y ) (t_x, t_y) (tx,ty)是网络预测的关于中心坐标的偏移参数, ( t w , t h ) (t_w, t_h) (tw,th)是网络预测的关于目标宽高的缩放因子, ( c x , c y ) (c_x, c_y) (cx,cy)是对应Grid Cell的左上角坐标, ( p w , p h ) (p_w, p_h) (pw,ph)代表对应Anchor模板的宽度和高度, ( g x , g y , g w , g h ) (g_x, g_y, g_w, g_h) (gx,gy,gw,gh)分别代表GT Boxes中心点的坐标x, y以及宽度和高度(映射在Grid网格中的)。公式中关于中心点偏移的误差计算可能和论文中略有不同:
L l o c ( t , g ) = ∑ i ∈ p o s ( σ ( t x i ) − g x i ^ ) 2 + ( σ ( t y i ) − g y i ^ ) 2 + ( t w i − g w i ^ ) 2 + ( t h i − g h i ^ ) 2 g x i ^ = g x i − c x i g y i ^ = g y i − c y i g w i ^ = l n ( g w i / p w i ) g h i ^ = l n ( g h i / p h i ) \begin{array}{l} L_{loc}(t,g) = \sum_{i \in pos}(\sigma(t_x^i) - \hat{g_x^i})^2 + (\sigma(t_y^i) - \hat{g_y^i})^2 + (t_w^i - \hat{g_w^i})^2 + (t_h^i - \hat{g_h^i})^2 \\ \\ \hat{g_x^i} = g_x^i - c_x^i \\ \\ \hat{g_y^i} = g_y^i - c_y^i \\ \\ \hat{g_w^i} = ln(g_w^i/p_w^i) \\ \\ \hat{g_h^i} = ln(g_h^i / p_h^i) \end{array} Lloc(t,g)=ipos(σ(txi)gxi^)2+(σ(tyi)gyi^)2+(twigwi^)2+(thighi^)2gxi^=gxicxigyi^=gyicyigwi^=ln(gwi/pwi)ghi^=ln(ghi/phi)

先写这么多吧,以后如果有什么需要补充的在补充,有问题还请指出,谢谢!

更多推荐