zoukankan      html  css  js  c++  java
  • YOLO V3

    YOLOV3

    YOLOv3: An Incremental Improvement

    Yolov3网络架构

    backbone:Darknet-53

    img

    backbone部分由Yolov2时期的Darknet-19进化至Darknet-53,加深了网络层数,引入了Resnet中的跨层加和操作。原文列举了Darknet-53与其他网络的对比:

    img

    Darknet-53处理速度每秒78张图,比Darknet-19慢不少,但是比同精度的ResNet快很多。Yolov3依然保持了高性能。

    (这里解释一下Top1和Top5:模型在ImageNet数据集上进行推理,按照置信度排序总共生成5个标签。按照第一个标签预测计算正确率,即为Top1正确率;前五个标签中只要有一个是正确的标签,则视为正确预测,称为Top5正确率)

    Yolov3网络结构全貌

    Yolov3使用Darknet-53作为整个网络的分类骨干部分。在Yolov3论文中并未给出全部网络结构。根据代码,整理数据流图如下:

    img

    网络结构解析:

    1. Yolov3中,只有卷积层通过调节卷积步长控制输出特征图的尺寸。所以对于输入图片尺寸没有特别限制,流程图中,输入图片以(256*256*3)作为样例
    2. Yolov3借鉴了特征金字塔的思想,小尺寸特征图用于检测大尺寸物体,而大尺寸特征图检测小尺寸物体。特征图的输出维度为(N imes N imes [3 imes (4+1+80)])(N imes N)为输出特征图格点数,一共3个Anchor框,每个框有4维预测框数值(t_x,t_y,t_w,t_h),1维预测框置信度,80维物体类别数。所以第一层特征图的输出维度为(8 imes 8 imes 255)
    3. Yolov3总共输出3个特征图,第一个特征图下采样32倍,第二个特征图下采样16倍,第三个下采样8倍。输入图像经过Darknet-53(无全连接层),再经过Yoloblock生成的特征图被当作两用,第一用为经过(3*3)卷积层、(1*1)卷积之后生成特征图一,第二用为经过(1*1)卷积层加上采样层,与Darnet-53网络的中间层输出结果进行拼接,产生特征图二。同样的循环之后产生特征图三。
    4. concat操作与加和操作的区别:加和操作来源于ResNet思想,将输入的特征图,与输出特征图对应维度进行相加,即(y=f(x)+x);而concat操作源于DenseNet网络的设计思路,将特征图按照通道维度直接进行拼接,例如(8*8*16)的特征图与(8*8*16)的特征图拼接后生成(8*8*32)的特征图。
    5. 上采样层(upsample):作用是将小尺寸特征图通过插值等方法,生成大尺寸图像。例如使用最近邻插值算法,将(8*8)的图像变换为(16*16)。上采样层不改变特征图的通道数。

    Yolo的整个网络,吸取了Resnet、Densenet、FPN的精髓,可以说是融合了目标检测当前业界最有效的全部技巧。

    Yolo输出特征图解码(前向过程)

    根据不同的输入尺寸,会得到不同大小的输出特征图,以图二中输入图片(256 imes 256 imes 3)为例,输出的特征图为(8 imes 8 imes 255,16 imes 16 imes 255,32 imes 32 imes255)。在Yolov3的设计中,每个特征图的每个格子中,都配置3个不同的先验框,所以最后三个特征图,这里暂且reshape为(8 imes 8 imes 3 imes 85,16 imes 16 imes 3 imes 85,32 imes 32 imes 3 imes 85),这样更容易理解,在代码中也是reshape成这样之后更容易操作。

    三张特征图就是整个Yolo输出的检测结果,检测框位置(4维)、检测置信度(1维)、类别(80维)都在其中,加起来正好是85维。特征图最后的维度85,代表的就是这些信息,而特征图其他维度(N imes N imes 3)(N imes N)代表了检测框的参考位置信息,3是3个不同尺度的先验框。下面详细描述怎么将检测信息解码出来:

    先验框

    在Yolov1中,网络直接回归检测框的宽、高,这样效果有限。所以在Yolov2中,改为了回归基于先验框的变化值,这样网络的学习难度降低,整体精度提升不小。Yolov3沿用了Yolov2中关于先验框的技巧,并且使用k-means对数据集中的标签框进行聚类,得到类别中心点的9个框,作为先验框。在COCO数据集中(原始图片全部resize为(416 imes 416)),九个框分别是 ((10 imes 13)),((16 imes 30)),((33 imes 23)),((30 imes 61)),((62 imes 45)),((59 imes 119)), ((116 imes 90)), ((156 imes 198)),((373 imes 326)) ,顺序为(w imes h)

    注:先验框只与检测框的(w、h)有关,与(x、y)无关。

    检测框解码

    有了先验框与输出特征图,就可以解码检测框(x,y,w,h)

    [egin{matrix}b_x=sigma(t_x)+c_x\b_y=sigma(t_y)+c_y\b_w=p_we^{t_w}\b_h=p_he^{t_h}end{matrix} ]

    如下图所示,(sigma(t_x),sigma(t_y))是基于矩形框中心点左上角格点坐标的偏移量,(sigma)激活函数,论文中作者使用sigmoid(p_w,p_h)是先验框的宽、高,通过上述公式,计算出实际预测框的宽高((b_w,b_h))

    img

    举个具体的例子,假设对于第二个特征图(16 imes 16 imes 3 imes 85)中的第([5,4,2])维,上图中的(c_y=5,c_x=4),第二个特征图对应的先验框为((30 imes61)),((62 imes45)),((59 imes119)),prior_box的index为2,那么取最后一个59,119作为先验w、先验h。这样计算之后的(b_x,b_y)还需要乘以特征图二的采样率16,得到真实的检测框(x,y)

    检测置信度解码

    物体的检测置信度,在Yolo设计中非常重要,关系到算法的检测正确率与召回率。

    置信度在输出85维中占固定一位,由sigmoid函数解码即可,解码之后数值区间在([0,1])中。

    类别解码

    COCO数据集有80个类别,所以类别数在85维输出中占了80维,每一维独立代表一个类别的置信度。使用sigmoid激活函数替代了Yolov2中的softmax,取消了类别之间的互斥,可以使网络更加灵活。

    三个特征图一共可以解码出$ 8 imes 8 imes 3 + 16 imes 16 imes 3 + 32 imes 32 imes 3 = 4032$个box以及相应的类别、置信度。这4032个box,在训练和推理时,使用方法不一样:

    1. 训练时4032个box全部送入打标签函数,进行后一步的标签以及损失函数的计算。
    2. 推理时,选取一个置信度阈值,过滤掉低阈值box,再经过NMS(非极大值抑制),就可以输出整个网络的预测结果了。

    训练策略与损失函数(反向过程)

    训练策略

    YOLOv3 predicts an objectness score for each bounding box using logistic regression. This should be 1 if the bounding box prior overlaps a ground truth object by more than any other bounding box prior. If the bounding box prior is not the best but does overlap a ground truth object by more than some threshold we ignore the prediction, following [17]. We use the threshold of .5. Unlike [17] our system only assigns one bounding box prior for each ground truth object. If a bounding box prior is not assigned to a ground truth object it incurs no loss for coordinate or class predictions, only objectness.

    以上是Yolov3论文中的训练策略,最后一句“一个没有被分配ground truth的预测框,只产生置信度loss“,有一定的歧义。深刻理解Yolov3之后,训练策略总结如下:

    1. 预测框一共分为三种情况:正例(positive)、负例(negative)、忽略样例(ignore)。

    2. 正例:任取一个ground truth,与4032个框全部计算IOU,IOU最大的预测框,即为正例。并且一个预测框,只能分配给一个ground truth

      例如第一个ground truth已经匹配了一个正例检测框,那么下一个ground truth,就在余下的4031个检测框中,寻找IOU最大的检测框作为正例。ground truth的先后顺序可忽略。

      正例产生置信度loss、检测框loss、类别loss。预测框为对应的ground truth box标签(需要反向编码,使用真实的x、y、w、h计算出(t_x,t_y,t_w,t_h) );类别标签对应类别为1,其余为0;置信度标签为1。

    3. 忽略样例:正例除外,与任意一个ground truth的IOU大于阈值(论文中使用0.5),则为忽略样例。忽略样例不产生任何loss。

    4. 负例:正例除外(与ground truth计算后IOU最大的检测框,但是IOU小于阈值,仍为正例),与全部ground truth的IOU都小于阈值(0.5),则为负例。负例只有置信度产生loss,置信度标签为0。

    Loss function

    特征图1的Yolov3的损失函数抽象表达式如下:

    [egin{matrix}loss_{N_1}=lambda_{box}sum^{N_1 imes N_1}_{i=0}sum^3_{j=0}1^{obj}_{ij}[(t_x-t_x')^2+(t_y-t_y')^2]\+lambda_{box}sum^{N_1 imes N_1}_{i=0}sum^3_{j=0}1^{obj}_{ij}[(t_w-t_w')^2+(t_h-t_h')^2]\-lambda_{obj}sum^{N imes N}_{i=0}sum^3_{j=0}1^{obj}_{ij}log(c_{ij})\-lambda_{noobj}sum^{N_1 imes N_1}_{i=0}sum^3_{j=0}1^{noobj}_{ij}log(1-c_{ij})\-lambda_{class}sum^{N_1 imes N_1}_{i=0}sum^3_{j=0}1^{obj}_{ij}sum_{cin classes}[p'_{ij}(c)log(p_{ij}(c))+(1-p'_{ij}(c))log(1-p_{ij}(c))]end{matrix} ]

    Yolov3 Loss为三个特征图Loss之和:

    [Loss=loss_{N_1}+loss_{N_2}+loss_{N_3} ]

    1. (lambda)为权重常数,控制检测框Loss、obj置信度Loss、noobj置信度Loss之间的比例,通常负例的个数是正例的几十倍以上,可以通过权重超参控制检测效果。
    2. (1^{obj}_{ij})若是正例则输出1,否则为0;(1^{noobj}_{ij})若是负例则输出1,否则为0;忽略样例都输出0。
    3. (x,y,w,h)用MSE作为损失函数,也可以使用(smooth L1 loss)(出自Faster R-CNN)作为损失函数。(smooth L1)可以使训练更加平滑。置信度、类别标签由于是0,1二分类,所以使用交叉熵作为损失函数。

    训练策略解释

    ground truth为什么不按照中心点分配对应的预测box?
    1. 在Yolov3的训练策略中,不再像Yolov1那样,每个cell负责中心落在该cell中的ground truth。原因是Yolov3一共产生3个特征图,3个特征图上的cell,中心是有重合的。训练时,可能最契合的是特征图1的第3个box,但是推理的时候特征图2的第1个box置信度最高。所以Yolov3的训练,不再按照ground truth中心点,严格分配指定cell,而是根据预测值寻找IOU最大的预测框作为正例。

      如果yolov3不以中心点作为分配依据,输出的(x,y),基于格子左上角的偏移量,这个没有问题,但这里的(x、y)是网络的预测值。标签(x',y'),是与该预测框IoU数值最高的那个框。

      解码和ground truth框的分配是两个独立的过程,上述过程只是gt框分配的过程。yolov1中,直接按照每个物体中心所在的格子,将预测与标签一一对应,但是yolov3一共预测三个特征图,所以按照中心点分配gt不再一一对应。

    2. 笔者实验结果:

      1. ground truth先从9个先验框中确定最接近的先验框,这样可以确定ground truth所属第几个feature map以及第几个anchor box位置,之后根据中心点进一步分配
      2. 全部4032个anchor框直接和ground truth计算IOU,取IOU最高的cell分配ground truth

      第二种计算方式的IOU数值,往往都比第一种要高,这样(w,h)(x,y)的loss较小,网络可以更加关注类别和置信度的学习;其次,在推理时,是按照置信度排序,再进行NMS筛选,第二种训练方式,每次给ground truth分配的box都是最契合的box,给这样的box置信度打1的标签,更加合理,最接近的box,在推理时更容易被发现。Yolov1中的置信度标签,就是预测框与真实框的IOU,Yolov3为什么是1?

    3. 置信度意味着该预测框是或者不是一个真实物体,是一个二分类,所以标签是1、0更加合理。

    4. 笔者实验结果:

      1. 置信度标签取预测框与真实框的IOU
      2. 置信度标签取1

      第一种的结果是,在训练时,有些预测框与真实框的IOU极限值就是0.7左右,置信度以0.7作为标签,置信度学习有一些偏差,最后学到的数值是0.5,0.6,那么假设推理时的激活阈值为0.7,这个检测框就被过滤掉了。但是IOU为0.7的预测框,其实已经是比较好的学习样例了。尤其是coco中的小像素物体,几个像素就可能很大程度影响IOU,所以第一种训练方法中,置信度的标签始终很小,无法有效学习,导致检测召回率不高。而检测框趋于收敛,IOU收敛至1,置信度就可以学习到1,这样的设想太过理想化。而使用第二种方法,召回率明显提升了很高。

    为什么有忽略样例?
    1. 忽略样例是Yolov3中的点睛之笔。由于Yolov3使用了多尺度特征图,不同尺度的特征图之间会有重合检测部分。比如有一个真实物体,在训练时被分配到的检测框是特征图1的第三个box,IOU达0.98,此时恰好特征图2的第一个box与该ground truth的IOU达0.95,也检测到了该ground truth,如果此时给其置信度强行打0的标签,网络学习效果会不理想。
    2. 笔者实验结果:如果给全部的忽略样例置信度标签打0,那么最终的loss函数会变成(Loss_{obj})(Loss_{noobj})的拉扯,不管两个loss数值的权重怎么调整,或者网络预测趋向于大多数预测为负例,或者趋向于大多数预测为正例。而加入了忽略样例之后,网络才可以学习区分正负例。

    优化器

    作者在文中没有提及优化器,Adam,SGD等都可以用,github上Yolov3项目中,大多使用Adam优化器。

    精度与性能

    在coco上的精度对比:

    img

    在coco上的性能对比:

    img

    直接说结论:Yolov3精度与SSD相比略有小优,与Faster R-CNN相比略有逊色,几乎持平,比RetinaNet差。但是速度是SSD、RetinaNet、Faster R-CNN至少2倍以上。输入尺寸为(320*320)的Yolov3,单张图片处理仅需22ms,简化后的Yolov3 tiny可以更快。

    本文来自博客园,作者:甫生,转载请注明原文链接:https://www.cnblogs.com/fusheng-rextimmy/p/15448982.html

  • 相关阅读:
    Web开发利器Webstorm导入多个文件夹或者项目
    js react 全选和反选
    nginx的配置文件 【nginx.conf】
    nginx 服务器重启命令,关闭
    Nginx反向代理新篇-使用location对多个URL做反向代理
    Windows下Nginx的安装与配置
    es6 递归 tree
    自定义table样式
    数据库(7)
    数据库(6)
  • 原文地址:https://www.cnblogs.com/fusheng-rextimmy/p/15448982.html
Copyright © 2011-2022 走看看