精华内容
下载资源
问答
  • yolov2
    千次阅读
    2021-12-20 21:58:22

    YOLO v2

    Yolov2论文链接:YOLO9000: Better, Faster, Stronger

    yolov2的改进

    从Yolov2论文的标题可以直观看到就是Better、Faster、Stronger。Yolov1发表之后,计算机视觉领域出现了很多trick,例如批归一化、多尺度训练等等,v2也尝试借鉴了R-CNN体系中的anchor box,所有的改进提升,下面逐一介绍。

    1. Batch Normalization(批归一化)*

    检测系列的网络结构中,BN逐渐变成了标配。在Yolo的每个卷积层中加入BN之后,mAP提升了2%,并且去除了Dropout。

    2. Dimension Clusters(Anchor Box的宽高由聚类产生)

    这里是yolov2的一个创新点。在v2中,Anchor Box的宽高不经过人为手动获取,而是将训练数据集中的矩形框全部拿出来,用k-means聚类的方式学习得到先验框的宽和高,目的使得大框小框的损失同等衡量。例如使用5个Anchor Box,那么k-means聚类的类别中心个数设置为5。

    聚类必须要定义聚类点( 矩形框(w, h) )之间的距离函数,使用(1-IOU)数值作为两个矩形框的的距离函数,如下函数所示:
    d ( b o x , c e n t r o i d ) = 1 − I O U ( b o x , c e n t r o i d ) d(box, centroid) = 1 - IOU(box, centroid) d(box,centroid)=1IOU(box,centroid)
    聚类的结果发现,聚类中心的目标框和以前手动选取的不大一样,更多的是较高、较窄的目标框。聚类结果也有了更好的性能。

    3. Box Regression(框回归)

    YOLOv2对框回归过程进行了改进,过去的框回归过程,由于对 t x t_{x} tx t y t_{y} ty参数没有约束,使得回归后的目标框可以位移到任意位置,这也导致YOLO的框回归中存在不稳定性。改进的做法为引入sigmid函数,对预测的 x x x y y y进行约束。

    YOLOv2在框回归时,为每一个目标框预测5个参数: t x t_{x} tx, t y t_{y} ty, t w t_{w} tw, t h t_{h} th, t o t_{o} to,调整的计算公式为:
    请添加图片描述

    • c x c_{x} cx, c y c_{y} cy为格子的左上角坐标(行列值), p w p_{w} pw, p h p_{h} ph为anchor原始的宽度。
    • t x = 0 t_{x}=0 tx=0时, σ ( t x ) = 0.5 \sigma(t_x)=0.5 σ(tx)=0.5 b x b_{x} bx刚刚好位于格子中间。
    • t w t_{w} tw, t h t_{h} th用来控制宽高的缩放, t o t_{o} to用来表达置信度信息。

    通过使用sigmod函数,将偏移量的范围限制到0到1之间,使得预测框的中心坐标总位于格子内部,减少了模型的不稳定性。

    另外,YOLOv2的分类置信度不再共享,每个anchor单独预测。即每一个anchor得到C+5 的预测值。

    4. Fine-Grained Features(细粒度特征)

    在26 * 26的特征图,经过卷积层等,变为13 * 13的特征图后,作者认为损失了很多细粒度的特征,如图所示,导致小尺寸物体的识别效果不佳,所以在此加入了passthrough层

    passthrough层在预测时使用,将网络中间层的特征图输出(具体见下图),将降采样时同一位置的像素分解成4个子图,concat合并起来。变换后通道数变为4倍,降采样2倍。如从512×26×26变为2048×13×13,在这一次操作中不损失细粒度特征。

    passthrough层的使用,融合了较高分辨率下的特征信息。
    请添加图片描述

    5. Multi-Scale Training(多尺寸训练)

    Yolov2的网络结构中只有卷积层与池化层,为了增加网络的鲁棒性,YOLOv2在训练过程中可以动态调整网络的输入大小,同时相应地调整网络的结构以满足输入。整个网络的降采样倍数为32,只要输入的特征图尺寸为32的倍数即可(如果网络中有全连接层,就不是这样了)。所以Yolo v2可以使用不同尺寸的输入图片训练。

    作者使用的训练方法是,在每10个batch之后,就将图片resize成{320, 352, …, 608}中的一种。不同的输入,最后产生的格点数不同,比如输入图片是320 * 320,那么输出格点是10 * 10,如果每个格点的先验框个数设置为5,那么共输出500个预测结果;如果输入图片大小是608 * 608,输出格点就是19 * 19,共输出1805个预测结果。

    网络结构

    YOLOv2中使用了一种新的基础网络结构,基于Googlenet,名为Darknet-19。拥有19个卷积层和5个Max Pooling层,网络中使用了Batch Normalization来加快收敛。
    v2中移除了v1最后的两层全连接层,全连接层计算量大,耗时久。v2主要是各种trick引入后的效果验证,建议不必纠结于v2的网络结构。

    训练过程

    主要的训练过程为:

    (1)先使用ImageNet数据集对Darknet-19进行分类训练,输入图片大小为224×224,包含标准的数据扩充方式。
    (2)将输入图片大小调整为448×448,进行fine-tune。
    (3)去掉分类的输出层,添加上文提到的目标检测输出层,进行目标检查的训练。

    YOLOv2在上述训练的基础上,又进行了一个联合训练,额外使用只包含标签信息的数据集来进行分类训练,扩大网络可以预测的物体种类数,使其变得更加强大,即YOLO9000。

    使用教程

    源码地址(pytorch版本):https://github.com/longcw/yolo2-pytorch
    (注意,该项目不再维护,并且可能和yolo4后的项目不兼容)

    注 1: 这仍然是一个实验项目。VOC07 ​​测试 mAP 约为 0.71(在 VOC07+12 trainval 上训练)。

    注意 2: 建议使用torch.utils.data.Dataset编写自己的数据加载器, 因为multiprocessing.Pool.imap即使没有足够的内存空间也不会停止。

    Installation and demo

    1. Clone仓库
    2. 下载训练模型的权重文件 yolo-voc.weights.h5 (link updated) 并且在demo.py中设置其路径。
    3. 运行demo.py.

    Training YOLOv2

    可以在任意数据集上训练yolov2,这边,将以VOC2007/2012数据集为示例。
    1. 下载训练、验证、测试数据和 VOCdevkit并解压

    wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar
    wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
    wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCdevkit_08-Jun-2007.tar
    tar xvf VOCtrainval_06-Nov-2007.tar
    tar xvf VOCtest_06-Nov-2007.tar
    tar xvf VOCdevkit_08-Jun-2007.tar
    

    2. 数据集结构目录按如下组织

    $VOCdevkit/                           # development kit
    $VOCdevkit/VOCcode/                   # VOC utility code
    $VOCdevkit/VOC2007                    # image sets, annotations, etc.
    # ... and several other directories ...
    

    3. 下载预训练模型
    下载预训练模型darknet19,然后在yolo2-pytorch/cfgs/exps/darknet19_exp1.py.中设置路径。

    4. 可视化训练过程
    要使用 TensorBoard,需要在 yolo2-pytorch/cfgs/config.py 中设置 use_tensorboard = True 并安装 TensorboardX。 Tensorboard 日志将保存在训练/运行中。

    5. 运行训练代码:python train.py.

    Evaluation

    在yolo2-pytorch/cfgs/config.py中设置把训练好的模型的路径。

    然后运行预测代码。

    Training on your own dataset

    如果需要在自己的数据集上训练,前向传递要求向网络提供乳腺癌 4 个参数:

    • im_data - 图像数据。
      • 这应该是 C x H x W 格式,其中 C 对应于图像的颜色通道,H 和 W 分别是高度和宽度。颜色通道应为 RGB 格式。
      • 使用 utils/im_transform.py 中提供的 imcv2_recolor 函数来预处理图像。 此外,请确保图像已调整为 416 x 416 像素
    • gt_boxes - numpy 数组的列表,其中每个数组的大小为 N x 4,其中 N 是图像中的特征数。 每行中的四个值应对应于 x_bottom_left、y_bottom_left、x_top_right 和 y_top_right。
    • gt_classes - numpy 数组的列表,其中每个数组包含一个整数值,对应于 gt_boxes 中提供的每个边界框的类
    • dontcare - 列表的列表
    更多相关内容
  • yolov2-tiny.cfg

    2020-04-29 11:12:59
    在运行目标检测典型算法yolov2时,有不同的神经网络可供选择,该文件是tiny版本,文件提供了神经网络中不同类型的层的配置参数包括batch_size, width,height,channel,momentum,decay,learning_rate等。
  • yolov2预训练权重darknet19.weights,可以不通过外网下载,直接在百度网盘提取下载即可
  • yolov2-tiny.weights

    2020-03-29 14:02:34
    yolov2-tiny 权重,可直接使用, ./darknet cfg/yolov2-tiny.cfg yolov2-tiny.weights data/dog.jpg
  • yolov2.weights.zip

    2019-11-10 15:16:05
    yolov2.weights,官方下载速度很慢很慢,5个积分良心价,省却烦恼,加油哦,么么哒,哼哼,what?
  • yolov2-by-tf2:使用tensorflow2实现的yolov2算法(只看一次)
  • 权重文件_yolov2.zip

    2021-04-05 16:48:51
    yolov2官方权重文件
  • yolo,yolov2和yolov3的论文原文,属于单阶段目标检测的代表性作品,对检测速度有很大提升,可以细细读一读
  • YOLOV2网络模型

    千次阅读 2022-02-23 10:14:30
    yolov2网络模型

    目录

    资料

    网络模型原理

    网络框架

    相对于yoloV1的改进 

    Batch Norm

     High Resolution Classifier

    Convolutional With Anchor Boxes

    Dimension Clusters

    New Network:Darknet-19 

    Direct location prediction

    PassThrough  

    Multi-Scale Training 

    Loss 

    YOLOV2的训练 

    YOLO9000 

    讨论 

    Reference 


    资料

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

    pytorch代码:GitHub - longcw/yolo2-pytorch: YOLOv2 in PyTorch 

    网络模型原理

    网络框架

    上图是仅分类的模型,模型通过1x1的卷积进行通道降维,3x3的卷积进行特征提取,采用Maxpool进行下采样,特征图尺寸长宽各减半。Darknet-19最终采用global avgpooling做预测。

    上图是yolov2的网络结构,前18层卷积结构和分类模型的前18层一样,第13个卷积层生成的特征图的尺寸为28x28x512,在这个卷积层接上paththrough结构。passthrough层与ResNet网络的shortcut类似,以前面更高分辨率的特征图为输入,然后将其连接到后面的低分辨率特征图上。前面的特征图维度是后面的特征图的2倍,passthrough层抽取前面层的每个2x2的局部区域,然后将其转化为channel维度,对于26x26x512的特征图,使用1x1的卷积降维到26x26x64(这部分论文中没有提到,但实际的代码是这样写的),经passthrough层处理之后就变成13x13x256的新特征图(特征图大小降低4倍,而channles增加4倍),这样就可以与后面的13x13x1024特征图连接在一起形成13x13x1280大小的特征图,网络最后使用了1x1的卷积将13x13x1280的特征降维到13x13x125,13x13x(5*(5+20))对应了13x13个grid cell,每个grid cell里面有5个anchor信息,每个anchor信息包含中心坐标x、y,框的长宽h、w,置信度c,以及对应的20个分类的概率。

    相对于yoloV1的改进 

     BN:YoloV2相较于YoloV1添加了BN层;Hi-res classifier:预训练模型使用了更大的分辨率的图像从224x224上升到448x448;convolutional+anchor boxes:移除了全连接层采用了卷积和anchor boxes来预测边界框;new network:采用了一个新的特征提取器Darknet19;dimension priors:采用k-means聚类方法对训练集中的边界做了聚类分析;location prediction:使用sigmoid函数处理偏移值,使预测的偏移值在(0,1)的范围内,约束在当前的cell内;passthrough:采用类似resnet中shortcut的连接特征的方式,使得相对低层的特征与高层特征相连,是特征更加丰富;multi-scale:由于yoloV2没有了全连接层,可以进行多尺度训练增加模型的鲁棒性;hi-res detector:采用高分辨率(544x544)的图片作为输入;

    Batch Norm

    引入BN层mAP从63.4提升到65.8,上图是BatchNorm的伪代码,算法的步骤:

    1.求出批数据的均值;

    2.求出批数据的方差;

    3.对输入数据进行归一化;

    4.引入缩放和平移变量得到最终结果。

    深度神经网络主要就是为了学习训练数据的分布,并在测试集上达到很好的泛化效果,但是,如果我们每一个batch输入的数据都具有不同的分布,显然会给网络的训练带来困难。另一方面,对于神经网络的各层输出,由于它们经过了层内操作作用,其分布显然与各层对应的输入信号分布不同,而且差异会随着网络深度增大而增大,此现象称为Internal Covariate Shift。为了减小Internal Covariate Shift,可以对神经网络的每一层做归一化,假设将每一层输出后的数据都归一化到0均值,1方差,满足正太分布,但是,此时有一个问题,每一层的数据分布都是标准正太分布,导致其完全学习不到输入数据的特征,因为,费劲心思学习到的特征分布被归一化了,因此,直接对每一层做归一化显然是不合理的。BatchNorm引入了两个参数,缩放变量\gamma和平移变量\beta,先讨论比较差的情况,缩放变量和平移变量分别为标准差和均值,那么y_{i}的结果就是最初的输入x,当BatchNorm起作用的时候,就保证了每一次数据经过归一化后还保留的有学习来的特征,同时又能完成归一化这个操作,加速训练。

    添加BatchNorm的优点:

    1.没有它之前,需要小心的调整学习率和权重初始化,但是有了BN可以放心的使用大学习率,但是使用了BN,就不用小心的调参了,较大的学习率极大的提高了学习速度;

    2.Batchnorm本身上也是一种正则的方式,可以代替其他正则方式如dropout等;

    3.batchnorm降低了数据之间的绝对差异,有一个去相关的性质,更多的考虑相对差异性,因此在分类任务上具有更好的效果。

     High Resolution Classifier

    ImageNet分类模型基本采用大小为224x224的图片作为输入,分辨率相对低一些,不利于检测模型。所以YOLOv1在采用224x224分类模型预训练后,将分辨率增加至448x448,并使用这个高分辨率在检测数据集上finetune。但是直接切换分辨率,检测模型可能难以快速适应高分辨率。所以YOLOv2增加了在ImageNet数据集上使用448x448输入来finetune分类网络这一中间过程(10 epochs),这可以使得模型在检测数据集上finetune之前已经适用高分辨率输入。使用高分辨率分类器后,YOLOv2的mAP从65.8到69.5。

    Convolutional With Anchor Boxes

    原来的YOLO是利用全连接层直接预测bounding box的坐标,而YOLOv2借鉴了Faster R-CNN的思想,引入anchor。首先将原网络的全连接层和最后一个pooling层去掉,使得最后的卷积层可以有更高分辨率的特征。在检测模型中,YOLOv2不是采用448x448的图片作为输入,而是采用416x416大小的图片。因为YOLOv2模型下采样的总步长为32 ,对于416x416大小的图片,最终得到的特征图大小为13x13,维度是奇数,这样特征图恰好只有一个中心位置。对于一些大物体,它们中心点往往落入图片中心位置,此时使用特征图的一个中心点去预测这些物体的边界框相对容易些(因为大的object一般会占据图像的中心,所以希望用一个center cell去预测,而不是4个center cell去预测),所以在YOLOv2设计中要保证最终的特征图有奇数个位置。


    原来的YOLOV1算法将输入图像分成7x7的网格,每个网格预测两个bounding box,因此一共只有98个box,但是在YOLOv2通过引入anchor boxes,预测的box数量超过了1千(以输出feature map大小为13*13为例,每个grid cell有9个anchor box的话,一共就是13*13*9=1521个,当然由后面第4点可知,最终每个grid cell选择5个anchor box)。顺便提一下在Faster RCNN在输入大小为1000*600时的boxes数量大概是6000,在SSD300中boxes数量是8732。显然增加box数量是为了提高object的定位准确率。作者的实验证明:虽然加入anchor使得MAP值下降了一点(69.5降到69.2),但是提高了recall(81%提高到88%),降低的是precision。

    Dimension Clusters

    在Faster R-CNN和SSD中,先验框的维度(长和宽)都是手动设定的,带有一定的主观性。如果选取的先验框维度比较合适,那么模型更容易学习,从而做出更好的预测。因此,YOLOv2采用k-means聚类方法对训练集中的边界框做了聚类分析。因为设置先验框的主要目的是为了使得预测框与ground truth的IOU更好,到聚类中心的距离越小越好,但IOU值是越大越好,所以使用 1 - IOU,这样就保证距离越小,IOU值越大,所以聚类分析时选用box与聚类中心box之间的IOU值作为距离指标: 

     d(box, centroid) = 1 - IOU(box, centroid)

    下图为在VOC和COCO数据集上的聚类分析结果,随着聚类中心数目的增加,平均IOU值(各个边界框与聚类中心的IOU的平均值)是增加的,但是综合考虑模型复杂度和召回率,作者最终选取5个聚类中心作为先验框,其相对于图片的大小如右边图所示。

    边界框聚类步骤:

    New Network:Darknet-19 

    模型结构在网络框架部分介绍过,在ImageNet分类数据集上,Darknet-19的top-1准确度为72.9%,top-5准确度为91.2%,但是模型参数相对小一些。使用Darknet-19之后,YOLOv2的mAP值没有显著提升,但是计算量却可以减少约33%。

    Direct location prediction

    YOLOv2借鉴RPN网络使用anchor boxes来预测边界框相对先验框的offsets。边界框的实际中心位置(x,y),需要根据预测的坐标偏移值(d_{x}^{'},d_{y}^{'}),先验框的尺寸(w_{a},h_{a})以及中心坐标(x_{a},y_{a}) 来计算:

    x = x_{a} + (d_{x}^{'} \times w_{a})

    y = y_{a} + (d_{y}^{'} \times h_{a})

    但是上面的公式是无约束的,预测的边界框很容易向任何方向偏移,因此每个位置预测的边界框可以落在图片任何位置,这导致模型的不稳定性,在训练时需要很长时间来预测出正确的offsets。所以,YOLOv2弃用了这种预测方式,而是沿用YOLOv1的方法,就是预测边界框中心点相对于对应cell左上角位置的相对偏移值,为了将边界框中心点约束在当前cell中,使用sigmoid函数处理偏移值,这样预测的偏移值在(0,1)范围内(每个cell的尺度看做1)。总结来看,根据边界框预测的4个offsetst_{x},t_{y}t_{w}t_{h}可以按如下公式计算出边界框实际位置和大小: 

    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}}

    其中(c_{x},c_{y})为cell的左上角坐标,如下图所示,在计算时每个cell的尺度为1,所以下图中绿色点的坐标点为(1,1)。由于sigmoid函数的处理,边界框的中心位置会约束在当前cell内部,防止偏移过多。由于sigmoid函数的处理,边界框的中心位置会约束在当前cell内部,防止偏移过多。其中e^{t_{w}}e^{t_{h}}没有过多约束,因为物体的大小是不受限制的,所以框的大小也没有约束。而p_{w}p_{h}是先验框的宽度与长度,前面说过它们的值也是相对于特征图大小的,在特征图中每个cell的长和宽均为1。这里记特征图的大小为(W,H),(在文中是(13,13)),这样我们可以将边界框相对于整张图片的位置和大小计算出来(4个值均在0和1之间):

    如果再将上面的4个值分别乘以图片的宽度和长度(像素点值)就可以得到边界框的最终位置和大小了。这就是YOLOv2边界框的整个解码过程。约束了边界框的位置预测值使得模型更容易稳定训练,结合聚类分析得到先验框与这种预测方法,YOLOv2的mAP值从69.6提升到74.4 。

    PassThrough  

    在前面的网络框架部分写了一部分passthrough的内容,下图是passthrough的整理操作流程。

     这里再写一下如何将26x26的特征图变换到13x13的。举个例子,如下图所示,原特征图是4x4x3的一个3维矩阵,采用交叉取数的方法,将相同的数单独形成一个2x2的三维矩阵,最终会有4个这样的矩阵,也就是前面所说的特征图长宽减半,深度增加4倍。这样就和更深的特征图保持相同的尺寸,可以进行融合,增加特征的丰富性。

    Multi-Scale Training 

    由于YOLOv2模型中只有卷积层和池化层,所以YOLOv2的输入可以不限于416x416大小的图片。为了增强模型的鲁棒性,YOLOv2采用了多尺度输入训练策略,具体来说就是在训练过程中每间隔一定的iterations之后改变模型的输入图片大小。由于YOLOv2的下采样总步长为32,输入图片大小选择一系列为32倍数的值:{320, 352, ...,608},输入图片最小为320x320,此时对应的特征图大小为10x10(不是奇数了,确实有点尴尬),而输入图片最大为608x608,对应的特征图大小为19x19。在训练过程,每隔10个iterations随机选择一种输入图片大小,然后只需要修改对最后检测层的处理就可以重新训练。

    采用Multi-Scale Training策略,YOLOv2可以适应不同大小的图片,并且预测出很好的结果。在测试时,YOLOv2可以采用不同大小的图片作为输入,在VOC 2007数据集上的效果如下图所示。可以看到采用较小分辨率时,YOLOv2的mAP值略低,但是速度更快,而采用高分辨输入时,mAP值更高,但是速度略有下降,对于544x544,mAP高达78.6%。注意,这只是测试时输入图片大小不同,而实际上用的是同一个模型(采用Multi-Scale Training训练)。 

    Loss 

    上式子中b_{ijk}^{o}是预测的置信度,b_{ijk}^{r}是预测的位置信息,其中r\in (x,y,w,h)b_{ijk}^{c}是预测的框所属类别。prior_{k}^{r}是anchor的位置,因为每个cell中的五个anchor都是一样的,所以下角标只需要知道anchor属于这五个anchor的哪一个信息。truth^{r}是标注框的位置信息。truth^{c}是标注框的类别信息。IOU_{truth}^{k}是anchor与标注框的IOU。

    loss由三部分组成,其中标黄的部分非0即1。

    第一部分标黄部分,表示预测框与标注框的IOU如果小于阈值0.6这部分的值为1,反之为0,后面的\lambda _{noobj} * (-b_{ijk}^{o})^{2}部分表示该预测框不负责预测物体,所以置信度越小越好;

    第二部分标黄部分,表示是否前12800次迭代,后面的\lambda _{prior} * \sum _{r\in (x,y,w,h)}(prior_{k}^{r} - b_{ijk}^{r})^{2}表示anchor与预测框位置误差,可以使模型能够更快学会预测anchor位置,使得t^{x},t^{y},t^{w},t^{h}更稳定;

    第三部分标黄部分,表示预测框是否负责预测物体,该anchor与标注框的IOU最大对应的预测框负责预测物体(IOU>0.6但非最大的预测框忽略不计),其中\lambda_{coord} * \sum _{r\in (x,y,w,h)}(truth^{r} - b_{ijk}^{r})^{2}表示预测框与标注框的定位误差,\lambda _{obj} * (IOU_{truth}^{k} - b_{ijk}^{o})^{2}表示预测框的置信度与标注框和anchor的IOU的误差,\lambda _{class} * \sum_{c=1}^{C}(truth^{c} - b_{ijk}^{c})^{2}表示预测框的所属分类结果与标注框的分类信息的误差。其中各个\lambda都表示该项的权重,是已经定义好的超参数。

    YOLOV2的训练 

    YOLOV2训练分为三个阶段:

    第一阶段:第一阶段就是先在ImageNet分类数据集上预训练Darknet-19,此时模型输入为224x224,共训练160个epochs。

    第二阶段:将网络的输入调整为448x448,继续在ImageNet数据集上finetune分类模型,训练10个epochs,此时分类模型的top-1准确度为76.5%,而top-5准确度为93.3%。

    第三阶段:修改Darknet-19分类模型为检测模型,并在检测数据集上继续finetune网络。网络修改包括:移除最后一个卷积层、global avgpooling层以及softmax层,并且新增了三个3x3x1024卷积层,同时增加了一个passthrough层,最后使用1x1卷积层输出预测结果,输出的channels数为:num_anchors x (5 + num_classes),和训练采用的数据集有关系。

    由于anchors数为5,对于VOC数据集输出的channels数就是125,而对于COCO数据集则为425。这里以VOC数据集为例,最终的预测矩阵为T(shape为(batch_size, 13, 13, 125)),可以reshape到(batch_size, 13, 13, 5, 25),其中T[:, :, :, :,0:4]为预测框的位置和大小,T[:, :, :, :,5]为预测框的置信度,T[:, :, :, :,5:]为类别预测值。

    YOLO9000 

    YOLO9000是在YOLOv2的基础上提出的一种可以检测超过9000个类别的模型,其主要贡献点在于提出了一种分类和检测的联合训练策略。众多周知,检测数据集的标注要比分类数据集打标签繁琐的多,所以ImageNet分类数据集比VOC等检测数据集高出几个数量级。在YOLO中,边界框的预测其实并不依赖于物体的标签,所以YOLO可以实现在分类和检测数据集上的联合训练。对于检测数据集,可以用来学习预测物体的边界框、置信度以及为物体分类,而对于分类数据集可以仅用来学习分类,但是其可以大大扩充模型所能检测的物体种类。

    作者选择在COCO和ImageNet数据集上进行联合训练,但是遇到的第一问题是两者的类别并不是完全互斥的,比如"Norfolk terrier"明显属于"dog",所以作者提出了一种层级分类方法(Hierarchical classification),主要思路是根据各个类别之间的从属关系(根据WordNet)建立一种树结构WordTree,结合COCO和ImageNet建立的WordTree如下图所示:

    WordTree中的根节点为"physical object",每个节点的子节点都属于同一子类,可以对它们进行softmax处理。在给出某个类别的预测概率时,需要找到其所在的位置,遍历这个path,然后计算path上各个节点的概率之积。

    在训练时,如果是检测样本,按照YOLOv2的loss计算误差,而对于分类样本,只计算分类误差。在预测时,YOLOv2给出的置信度就是Pr(physical object),同时会给出边界框位置以及一个树状概率图。在这个概率图中找到概率最高的路径,当达到某一个阈值时停止,就用当前节点表示预测的类别。通过联合训练策略,YOLO9000可以快速检测出超过9000个类别的物体,总体mAP值为19.7%。

    讨论 

    欢迎大家加群讨论

    Reference 

    目标检测|YOLOv2原理与实现(附YOLOv3) - 知乎

    深度学习中 Batch Normalization为什么效果好? - 知乎

    YOLOv2、v3使用K-means聚类计算anchor boxes的具体方法_fu18946764506的博客-CSDN博客_yolov2 聚类

    【精读AI论文】YOLO V2目标检测算法_哔哩哔哩_bilibili

    展开全文
  • YOLOv2 cpu版dll文件

    2018-04-05 08:38:08
    使用说明参看https://blog.csdn.net/qq_17550379/article/details/78504790
  • YOLOV2函数调用图

    2018-09-20 15:07:28
    使用工具生成的yolov2进行预测时的函数调用关系图。如果需要相关工具,可以私信。
  • YOLOv1、YOLOv2和YOLOv3对比

    千次阅读 2020-06-06 10:04:22
    YOLOv1、YOLOv2和YOLOv3对比R-CNN系列YOLOv1结构目标输出网络训练YOLOv1的局限性和R-CNN系列的对比YOLOv2结构目标输出网络训练关于YOLO9000YOLOv3结构目标输出网络训练YOLOv3系统做过的不成功的尝试未来 YOLO深度...

    YOLO深度卷积神经网络已经经过原作者Joseph Redmon已经经过了3代4个经典版本(含YOLOv2和YOLO9000),俄罗斯的AlexeyAB已经完成了第4版迭代,并获得了Joseph官方认可。本文主要对前3个经典版本进行分析。
    YOLOv1是2015年提出,其基本原理和创新点可参考Ross Girshick的论文《You Only Look Once: Unified, Real-Time Object Detection》(https://arxiv.org/abs/1506.02640)。

    R-CNN系列

    YOLOv1在设计之初主要是和Fast R-CNN进行比较,主要是YOLO系列模型是在R-CNN系列模型基础上解决其存在缺点问题提出的。
    先简单介绍一下R-CNN系列,R-CNN(Region with CNN feature)顾名思义就是区域卷积神经网络特征提取方法,强调区域和卷积,当然信号检测的最终实现还离不开分类和边界回归。
    先说区域R(Region),就是把一幅图先切分为S×S个网格,将小的区域网格使用SS算法(Selective search)不断的合并,然后提取特征每个小的网格的特征。SS算法不进行详细介绍,参考下图进行直观理解。

    在这里插入图片描述
    再说卷积(CNN),不同的卷积核在犹如一个个窗口,在图片上滑动,求相关性,为便于理解,姑且认为是求出的“相关度”。将不同的“相关度”反复归纳合并,最后计算出一个整体相关度。数字识别的卷积核大概只需要5、6个就可以,因为数字无非就是一些曲线、直线、交叉线的组合,第一层计算这些特征,第二层计算这些特征的组合等等。复杂的图像如人、动物等具有更多的特征,所以需要的卷积核就会比较多,特征的组合就比较多,最终网络深度也会比较深。
    再说区域+卷积,就是将候选区图像标准化,使用卷积对区域特征进行判断,最后再通过更深层次的卷积层合并特征,获得最终结果。
    最后再说分类与边框回归,分类+边框回归合起来完成目标检测,就是不但知道检测的结果是什么,还知道位置和尺寸大小,这样就可以得到我们经常看到的结果输出图像:先画个小框框,再打个标签,有木有觉得马上就高大上了,哈哈!分类呢,简单来说就类似于数字识别,把不同的图分成不同的数字结果,再根据排序找到相应的标签,这个会在以后详细介绍。边框回归通常就是预测出(x,y,w,h),这个方法很多,本文也不详细介绍,先挖个坑,以后再补。
    以上描述的这个过程可以参考论文中的示意图,进行直观的理解。
    在这里插入图片描述
    以上就是R-CNN的大体思路,可以说,合并选取的办法是符合科学的思考规律的,区域来源于“感受野”的概念,不同的感受野对应不同的区域。但是R-CNN就是因为这个感受野处理,首先需要消耗大量计算机资源进行候选区提取;其次图像归一化虽然人眼神经处理的很溜,计算机处理起来就会因为尺寸归一化问题导致计算量大大增加,同时因为分辨率的问题效果未必好;另外大量重叠的区域也会导致CNN过程重复计算。
    那Fast R-CNN有什么好处呢?当然是“快”啦。和R-CNN最大的区别在于对于候选区的处理。
    先来看R-CNN。尺度不同的候选区作为后续卷积网络的输入,为了与之兼容,如后续卷积网络采用 Alexnet(输入227×227), R-CNN 采用了非常暴力的手段,那就是无视候选区域的大小和形状,统一变换到 227×227的尺寸,然后进行分类,边框回归。注意哦,候选区确定的时候,其定位(x,y)已经最终确定了。那Fast R-CNN怎么处理呢?它使用了ROI Pooling层,哈哈,当然不是往RIO鸡尾酒池子放水啦。ROI是region of interest,它是根据我们感兴趣的区域将候选区图片非均匀的切分成固定的大小,每个元素的计算方法通过池化的方式,方法很简单,计算量大大减小。
    Faster R-CNN速度更快,是在Fast R-CNN基础上,将选取候选区的SS算法改为RPN(region proposal net),RPN是一个全卷积神经网络。具体结构可以参考下图,这里不进行更加详细的讨论,希望了解可以参考相关文章。

    在这里插入图片描述
    可以看出,R-CNN系列模型的结构就是在进行分类之前,就确定了候选区,然后再使用卷积神经网络完成最终分类和边框回归。需要特别说明的是,R-CNN系列模型通过softmax进行分类,Faster R-CNN在RPN网络中也使用了softmax进行候选框的分类,这样就使得整个模型进行了两次检测。第一次检测判断是不是能够对应上目标类的某一类,第二次检测是判断具体是哪个类型。

    YOLOv1

    了解了R-CNN系列方法,我们再看看YOLO系列方法。最大的区别就是不再提前确定候选区,也就是没有了R-CNN中的“R”,通过深度卷积神经网络进行处理,所有的结果都在YOLO层一次检测成型,这就是You Only Look Once的精髓吧?哈哈,虽然这个说法是强调一个字“快”但是我还是觉得他的意思在于前面不生成候选区,也不分类,所有工作都在最后成形,眼睛“感受野”中的内容直接一次检测成型。废话不多说,我们接着往下看。

    结构

    YOLOv1和R-CNN一样,开始也是先把图像分割成S×S个网格,只不过这个切分没有R-CNN那么密集,毕竟不需要提前合并候选框不是?YOLOv1结构如下图:

    在这里插入图片描述
    论文上说,前面的卷基层提取特征,后面的全连接层用于计算输出概率和坐标。网络主体采用24个卷基层+2个全连接层的结构。YOLOv1还有一个Fast YOLO版本,这个版本是将前面的24个卷基层裁剪为9个卷基层,其他都一样。
    注意,这次我们要结合具体的模型进行讨论了。在YOLOv1的第一个模型中。输入图像都统一到448×448个像素的RGB三通道的图像上,方法嘛就是填充拉伸,长方形图像撑不满这个正方形图像的地方就用五十度灰涂上,这个具体方法以后有机会再说。根据上面的流程图,这个448(像素)×448(像素)×3(通道)的图像,进入网络后:
    第一层:使用分辨率为7×7×64卷积核(步长为2),将448×448×3的图像先变为224×224×64图像;再使用分辨率为2×2(步长为2)的最大池化层,将图像变为112×112×64的图像。注意哦,卷积核的个数决定计算后图像的通道数,先挖个坑,后头专门讲darknet使用图像重排和通用矩阵乘法(GEMM,General Matrix Multiplication)方法求卷积。总之,记住卷积后的图像长宽等于原始长宽分别除以卷积步长、通道数等于卷积核个数就行了。
    第二层:使用3×3×192的卷积核(步长为1),将112×112×64图像变为112×112×192图像;再使用分辨率为2×2(步长为2)的最大池化层,将图像变为56×56×192的图像。
    第三层:使用1×1×128的卷积核(步长为1),将56×56×192图像变为56×56×128图像;使用3×3×256的卷积核(步长为1),将56×56×128图像变为56×56×256图像;使用1×1×256的卷积核(步长为1),56×56×256图像没有变化;使用3×3×512的卷积核(步长为1),将56×56×512图像变为56×56×512图像;再使用分辨率为2×2(步长为2)的最大池化层,将图像变为28×28×512的图像。
    第四层:1×1×128的卷积核(步长为1)和3×3×256的卷积核(步长为1)先使用4次,再参考之前的方法,得到14×14×1024的图像。
    第五层:得到7×7×1024的图像。
    第六层:3×3×1024的两种卷积核使用后得到7×7×1024的图像。
    第七层:单层全连接层,得到4096个元素。
    第八层:7×7×30的全连接层,得到7×7×30个结果元素。
    这就是yolov1结构,共24个卷基层,从第一层到第八层:1+1+4+(2×4+2) +(2×2+2)+2=24。

    目标输出

    YOLOv1的目标输出为7×7×30个结果,什么意思呢。7×7输出层包含对应448×448原始输入平面对应位置经过64倍缩放和特征提取,每个相应区域能够检测出来的结果。这是一个30维的张量,前10个维度分2组,分别用于检测(注意是“用于”而不是直接“输出”)2个目标置信度confidence、中心的坐标(x,y)、边框(w,h)。后面20个维度用于20中目标的分类。简而言之,YOLOv1的检测能力是一个区域内在20种目标中检测出2个结果。
    前面说“用于”而不是输出,是因为还要通过一定的计算公式计算出相应的结果。YOLO和其他模型不同的是,边框回归值并不是直接预测出来坐标和尺寸,而是坐标预测一个0到1之间的偏置值,边框尺寸预测一个0到1的相对值。这个关于目标检测计算的原理这里挖个坑,后面结合代码再说。

    网络训练

    YOLO系列的模型训练其实是两步训练的,卷积层的初始参数通过ImageNet 1000-class,使用前20个卷基层+平均池化层+一个全连接层的模型进行预训练。后面新增的权重都采用随机生成的方式,用户可以根据自己实际的数据集需求使用YOLO网络,用YOLO预训练的weight文件进行训练。预训练不在我们讨论的范畴,拿来直接用就行了,我们这里讨论YOLO模型本身的训练。
    训练的过程当然还是使用反向传播,无论哪个版本的神经网络反向传播原理都是一样的,关于反向传播的具体方法和代码解读这里也挖个坑,后续有机会再说。为了说明不同的版本的YOLO模型的差异,这里重点讨论LOSS函数。
    LOSS函数就是损失函数,有时候也叫做代价函数。在YOLOv1中损失函数见下图。

    在这里插入图片描述
    关于这个LOSS函数,我们说几个点:
    1.采用平方和误差
    2.由于需要均衡不同输出值得数量级和大小对整个LOSS函数的影响,首先,使用了λcoord =5和λnoobj=0.5进行调节;其次宽高计算平方根的误差,而坐标直接计算误差(因为坐标是偏置值,普遍比宽高要小);再次,计算confidence时候,同时计算有目标和无目标的误差。
    3.计算分类时候,只计算有目标的条件下的分类的准确性。
    4.公式中 表示有物体中心落入的cell,需要计算分类损失,无目标就置0,通过这种方式减少运算量。
    总之这个LOSS函数设计的也是煞费苦心,至于λ设置是不是最优,这个很难说,但是应该是一个比较优异的设计。
    根据这个LOSS函数,再进行求导,反向传播,调整weight。

    YOLOv1的局限性

    1.YOLOv1每次只能检测1个类别,两个目标。
    2.成群的小目标无法预测。
    3. YOLOv1对于大尺度目标效果不错,但是小目标效果欠佳。因为小目标有一点小偏差,其相对误差就会很大,大目标相反。
    4.图片长宽比和设置特殊的条件下效果就差一些,比如窄条图像,效果不好。

    和R-CNN系列的对比

    目标探测是计算机视觉的核心问题,首先都是先进行特征提取,如使用Haar,SIFT,HOG,卷积特征提取等,然后分类器和定位器开始使用滑窗(三十年前雷达信号处理就是这种方法,还有脉冲积累,和图像多层次累积的方法太相似了)或者图像子区域等方法进行处理。
    YOLO和R-CNN其实有很多相似之处,首先都是对原始图像划分网格,每个网格又表征一些图像特征,但是YOLO划分的网格要比R-CNN系列少的多,合并后的区域也只有一个最终目标的区域。Fast R-CNN和Faster R-CNN速度更快,但是效果有较大差距。和其他模型相似度更低的模型的比较可以参考YOLOv1的论文,这里再讨论。

    在这里插入图片描述
    mAP(mean Average Precision)就是每一类平均精度AP(Average Precision)的均值。AP就是对PR曲线(P:precision,R:recall,横轴R,纵轴P)求均值。具体评价体系先挖坑,总之就是考察目标命中率、命中正确率的综合指标。FPS (Frame Per Second)每秒帧率,就是每秒可以处理的图片数量。对于同一个模型,修改设置,这两个指标相互妥协,但是考虑不同模型之间,YOLO具有综合优势。最暴力的理解方式就是把mPA和FPS相乘看哪个大,一般就可以判断出来啦。
    另外还有一个对比图

    在这里插入图片描述
    关于这幅图,大家自己看。有个问题不吐不快,当研究出一个新的模型的时候,往往都会有一些妥协的因素在里面。国内学术界往往有一个很不好的习惯,就是是个创新就要全方位比别人优越百分之多少,其实参考这个YOLO,和Fast R-CNN相比,速度就是绝对优势,正确率和同类系统持平就是最大创新。都给你穿刘翔的红魔了,还要什么自行车?

    YOLOv2

    YOLOv2论文是Joseph Redmon在CVPR 2017获得 Best Paper Honorable Mention的作品,名称《YOLO9000: Better, Faster, Stronger》,首先在YOLOv1基础上改进得到YOLOv2,在COCO检测数据集和ImageNet分类数据集上训练出了YOLO9000模型,其可以检测超过9000多类物体。在保持一惯性的优良速度上,提高了mAP。
    上一节我们说到,YOLOv1和R-CNN相比,速度快,但精度下降。到了YOLOv2提出了几个改进策略。

    结构

    这次的模型的基础分类结构叫做Darknet-19,包括19个卷积层、5个maxpooling层、1个全局Avgpool层,一个softmax分类激活层,如下图所示。

    在这里插入图片描述
    遵循上一节的思路,我们把它分为8个大层。为了和前面描述保持一致,具体描述可参考配置文件darknet19_448.cfg。上图从论文中截取,论文中使用的是224×224的输入,这个都没有很大关系。
    每一层具体有什么,输出多大,估计读者已经很熟悉了,参考YOLOv1这里不再啰嗦,需要注意的是第六层:5个卷基层、无池化层;第七层:1×1×1000(步长为1)的卷基层+全局平均池化,得到1000个输出;第八层:softmax分类激活层,得到最终结果。YOLOv2已经没有了4096个输入的全连接层。这个darknet19输出只有分类,具体如何得到估计结果,可以参考yolov2.cfg和yolov2-voc.cfg。
    这里以yolov2.cfg描述的结构为例进行进一步说明(这里输入为608×608)。
    这里第七层、第八层由region探测模块代替:一个卷积+1000输出的全局平均池化改为3×3×1024(步长为1)的卷基层+3×3×1024(步长为1)的卷基层+route层(往前追溯9层后拿过来累加)+1×1×64(步长为1)的卷基层+reorg层(步长2)+route层(往前追溯1层和4层后拿过来两层累加)+1×1×425(步长为1)的卷基层+region层。
    好了,除了整体上结构组成和YOLOv1相比有变化,还有哪些优化呢?下面简单介绍一下,关于源码解析,也挖个坑。

    1. batch_normalize层
      在每一个卷积层的实现中增加了一个batch_normalize层。这个层的主要用处就是防止梯度爆炸和梯度消失。YOLOv1总共只有24个卷积层,到了YOLOv2其实也是24个卷基层,和yolov2和darknet19共同的结构也是前面19个卷基层+5个最大池化层。这时候相比较YOLOv1这个功能还不太明显,但是到了YOLOv3中的darknet53,甚至YOLOv4,这个功能的效果就很明显了。
      那么是怎么防止梯度爆炸和梯度消失的呢,计算梯度需要计算误差,反向传播过程中误差也在反向传播,根据反向传播原理会有累加和累乘效应,如果每一层的误差计算不加以控制的话,梯度的增量会逐渐消失或者变成无限大。batch_normalize就是按批次(batch)进行归一化,控制反向传播过程中这种问题。
      具体思想要结合随机梯度下降(SGD)的理念来说,把每一层都当做一个联合概率函数,整个系统累乘就是一个巨大的联合概率函数, 元素就是每一层的输入,再在每一层进行归一化的时候,把一个batch的元素放在一起求均值和方差,用计算的元素减去均值再除以方差,就是归一化。执行的时候,为了防止改变概率分布特征,需要对归一化的结果加上尺度变换(scale)和偏置(offset)。
    2. route层
      增加了2个route层。
      先说第1个,这个route层往前追溯9层,就到了最后一个maxpool层之前的一层,如果输入是一个608×608的图像。到了这一层,输出就是一个38×38×512的l.output(代码中每个layer结构中都定义了output变量,l.output表示layer变量l中的output,这里这样描述感觉会让读者潜移默化的了解代码,会比较方便,尝试一下哈)。
      再说第2个,将reorg层的l.output和第七层中的3×3×1024(步长为1)的卷基层的l.output拿过来,放在一起,这两个l.output的尺寸(l.w×l.h×l.channels)分别是19×19×256和19×19×1024。
      那么route层干什么呢?route就是路由,简单的说就是将指定层的输出拿过来放在本层中,如果是多层,就接续放在后面。如果是多层,有一个关键的规则就是这两层的尺寸宽×高(l.w×l.h)必须一样,否则就把l.w和l.h都归零。
      由于YOLO是一次检测,特征提取顺序进行,不断的进行卷积卷积再卷积,然后还要池化,卷到最后就可能会有一些信息糊到一起了,很对细节的信息越往前越清楚,越往后分类越清楚,可是坐标啊、图像尺寸啊,就慢慢模糊了。为了进行平衡,需要把前面的信息拿过来和后面的信息混在一起用一用。怎么办呢?就路由一下吧。上一节讨论过妥协,route层使得YOLO不再是纯粹的“你只看一眼”,到后头你还要往前多看两眼,调整一下得到的结果,然后提高了预测准确度。
    3. reorg层
      reorg层的作用是将上一层卷积后的特征图38×38×64 拉伸成19×19×256,步长stride=2就相当于l.input中以每2×2为一个单位拆分到4层,和池化层相比的好处就是不会把2×2中的内容糊到一起,当然,个人觉得使用池化再把池化后的l.output复制4次效果可能也差不多,但是在路由的时候会失掉一些细节,那路由的意义就下降了。
    4. region层
      需要说明的一点,在darknet软件框架中,将YOLOv1的探测层定义为detection,将YOLOv2的探测层定义为region,将YOLOv3的探测层定义为yolo。功能都是用于生成最终的输出结果。
      YOLOv1的detection使用的是全连接层,而YOLOv2的region层使用softmax进行分类,使用了anchors进行边框回归获得边框坐标和尺寸。

    目标输出

    以coco数据集为例,最后一层输出最后一层维度是425,表示可以最多检测80个种类,同时检测5个目标,5*(80+5),输出卷积层l.output是一个425个通道的张量。
    注意,这里使用了Anchor boxes,这个玩意就是先验框,提前使用K-means聚类算法,将各种不同的目标聚类成5大类。在region层实现探测的时候,选择最接近的一个,计算目标尺寸和先验框的比值。
    这里就很自然的引出来YOLOv2的边框回归计算坐标和目标尺寸的思想。其实在R-CNN系列模型中就已经使用了边框回归了,当然,具体方法有所区别,大体思路还是一致的。
    先给一个论文中的新鲜截图

    在这里插入图片描述
    边框回归需要处理的输出就是(tx,ty,tw,th)。公式如下
    在这里插入图片描述
    理论上可以使用一定的公式方法σ(t)先处理一下,当tx<0,,就直接置0,代码实现中使用sigmod函数(LOGISTIC),针对每个预选框前两个输出平面使用激活函数。tw和th之所以需要计算幂值,是因为tw和th实际上是预测宽度和高度与真实值(truth.w和truth.h)的比值,为同样为了防止由于误差过大导致梯度爆炸或梯度消失退,这个比值取了一个log。有说法是根据极限定理,当tw->truth.w,两个值是有线性关系,可以进行线性回归。本人对此不是很认同,解释有点牵强附会。
    另外,关于置信度见以下公式
    在这里插入图片描述
    输出结果中,score,也就是to,也是使用了sigmod函数的。这里面IOU就是预测结果和真实目标(GT,ground truth)的交并比(Intersection-over-Union),说白了,就是两个图像区域的交集和并集的比值。区域重合度越高,说明预测的边框越准确,这个IOU属于区间[0,1),为啥说不可能为1呢?因为你能够计算出1,就是过拟合,你的模型泛化能力就太差了。
    关于这个Pr(object)目前没有查到具体的解释,论文中也没有明确的解释,如果以后弄明白了再更新。但是根据本文所需理解的内容,这个公式基本用不到。

    网络训练

    方法和YOLOv1相同,这里重点看LOSS函数。YOLOv2比YOLOv1的LOSS函数更加复杂。
    在这里插入图片描述
    W和H是先验框宽和高,在YOLOv1中使用了S×S。A表示先验框数目,这里是5,前面在说配置文件的时候中也提到过。
    第一项loss是计算background的置信度误差,但是哪些预测框来预测背景呢,需要先计算各个预测框和所有ground truth的IOU值,并且取最大值Max_IOU,如果该值小于一定的阈值(YOLOv2使用的是0.6),那么这个预测框就标记为background,需要计算noobj的置信度误差。
    第二项是计算先验框与预测框的坐标误差,但是只在前12800个iterations间计算,我觉得这项应该是在训练前期使预测框快速学习到先验框的形状。
    第三大项计算与某个ground truth匹配的预测框各部分loss值,包括坐标误差、置信度误差以及分类误差。先说一下匹配原则,对于某个ground truth,首先要确定其中心点要落在哪个cell上,然后计算这个cell的5个先验框与ground truth的IOU值(YOLOv2中bias_match=1),计算IOU值时不考虑坐标,只考虑形状,所以先将先验框与ground truth的中心点都偏移到同一位置(原点),然后计算出对应的IOU值,IOU值最大的那个先验框与ground truth匹配,对应的预测框用来预测这个ground truth。在计算obj置信度时,在YOLOv1中target=1,而YOLOv2增加了一个控制参数rescore,当其为1时,target取预测框与ground truth的真实IOU值。对于那些没有与ground truth匹配的先验框(与预测框对应),除去那些Max_IOU低于阈值的,其它的就全部忽略,不计算任何误差。这点在YOLOv3论文中也有相关说明:YOLO中一个ground truth只会与一个先验框匹配(IOU值最好的),对于那些IOU值超过一定阈值的先验框,其预测结果就忽略了。这和SSD与RPN网络的处理方式有很大不同,因为它们可以将一个ground truth分配给多个先验框。尽管YOLOv2和YOLOv1计算loss处理上有不同,但都是采用均方差来计算loss。另外需要注意的一点是,在计算boxes的和误差时,YOLOv1中采用的是平方根以降低boxes的大小对误差的影响,而YOLOv2是直接计算,但是根据ground truth的大小对权重系数进行修正:l.coord_scale * (2 - truth.w*truth.h),这样对于尺度较小的boxes其权重系数会更大一些,起到和YOLOv1计算平方根相似的效果(参考YOLO v2 损失函数源码分析)。
    最终的YOLOv2模型在速度上比YOLOv1还快(采用了计算量更少的Darknet-19模型),而且模型的准确度比YOLOv1有显著提升,详情见paper。

    关于YOLO9000

    YOLO9000是在YOLOv2的基础上提出的一种可以检测超过9000个类别的模型,其主要贡献点在于提出了一种分类和检测的联合训练策略。
    众多周知,检测数据集的标注要比分类数据集打标签繁琐的多,所以ImageNet分类数据集比VOC等检测数据集高出几个数量级。在YOLO中,边界框的预测其实并不依赖于物体的标签,所以YOLO可以实现在分类和检测数据集上的联合训练。对于检测数据集,可以用来学习预测物体的边界框、置信度以及为物体分类,而对于分类数据集可以仅用来学习分类,但是其可以大大扩充模型所能检测的物体种类。
    作者选择在COCO和ImageNet数据集上进行联合训练,但是遇到的第一问题是两者的类别并不是完全互斥的,所以作者提出了一种层级分类方法(Hierarchical classification),主要思路是根据各个类别之间的从属关系(根据WordNet)建立一种树结构WordTree。
    这部分内容读者有兴趣可以专门研究,本人在将来有时间且搞明白的时候也会努力写一写。

    YOLOv3

    YOLOv3依然是在YOLOv2的基础上,可参考的论文《YOLOv3: An Incremental Improvement》,文章很简单,作者也说这是个工作报告,把其他的一些文章中的有价值的内容尝试一下。

    结构

    YOLOv3在YOLOv2的基础上拓展成darknet53,算是比较大的了。先上结构图。
    在这里插入图片描述
    Darknet53就是指52层卷积层+1个全连接层(通过1x1卷积实现)。相比较YOLOv2,YOLOv3再也没有了maxpooling层,没有了reorg层,相比多了residual层,结构上采用了多分辨率的方法,设置大、中、小三个不同尺度的YOLO层。上图和描述YOLOv2的结构图一样,只描述了一个分类结构,参考yolov3.cfg和yolov3-voc.cfg配置文件,代替Avgpool后面内容的是3个并联的yolo层,并联的实现是通过route层。上图。
    在这里插入图片描述
    这个图是我在网上看到的最详细的结构图,粉红色为特征提取层,橘色为检测层,绿色为上采样层。其实在配置文件中是52个卷积特征提取层和23个residual(配置文件中为shortcut)之后,先经过(7个卷基层+1个yolo层构成的)8层大尺度检测模块,接着是(1个route层+1个卷基层+1个upsample层+1个route层+7个卷积层+1个yolo层)的12层中尺度检测模块,最后是和中尺度类似结构的12层小尺度检测模块,共107层。
    下面说说新增的residual层和upsample层。

    1. residual层
      先说说residual层的产生背景。前面说过,深度神经网络就是一个巨大的联合概率分布,参数越多,提取的特征越多。你可以横向把单个层做的很宽,也可以往深里面做。做的宽没有累乘效应,实现相同的效果参数就会指数增加,往深里做就可以以节约参数,更重要的一点是可以不断抽象、抽象、抽象,可以变得适应性更强。但是往深里走也有坏处,第一个问题是,累乘多了,就会梯度爆炸和梯度消失,前面说归一化的时候已经讨论这个问题了。第二个问题就是网络退化,梯度问题是反向传播的问题,网络退化是凡响传播和前向传播共同的问题。为啥退化呢?这个有点类似于采购与供应链管理中的“牛鞭效应”,一个是就是误差积累,每一层都有误差,通过卷积累乘累加之后误差到牛鞭末梢就会很大;另外,层次越多,“牛鞭”越长,往往前后难以兼顾,训练就很困难。
      怎么办呢?ResNets就诞生了,ResNets叫残差网络。残差,顾名思义就是回归运算中估计值与真实值的差,残差网络基本原理就是训练的卷基层不再针对本身输出的结果,而是训练一个残差。前面说过,为了保证网络不过拟合,拥有较好的泛化能力,残差就不可避免,我们这里是将残差训练到最小。
      于是,在YOLOv3中,加入了residual层用来实现残差网络。residual层也叫shortcut层,听起来就是个捷联层或者短路层。谁和谁短路呢?一般是将前面若干层的输出直接引到当前层的输出层。但它和route层有个很大的区别,就是route层只是将前面层的输出拿过来放在当前输出的存储空间后面,下一层一起处理这两个层的信息,但residual层就直接用来和当前输出相加,再通过激活函数输出。具体结构见下图,shortcut层就是那个加法结构。
      在这里插入图片描述
      假如没有残差层,以上模块输入为x,输出为H(x),我们优化的目标是H(x)。有了残差层,H(x)=F(x)+ x,残差就是F(x)= H(x)-x,只要把F(x)训练到一个足够小的合适的值,H(x)就会更加接近理想的输出。这里面有两方面原因:
      第一,如果一个数据集条件下(注意,不同的数据集对网络配置的需求也不一样,就好像打游戏的人买手机和不打游戏的人买手机需求不同类似)深度神经网络前面的层已经训练饱和,后面的训练其实就不再需要,冗余的配置可以通过残差网络抵消,不使用残差网络就需要把后面几层训练成“恒等映射”,没有约束的条件下随便几层网络是训练不成的。
      第二,当非残差层将网络训练到近似可用的条件下,残差网络模块就是一个调优器。用过示波器的朋友们都知道,示波器有一个“粗调”旋钮和一个“细调”旋钮,粗调和细调的步进值不同。训练过程就像一个调节的过程,改变相同的参数幅度,F(x)和 x调节的效果不同。另外,有实验证明残差模块组成需要两层以上,单层的并不起作用。
    2. upsample层
      这个层和上面的reorg层功能有点类似,reorg层是在某一层l.output单个输出特征平面尺寸l.w×l.h比route层拿过来的其它层l.w×l.h尺寸大的时候,把当前的l.output像弹簧圈一样拉细拉长。upsample正相反,用于在route的时候要扩大特征平面,不同通道的内容代表不同的特征,这辈子压扁是不可能了,就只能用每个点的分身去周边填充,吃个虚胖再说。
      神经网络越深,不是特征平面越小么,YOLOv3怎么还要增大呢?大家肯定没有忘记,咱们的YOLOv3是分了大、中、小单个尺度。先计算大尺度,大尺度特征比较粗线条,卷积后的特征图肯定是要糊啊,要缩小尺度提高检测精细程度,就要把前面没有糊的较大的特征平面拿过来路由在一起,但是尺寸有不一样,只能打肿脸充胖子。当然说打肿脸也不全对,因为就像发酵的酵母,拿过来一点和新鲜面粉和在一起,可以提高三个尺度检测的一致性,虽然并不是经常都能一致,甚至大尺度有些目标东西根本就检测不出来。
    3. yolo层
      YOLO系列作者挺有意思,v1输出层叫detection层,v2输出层叫region层,v3输出层叫yolo层,也许真的认为v3已经修炼成功了。
      看配置文件,共有三个yolo层,配置都一样,唯一的区别就是mask序号不一样,mask对应这一层使用的anchor。从结构上,每层都就简单多了,没有了softmax分类器。
      yolo层每层对应3个聚类好的anchor box,尺度一看也可以看出来。anchor预先确定的尺寸是相对整个网络输入层而言的,在训练的时候先确定使用3个框中使用哪个,然后对照训练预测宽高和anchor box宽高的比值。

    目标输出

    每个yolov层的目标输出为255个通道,255个通道表示可以同时输出80个类别中3个类别的目标,输出结果中每组前5个通道是(x,y,w,h,score),后80个通道是80个类别,一共(4+1+80)×3 = 255。另外,按照darknet中的配置,每个图最多可以显示90个目标,万人大会做不到,有木有感觉有点少。
    其他目标输出的检测原理和YOLOv2都是一样的。

    网络训练

    关于YOLOv3的损失函数,先上公式。
    在这里插入图片描述
    这个公式有4点需要说明:
    1.公式是从YOLOv1、YOLOv2演变过来的,使用了二分交叉熵损失,但不再单独区分background,不再使用基于softmax的多分类损失函数。在配置文件中不再专门配置各种λ系数,实际上全都取了常数1。
    2.比较有争议的一点是在darknet的实现中,使用了MSE损失函数代替交叉熵损失函数,一种解释是对于Logistic回归,正好方差损失和交叉熵损失的求导形式是一样的,作者这里直接用方差损失代替了,因为数值趋势上是一样的。(可参考https://blog.csdn.net/jasonzzj/article/details/52017438)
    3.边框信息损失会乘一个(2-w×h)的比例系数,w 和 h 分别是GT的宽和高。这是为了提升针对小物体预测准确度的一个小技巧,对于w,h<1,如果w,h越小,(2-w×h)越大,这部分权重就越大,误差产生的影响就可以进一步放大,有人做实验针对 YOLOv3,如果不减去 wh,AP 会有一个明显下降,如果继续往上加,如 (2-wh)*1.5,总体的 AP 还会涨一个点左右(包括验证集和测试集)。
    4.在代码中计算class的误差有一个是否为0的判断,主要是因为由于不同尺度输出平面每个元素对应网络输入至少8×8的像素面积,在同一个位置可能会预测到多个目标,如果判断为0,就可以转入下一个预测框中。这部分可以看代码(https://blog.csdn.net/jiyangsb/article/details/81976090)中也有说明,写得更详细。

    YOLOv3系统做过的不成功的尝试

    作者在论文中专门介绍了实验过程中不成功的尝试,这是很新颖的,这里也罗列一下:
    1.Anchor box 坐标偏移量预测。作者尝试通过常规的Anchor box预测机制,将坐标偏移量预测为边界框宽度或高度的倍数,激活函数使用linear函数。但是降低了系统的稳定性,效果也不好。
    2.使用linear激活函数代替logistic来预测坐标,这种方式导致mAP的下降。其实很佩服的一点是YOLOv3取消了池化层、softmax层、全连接层,已经把卷积神经网络弄得足够简单,但是想把激活函数也去掉(linear激活就相当于不用激活),看来是不行,作者的反叛精神可见一斑。
    3. focal loss。下面是focal loss的公式:
    在这里插入图片描述
    这里不详细讨论,介绍一下背景,方便我们感知目标检测的现状。首先,Lin等人回顾了一下目前目标检测的发展概况,先进的目标检测算法目前大概分成两种,一种是one-stage的,一种是two-stage的。one-stage的代表作YOLO以一种简单统一的网络成功实现了实时检测的目的,但是它的准确率并不是best。相反的,two-stage的代表作RCNN系列则是在准确率方面完胜其他模型,但是它的检测速度真的是慢的有的可怜(相比于YOLO)。 于是,Lin他们就开始研究造成这种现象的原因,接着他们就发现原来是在训练的时候,后景数据相比于前景数据较少的缘故。为了解决这个问题,Lin等人对标准的交叉熵损失函数进行修改,降低那些已经分类很好的样例对loss的影响比重,称之为Focal Loss,也就是会特别关注某一些loss的意思。 最后,Lin等人实现了一个使用Focal Loss的简单的检测系统,最终在速度上几乎赶上了YOLO,并且在准确性了超过了现有的所有检测算法。
    其实吧,YOLOv3不再专门检测背景数据是再次提升速度的一个原因,天下没有免费的午餐,想要精度就要牺牲速度,Faster R-CNN也没有必要继续追求快,“快”这个字交给YOLO就好了,未来硬件水平提升了,还能更快。作者也说了,对于focal loss想要解决的问题,YOLO已经做得很好了,这个尝试方向确实有很多不确定的东西。
    4.双IOU阈值和真值分配。Faster R-CNN训练时候使用了双IOU阈值。双IOU的意思是如果预测框和GT框的IOU>0.7,则为正样本,0.3到0.7之间忽略,<0.3认为是负样本,实际效果并不好。

    未来

    写这篇文章,是想从R-CNN开始,梳理了一下YOLOv1、YOLOv2、YOLOv3,便于下一步更加清楚的理解YOLOv3的实现和后续。YOLOv4已经由Alex提出,本质上继承了YOLOv3的结构,加了更多目前的新的用途的trick。YOLOv4主要还是面向工业级的应用,在TensorFlow、pytorch、caffe等框架中都在应用,不同版本的实现各有不同,本质上都是相同的。目前的报道上PaddlePaddle也有了YOLOv3的实现,而且PaddlePaddle这两年受欢迎度蹿升的很厉害,不知道PaddlePaddle版本的应用未来会怎样,我们拭目以待。

    展开全文
  • YOLO系列详解:YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5

    万次阅读 多人点赞 2021-03-15 10:57:00
    具体的改进见下表: 3.2 YOLOv2的改进点 3.2.1 Batch Normalization 批量归一化有助于解决反向传播过程中的梯度消失和梯度爆炸问题,降低对一些超参数(比如学习率、网络参数的大小范围、激活函数的选择)的敏感性...

    一、前言

    YOLO系列是one-stage且是基于深度学习的回归方法,而R-CNN、Fast-RCNN、Faster-RCNN等是two-stage且是基于深度学习的分类方法。

    YOLO官网:https://github.com/pjreddie/darknet

    1.1 YOLO vs Faster R-CNN

    1、统一网络:YOLO没有显示求取region proposal的过程。Faster R-CNN中尽管RPN与fast rcnn共享卷积层,但是在模型训练过程中,需要反复训练RPN网络和fast rcnn网络。相对于R-CNN系列的"看两眼"(候选框提取与分类),YOLO只需要Look Once.

    2、YOLO统一为一个回归问题,而Faster R-CNN将检测结果分为两部分求解:物体类别(分类问题)、物体位置即bounding box(回归问题)。

    二、YOLOv1

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

    官方代码:https://github.com/pjreddie/darknet

    YOLOv1的核心思想:

    • YOLOv1的核心思想就是利用整张图作为网络的输入,直接在输出层回归bounding box的位置和bounding box所属的类别。
    • Faster RCNN中也直接用整张图作为输入,但是Faster-RCNN整体还是采用了RCNN那种 proposal+classifier的思想,只不过是将提取proposal的步骤放在CNN中实现了,而YOLOv1则采用直接回归的思路。

    2.1、实现方法

    • 将一幅图像分成SxS个网格(grid cell),如果某个object的中心落在这个网格中,则这个网格就负责预测这个object。

    • 每个网格要预测B个bounding box,每个bounding box除了要回归自身的位置之外,还要附带预测一个confidence值。这个confidence代表了所预测的box中含有object的置信度和这个box预测的有多准两重信息,其值是这样计算的:

            该表达式含义:如果有object落在一个grid cell里,则第一项取1,否则取0。 第二项是预测的bounding box和实际的groundtruth之间的IoU值。 

    • 每个bounding box要预测(x, y, w, h)和confidence共5个值,每个网格还要预测一个类别信息,记为C类。则SxS个网格,每个网格要预测B个bounding box还要预测C个categories。输出就是S x S x (5*B+C)的一个tensor。

           注意:class信息是针对每个网格的,confidence信息是针对每个bounding box的。

    举例说明:

    在PASCAL VOC中,图像输入为448x448像素,取S=7,B=2,一共有20个类别(C=20)。则输出就是7x7x(2x5+20)的一个tensor。整个网络结构如下图所示:

    • 在test的时候,每个网格预测的class信息和bounding box预测的confidence信息相乘,就得到每个bounding box的class-specific confidence score,得到每个box的class-specific confidence score以后,设置阈值,滤掉得分低的boxes,对保留的boxes进行NMS处理,就得到最终的检测结果。

           该表达式含义:等式左边第一项就是每个网格预测的类别信息,第二三项就是每个bounding box预测的confidence。这个乘积即encode了预测的box属于某一类的概率,也有该box准确度的信息。 

    注意:

    1. 由于输出层为全连接层,因此在检测时,YOLOv1模型的输入只支持与训练图像相同的输入分辨率。
    2. 虽然每个格子可以预测B个bounding box,但是最终只选择IOU最高的bounding box作为物体检测输出,即每个格子最多只预测出一个物体。当物体占画面比例较小,如图像中包含畜群或鸟群时,每个格子包含多个物体,但却只能检测出其中一个。

    简单的概括就是:

    • 给个一个输入图像,首先将图像划分成7*7的网格;
    • 对于每个网格,我们都预测2个边框(包括每个边框是目标的置信度以及每个边框区域在多个类别上的概率);
    • 根据上一步可以预测出7*7*2个目标窗口,然后根据阈值去除可能性比较低的目标窗口,最后NMS去除冗余窗口即可。

    2.2、损失函数

    每个grid有30维,这30维中,8维是回归box的坐标,2维是box的confidence,还有20维是类别。其中坐标的x,y用对应网格的offset归一化到0-1之间,w,h用图像的width和height归一化到0-1之间。在实现中,最主要的就是怎么设计损失函数,让这个三个方面得到很好的平衡。作者简单粗暴的全部采用了sum-squared error loss来做这件事。

    这种做法存在以下几个问题:

    • 第一,8维的localization error和20维的classification error同等重要显然是不合理的;
    • 第二,如果一个网格中没有object(一幅图中这种网格很多),那么就会将这些网格中的box的confidence push到0,相比于较少的有object的网格,这种做法是overpowering的,这会导致网络不稳定甚至发散。

    解决方法

    • 更重视8维的坐标预测,给这些损失前面赋予更大的loss weight;
    • 对没有object的box的confidence loss,赋予小的loss weight;
    • 有object的box的confidence loss和类别的loss的loss weight正常取1。

    YOLOv1在对不同大小的box预测中,相比于大box预测偏一点,小box预测偏一点肯定更不能被忍受的。而sum-square error loss中对同样的偏移loss是一样。为了缓和这个问题,作者用了一个比较取巧的办法,就是将box的width和height取平方根代替原本的height和width。这个参考下面的图很容易理解,小box的横轴值较小,发生偏移时,反应到y轴上相比大box要大。(也是个近似逼近方式)

    一个网格预测多个box,希望每个box predictor专门负责预测某个object。具体做法就是看当前预测的box与ground truth box中哪个IoU大,就负责哪个。这种做法称作box predictor的specialization。

    在YOLOv1的损失函数中:

    • 只有当某个网格中有object的时候才对classification error进行惩罚。
    • 只有当某个box predictor对某个ground truth box负责的时候,才会对box的coordinate error进行惩罚,而对哪个ground truth box负责就看其预测值和ground truth box的IoU是不是在那个cell的所有box中最大。

    注:

    • YOLOv1方法模型训练依赖于物体识别标注数据,因此,对于非常规的物体形状或比例,YOLOv1的检测效果并不理想。
    • YOLOv1采用了多个下采样层,网络学到的物体特征并不精细,因此也会影响检测效果。
    • YOLOv1的loss函数中,大物体IOU误差和小物体IOU误差对网络训练中loss贡献值接近(虽然采用求平方根方式,但没有根本解决问题)。因此,对于小物体,小的IOU误差也会对网络优化过程造成很大的影响,从而降低了物体检测的定位准确性。

    YOLO的缺点

    • YOLO对相互靠的很近的物体和很小的群体检测效果不好,这是因为一个网格中只预测了两个框,并且只属于一类;
    • 同一类物体出现的新的不常见的长宽比和其他情况时,泛化能力偏弱;
    • 由于损失函数的问题,定位误差是影响检测效果的主要原因。尤其是大小物体的处理上,还有待加强。

    三、YOLOv2

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

    官方代码:http://pjreddie.com/darknet/yolo/

    3.1 YOLOv2介绍

    YOLOv2相对v1版本,在继续保持处理速度的基础上,从预测更准确(Better)速度更快(Faster)识别对象更多(Stronger)这三个方面进行了改进。其中识别更多对象也就是扩展到能够检测9000种不同对象,称之为YOLO9000

    文章提出了一种新的训练方法–联合训练算法,这种算法可以把这两种的数据集混合到一起。使用一种分层的观点对物体进行分类,用巨量的分类数据集数据来扩充检测数据集,从而把两种不同的数据集混合起来。联合训练算法的基本思路就是:同时在检测数据集和分类数据集上训练物体检测器(Object Detectors ),用检测数据集的数据学习物体的准确位置,用分类数据集的数据来增加分类的类别量、提升健壮性。

    YOLO9000就是使用联合训练算法训练出来的,他拥有9000类的分类信息,这些分类信息学习自ImageNet分类数据集,而物体位置检测则学习自COCO检测数据集。

    YOLOv1有很多缺点,作者希望改进的方向是:改善recall,提升定位的准确度,同时保持分类的准确度。目前计算机视觉的趋势是更大更深的网络,更好的性能表现通常依赖于训练更大的网络或者把多种model综合到一起,但是YOLOv2则着力于简化网络。具体的改进见下表:

    3.2 YOLOv2的改进点

    3.2.1 Batch Normalization

    批量归一化有助于解决反向传播过程中的梯度消失和梯度爆炸问题,降低对一些超参数(比如学习率、网络参数的大小范围、激活函数的选择)的敏感性,并且每个batch分别进行归一化的时候,起到了一定的正则化效果(YOLOv2不再使用dropout),从而能够获得更好的收敛速度和收敛效果。

    使用Batch Normalization对网络进行优化,让网络提高了收敛性,同时还消除了对其他形式的正则化(regularization)的依赖。通过对YOLOv2的每一个卷积层增加Batch Normalization,最终使得mAP提高了2%,同时还使model正则化。使用Batch Normalization可以从model中去掉Dropout,而不会产生过拟合。

    关于批规一化的更多信息可以参考:Batch Normalization原理与实战

    3.2.2 High resolution classifier

    用于图像分类的训练样本很多,而标注了边框的用于训练目标检测的样本相比而言就少了很多,因为标注边框的人工成本比较高。所以目标检测模型通常都先用图像分类样本训练卷积层,提取图像特征,但这引出另一个问题,就是图像分类样本的分辨率不是很高。所以YOLOv1使用ImageNet的图像分类样本采用 224*224 作为输入,来训练CNN卷积层。然后在训练目标检测时,检测用的图像样本采用更高分辨率的 448*448 像素图像作为输入,但这样不一致的输入分辨率肯定会对模型性能有一定影响。

    所以YOLOv2在采用 224*224 图像进行分类模型预训练后,再采用 448*448 高分辨率样本对分类模型进行微调(10个epoch),使网络特征逐渐适应 448*448 的分辨率。然后再使用 448*448 的检测样本进行训练,缓解了分辨率突然切换造成的影响,最终通过使用高分辨率,mAP提升了4%。

    3.2.3 Convolution with anchor boxes

    YOLOv1包含有全连接层,从而能直接预测Bounding Boxes的坐标值。Faster R-CNN算法只用卷积层与Region Proposal Network来预测Anchor Box的偏移值与置信度,而不是直接预测坐标值,YOLOv2作者发现通过预测偏移量而不是坐标值能够简化问题,让神经网络学习起来更容易。

    借鉴Faster RCNN的做法,YOLOv2也尝试采用先验框(anchor)。在每个grid预先设定一组不同大小和宽高比的边框,来覆盖整个图像的不同位置和多种尺度,这些先验框作为预定义的候选区在神经网络中将检测其中是否存在对象,以及微调边框的位置。

    之前YOLOv1并没有采用先验框,并且每个grid只预测两个bounding box,也就是整个图像只有98个bounding box。YOLOv2如果每个grid采用9个先验框,总共有13*13*9=1521个先验框。所以最终YOLOv2去掉了全连接层,使用Anchor Boxes来预测 Bounding Boxes。作者去掉了网络中一个Pooling层,这让卷积层的输出能有更高的分辨率,同时对网络结构进行收缩让其运行在416*416而不是448*448。

    由于图片中的物体都倾向于出现在图片的中心位置,特别是那种比较大的物体,所以有一个单独位于物体中心的位置用于预测这些物体。YOLOv2的卷积层采用32这个值来下采样图片,所以通过选择416*416用作输入尺寸最终能输出一个13*13的Feature Map。使用Anchor Box会让精确度稍微下降,但用了它能让YOLOv2能预测出大于一千个框,同时recall达到88%,mAP达到69.2%。

    3.2.4 Dimension clusters

    之前Anchor Box的尺寸是手动选择的,所以尺寸还有优化的余地。YOLOv2尝试统计出更符合样本中对象尺寸的先验框,这样就可以减少网络微调先验框到实际位置的难度。YOLOv2的做法是对训练集中标注的边框进行K-means聚类分析,以寻找尽可能匹配样本的边框尺寸。如果我们用标准的欧式距离的k-means,尺寸大的框比小框产生更多的错误。因为我们的目的是提高IOU分数,这依赖于Box的大小,所以距离度量的使用:

     其中,centroid是聚类时被选作中心的边框,box就是其它边框,d就是两者间的“距离”,IOU越大,“距离”越近。YOLOv2给出的聚类分析结果如下图所示,通过分析实验结果(Figure 2),在model复杂性与high recall之间权衡之后,选择聚类分类数K=5。

    Table1是说明用K-means选择Anchor Boxes时,当Cluster IOU选择值为5时,AVG IOU的值是61,这个值要比不用聚类的方法的60.9要高。选择值为9的时候,AVG IOU更有显著提高。总之就是说明用聚类的方法是有效果的。

    3.2.5 Direct location prediction 

    用Anchor Box的方法,会让model变得不稳定,尤其是在最开始几次迭代的时候。大多数不稳定因素产生自预测Box的(x,y)位置的时候。按照之前YOLOv1的方法,网络不会预测偏移量,而是根据YOLOv1中的网格单元的位置来直接预测坐标,这就让Ground Truth的值介于0到1之间。而为了让网络的结果能落在这一范围内,网络使用一个 Logistic Activation来对于网络预测结果进行限制,让结果介于0到1之间。 网络在每一个网格单元中预测出5个Bounding Boxes,每个Bounding Boxes有五个坐标值tx,ty,tw,th,t0,他们的关系见下图。假设一个网格单元对于图片左上角的偏移量是cx,cy,Bounding Boxes Prior的宽度和高度是pw,ph,那么预测的结果见下图右面的公式:

    3.2.6 Fine-Grained Features 

    目标检测面临的一个问题是图像中的需要检测的目标会有大有小,输入图像经过多层网络提取特征,最后输出的特征图中(比如YOLOv2中输入416*416经过卷积网络下采样最后输出是13*13),较小的对象可能特征已经不明显甚至被忽略掉了。为了更好的检测出一些比较小的对象,最后输出的特征图需要保留一些更细节的信息。于是YOLOv2引入一种称为passthrough层的方法在特征图中保留一些细节信息。具体来说,就是在最后一个pooling之前,特征图的大小是26*26*512,将其1拆4,直接传递(passthrough)到pooling后(并且又经过一组卷积)的特征图,两者叠加到一起作为输出的特征图。

     具体怎样将1个特征图拆成4个特征图,见下图,图中示例的是1个4*4拆成4个2*2,因为深度不变,所以没有画出来。

    3.2.7 Multi-ScaleTraining

    作者希望YOLOv2能健壮的运行于不同尺寸的图片之上,所以把这一想法用于训练model中。区别于之前的补全图片的尺寸的方法,YOLOv2每迭代几次都会改变网络参数。每10个Batch,网络会随机地选择一个新的图片尺寸,由于使用了下采样参数是32,所以不同的尺寸大小也选择为32的倍数{320,352…..608},最小320*320,最大608*608,网络会自动改变尺寸,并继续训练的过程。这一政策让网络在不同的输入尺寸上都能达到一个很好的预测效果,同一网络能在不同分辨率上进行检测。当输入图片尺寸比较小的时候跑的比较快,输入图片尺寸比较大的时候精度高,所以你可以在YOLOv2的速度和精度上进行权衡。

    3.3 YOLOv2 Faster

    YOLOv1的backbone使用的是GoogleLeNet,速度比VGG-16快,YOLOv1完成一次前向过程只用8.52 billion 运算,而VGG-16要30.69billion,但是YOLOv1精度稍低于VGG-16。

    3.3.1 Draknet19

    YOLOv2基于一个新的分类model,有点类似与VGG。YOLOv2使用3*3filter,每次Pooling之后都增加一倍Channels的数量。YOLOv2使用Global Average Pooling,使用Batch Normilazation来让训练更稳定,加速收敛,使model规范化。最终的model–Darknet19,有19个卷积层和5个maxpooling层,处理一张图片只需要5.58 billion次运算,在ImageNet上达到72.9%top-1精确度,91.2%top-5精确度。

     

    3.3.2 Training for classification

    网络训练在 ImageNet 1000类分类数据集上训练了160epochs,使用随机梯度下降,初始学习率为0.1, polynomial rate decay with a power of 4, weight decay of 0.0005 and momentum of 0.9 。训练期间使用标准的数据扩大方法:随机裁剪、旋转、变换颜色(hue)、变换饱和度(saturation), 变换曝光度(exposure shifts)。在训练时,把整个网络在更大的448*448分辨率上Fine Turnning 10个 epoches,初始学习率设置为0.001,这种网络达到达到76.5%top-1精确度,93.3%top-5精确度。

    3.3.3 Training for detection

    网络去掉了最后一个卷积层,而加上了三个3*3卷积层,每个卷积层有1024个Filters,每个卷积层紧接着一个1*1卷积层。对于VOC数据,网络预测出每个网格单元预测五个Bounding Boxes,每个Bounding Boxes预测5个坐标和20类,所以一共125个Filters,增加了Passthough层来获取前面层的细粒度信息,网络训练了160epoches,初始学习率0.001,数据扩大方法相同,对COCO与VOC数据集的训练对策相同。

    四、YOLOv3

    论文地址:https://pjreddie.com/media/files/papers/YOLOv3.pdf 

    网络结构

    这里盗了张图,这张图很好的总结了YOLOv3的结构,让我们对YOLO有更加直观的理解。

    DBL: 代码中的Darknetconv2d_BN_Leaky,是YOLOv3的基本组件,就是卷积+BN+Leaky relu。
    resn:n代表数字,有res1,res2, … ,res8等等,表示这个res_block里含有多少个res_unit。不懂resnet请戳这儿
    concat:张量拼接;将darknet中间层和后面的某一层的上采样进行拼接。拼接的操作和残差层add的操作是不一样的,拼接会扩充张量的维度,而add只是直接相加不会导致张量维度的改变。

    Backbone:darknet-53

    为了达到更好的分类效果,作者自己设计训练了darknet-53,在ImageNet数据集上实验发现这个darknet-53,的确很强,相对于ResNet-152和ResNet-101,darknet-53不仅在分类精度上差不多,计算速度还比ResNet-152和ResNet-101强多了,网络层数也比他们少,测试结果如图所示。

    darknet-53的网络结构如下图所示。YOLOv3使用了darknet-53的前面的52层(没有全连接层),YOLOv3这个网络是一个全卷积网络,大量使用残差的跳层连接,并且为了降低池化带来的梯度负面效果,作者直接摒弃了POOLing,用conv的stride来实现降采样。在这个网络结构中,使用的是步长为2的卷积来进行降采样。

    为了加强算法对小目标检测的精确度,YOLOv3中采用类似FPN的upsample和融合做法(最后融合了3个scale,其他两个scale的大小分别是26×26和52×52),在多个scale的feature map上做检测。

    作者在3条预测支路采用的也是全卷积的结构,其中最后一个卷积层的卷积核个数是255,是针对COCO数据集的80类:3*(80+4+1)=255,3表示一个grid cell包含3个bounding box,4表示框的4个坐标信息,1表示objectness score。

    output 

    所谓的多尺度就是来自这3条预测之路,y1,y2和y3的深度都是255,边长的规律是13:26:52。YOLOv3设定的是每个网格单元预测3个box,所以每个box需要有(x, y, w, h, confidence)五个基本参数,然后还要有80个类别的概率。所以3×(5 + 80) = 255,这个255就是这么来的。

    下面我们具体看看y1,y2,y3是如何而来的。
    网络中作者进行了三次检测,分别是在32倍降采样,16倍降采样,8倍降采样时进行检测,这样在多尺度的feature map上检测跟SSD有点像。在网络中使用up-sample(上采样)的原因:网络越深的特征表达效果越好,比如在进行16倍降采样检测,如果直接使用第四次下采样的特征来检测,这样就使用了浅层特征,这样效果一般并不好。如果想使用32倍降采样后的特征,但深层特征的大小太小,因此YOLOv3使用了步长为2的up-sample(上采样),把32倍降采样得到的feature map的大小提升一倍,也就成了16倍降采样后的维度。同理8倍采样也是对16倍降采样的特征进行步长为2的上采样,这样就可以使用深层特征进行detection。

    作者通过上采样将深层特征提取,其维度是与将要融合的特征层维度相同的(channel不同)。如下图所示,85层将13×13×256的特征上采样得到26×26×256,再将其与61层的特征拼接起来得到26×26×768。为了得到channel255,还需要进行一系列的3×3,1×1卷积操作,这样既可以提高非线性程度增加泛化性能提高网络精度,又能减少参数提高实时性。52×52×255的特征也是类似的过程。

     

    Bounding Box


    YOLOv3的Bounding Box由YOLOv2又做出了更好的改进。在YOLOv2和YOLOv3中,都采用了对图像中的object采用k-means聚类。feature map中的每一个cell都会预测3个边界框(bounding box) ,每个bounding box都会预测三个东西:(1)每个框的位置(4个值,中心坐标tx和ty,框的高度bh和宽度bw),(2)一个objectness prediction ,(3)N个类别,coco数据集80类,voc20类。

    三次检测,每次对应的感受野不同,32倍降采样的感受野最大,适合检测大的目标,所以在输入为416×416时,每个cell的三个anchor box为(116 ,90); (156 ,198); (373 ,326)。16倍适合一般大小的物体,anchor box为(30,61); (62,45); (59,119)。8倍的感受野最小,适合检测小目标,因此anchor box为(10,13); (16,30); (33,23)。所以当输入为416×416时,实际总共有(52×52+26×26+13×13)×3=10647个proposal box。

     感受一下9种先验框的尺寸,下图中蓝色框为聚类得到的先验框。黄色框式ground truth,红框是对象中心点所在的网格。

    这里注意bounding box 与anchor box的区别:
    Bounding box它输出的是框的位置(中心坐标与宽高),confidence以及N个类别。anchor box只是一个尺度即只有宽高。

    LOSS Function

    YOLOv3重要改变之一:No more softmaxing the classes。YOLOv3现在对图像中检测到的对象执行多标签分类。

    logistic回归用于对anchor包围的部分进行一个目标性评分(objectness score),即这块位置是目标的可能性有多大。这一步是在predict之前进行的,可以去掉不必要anchor,可以减少计算量。

    如果模板框不是最佳的即使它超过我们设定的阈值,我们还是不会对它进行predict。不同于Faster R-CNN的是,YOLOv3只会对1个prior进行操作,也就是那个最佳prior。而logistic回归就是用来从9个anchor priors中找到objectness score(目标存在可能性得分)最高的那一个。logistic回归就是用曲线对prior相对于 objectness score映射关系的线性建模。

    	lxy, lwh, lcls, lconf = ft([0]), ft([0]), ft([0]), ft([0])
        txy, twh, tcls, indices = build_targets(model, targets)#在13 26 52维度中找到大于iou阈值最适合的anchor box 作为targets
        #txy[维度(0:2),(x,y)] twh[维度(0:2),(w,h)] indices=[0,anchor索引,gi,gj]
    
        # Define criteria
        MSE = nn.MSELoss()
        CE = nn.CrossEntropyLoss()
        BCE = nn.BCEWithLogitsLoss()
    
        # Compute losses
        h = model.hyp  # hyperparameters
        bs = p[0].shape[0]  # batch size
        k = h['k'] * bs  # loss gain
        for i, pi0 in enumerate(p):  # layer i predictions, i
            b, a, gj, gi = indices[i]  # image, anchor, gridx, gridy
            tconf = torch.zeros_like(pi0[..., 0])  # conf
    
    
            # Compute losses
            if len(b):  # number of targets
                pi = pi0[b, a, gj, gi]  # predictions closest to anchors 找到p中与targets对应的数据lxy
                tconf[b, a, gj, gi] = 1  # conf
                # pi[..., 2:4] = torch.sigmoid(pi[..., 2:4])  # wh power loss (uncomment)
    
                lxy += (k * h['xy']) * MSE(torch.sigmoid(pi[..., 0:2]),txy[i])  # xy loss
                lwh += (k * h['wh']) * MSE(pi[..., 2:4], twh[i])  # wh yolo loss
                lcls += (k * h['cls']) * CE(pi[..., 5:], tcls[i])  # class_conf loss
    
            # pos_weight = ft([gp[i] / min(gp) * 4.])
            # BCE = nn.BCEWithLogitsLoss(pos_weight=pos_weight)
            lconf += (k * h['conf']) * BCE(pi0[..., 4], tconf)  # obj_conf loss
        loss = lxy + lwh + lconf + lcls
    
    

    以上是一段pytorch框架描述的YOLOv3的loss_function代码。忽略恒定系数不看,以下我想着重说几点:

    • 首先,YOLOv3要先build target,因为我们知道正样本是label与anchor box iou大于0.5的组成,所以我们根据label找到对应的anchor box。如何找出label中存放着[image,class,x(归一化),y,w(归一化),h],我们可以用这些坐标在对应13×13 Or 26×26 or 52×52的map中分别于9个anchor算出iou,找到符合要求的,把索引与位置记录好。用记录好的索引位置找到predict的anchor box。
    • xywh是由均方差来计算loss的,其中预测的xy进行sigmoid来与lable xy求差,label xy是grid cell中心点坐标,其值在0-1之间,所以predict出的xy要sigmoid。
    • 分类用的多类别交叉熵,置信度用的二分类交叉熵。只有正样本才参与class,xywh的loss计算,负样本只参与置信度loss。

     

    五、YOLOv4

    YOLOv4: Optimal Speed and Accuracy of Object Detection

    论文:https://arxiv.org/abs/2004.10934

    代码:https://github.com/AlexeyAB/darknet

    YOLOv4其实是一个结合了大量前人研究技术,加以组合并进行适当创新的算法,实现了速度和精度的完美平衡。可以说有许多技巧可以提高卷积神经网络(CNN)的准确性,但是某些技巧仅适合在某些模型上运行,或者仅在某些问题上运行,或者仅在小型数据集上运行;我们来码一码这篇文章里作者都用了哪些调优手段:加权残差连接(WRC),跨阶段部分连接(CSP),跨小批量标准化(CmBN),自对抗训练(SAT),Mish激活,马赛克数据增强,CmBN,DropBlock正则化,CIoU Loss等等。经过一系列的堆料,终于实现了目前最优的实验结果:43.5%的AP(在Tesla V100上,MS COCO数据集的实时速度约为65FPS)。

     

    5.1、YOLOv4框架原理


    先直接上YOLOv4的整体原理图(来源网络)如下:

    5.1.1  CSPDarknet53

    我们前面知道在YOLOv3中,特征提取网络使用的是Darknet53,而在YOLOv4中,对Darknet53做了一点改进,借鉴了CSPNet,CSPNet全称是Cross Stage Partial Networks,也就是跨阶段局部网络。CSPNet解决了其他大型卷积神经网络框架Backbone中网络优化的梯度信息重复问题,将梯度的变化从头到尾地集成到特征图中,因此减少了模型的参数量和FLOPS数值,既保证了推理速度和准确率,又减小了模型尺寸。如下图:

    CSPNet实际上是基于Densnet的思想,复制基础层的特征映射图,通过dense block发送副本到下一个阶段,从而将基础层的特征映射图分离出来。这样可以有效缓解梯度消失问题(通过非常深的网络很难去反推丢失信号) ,支持特征传播,鼓励网络重用特征,从而减少网络参数数量。CSPNet思想可以和ResNet、ResNeXt和DenseNet结合,目前主要有CSPResNext50 和CSPDarknet53两种改造Backbone网络。

    考虑到几方面的平衡:输入网络分辨率/卷积层数量/参数数量/输出维度。一个模型的分类效果好不见得其检测效果就好,想要检测效果好需要以下几点:

    • 更大的网络输入分辨率——用于检测小目标
    • 更深的网络层——能够覆盖更大面积的感受野
    • 更多的参数——更好的检测同一图像内不同size的目标

    这样最终的CSPDarknet53结构就如下图:

    CSPNet论文: https://arxiv.org/pdf/1911.11929v1.pdf

    为了增大感受野,作者还使用了SPP-block,使用PANet代替FPN进行参数聚合以适用于不同level的目标检测。

     5.1.2 SPP结构

    SPP-Net结构我们之前也有学过,SPP-Net全称Spatial Pyramid Pooling Networks,当时主要是用来解决不同尺寸的特征图如何进入全连接层的,直接看下图,下图中对任意尺寸的特征图直接进行固定尺寸的池化,来得到固定数量的特征。

    如上图,以3个尺寸的池化为例,对特征图进行一个最大值池化,即一张特征图得取其最大值,得到1*d(d是特征图的维度)个特征;对特征图进行网格划分为2x2的网格,然后对每个网格进行最大值池化,那么得到4*d个特征;同样,对特征图进行网格划分为4x4个网格,对每个网格进行最大值池化,得到16*d个特征。 接着将每个池化得到的特征合起来即得到固定长度的特征个数(特征图的维度是固定的),接着就可以输入到全连接层中进行训练网络了。用到这里是为了增加感受野。

    5.1.3 PAN结构

    YOLOv4使用PANet(Path Aggregation Network)代替FPN进行参数聚合以适用于不同level的目标检测, PANet论文中融合的时候使用的方法是AdditionYOLOv4算法将融合的方法由加法改为Concatenation。如下图:

    5.2 BackBone训练策略

    这里我们主要从数据增强,DropBlock正则化,类标签平滑方面来学习下BackBone训练策略。

    5.2.1 数据增强
    1、CutMix

    YOLOv4选择用CutMix的增强方式,CutMix的处理方式也比较简单,同样也是对一对图片做操作,简单讲就是随机生成一个裁剪框Box,裁剪掉A图的相应位置,然后用B图片相应位置的ROI放到A图中被裁剪的区域形成新的样本,ground truth标签会根据patch的面积按比例进行调整,比如0.6像狗,0.4像猫,计算损失时同样采用加权求和的方式进行求解。这里借CutMix的地方顺带说下几种类似的增强方式:

    上图是CutMix论文中作者对几种增强方式做的对比,结果显而易见,CutMix的增强方式在三个数据集上的表现都是最优的。其中Mixup是直接求和两张图,如同附身,鬼影一样,模型很难学到准确的特征图响应分布。Cutout是直接去除图像的一个区域,这迫使模型在进行分类时不能对特定的特征过于自信。然而,图像的一部分充满了无用的信息,这是一种浪费。在CutMix中,将图像的一部分剪切并粘贴到另一个图像上,使得模型更容易区分异类。

    CutMix论文: https://arxiv.org/pdf/1905.04899v2.pdf

    2、Mosaic

    Yolov4的Mosaic数据增强是参考CutMix数据增强,理论上类似。区别在于Mosaic是一种将4张训练图像合并成一张进行训练的数据增强方法(而不是CutMix中的2张)。这增强了对正常背景(context)之外的对象的检测,丰富检测物体的背景。此外,每个小批包含一个大的变化图像(4倍),因此,减少了估计均值和方差的时需要大mini-batch的要求,降低了训练成本。如下图:

     5.2.2 DropBlock正则化

    正则化技术有助于避免数据科学专业人员面临的最常见的问题,即过拟合。对于正则化,已经提出了几种方法,如L1和L2正则化、Dropout、Early Stopping和数据增强。这里YOLOv4用了DropBlock正则化的方法。

    DropBlock方法的引入是为了克服Dropout随机丢弃特征的主要缺点,Dropout被证明是全连接网络的有效策略,但在特征空间相关的卷积层中效果不佳。DropBlock技术在称为块的相邻相关区域中丢弃特征。这样既可以实现生成更简单模型的目的,又可以在每次训练迭代中引入学习部分网络权值的概念,对权值矩阵进行补偿,从而减少过拟合。如下图:

    DropBlock论文中作者最终在ImageNet分类任务上,使用Resnet-50结构,将精度提升1.6%个点,在COCO检测任务上,精度提升1.6%个点。

    DropBlock论文: https://arxiv.org/pdf/1810.12890.pdf

    5.2.3 DropBlock正则化

    对于分类问题,特别是多分类问题,常常把向量转换成one-hot-vector,而one-hot带来的问题: 对于损失函数,我们需要用预测概率去拟合真实概率,而拟合one-hot的真实概率函数会带来两个问题:

    • 无法保证模型的泛化能力,容易造成过拟合;
    • 全概率和0概率鼓励所属类别和其他类别之间的差距尽可能加大,而由梯度有界可知,这种情况很难适应。会造成模型过于相信预测的类别。

    对预测有100%的信心可能表明模型是在记忆数据,而不是在学习。标签平滑调整预测的目标上限为一个较低的值,比如0.9。它将使用这个值而不是1.0来计算损失。这个概念缓解了过度拟合。说白了,这个平滑就是一定程度缩小label中min和max的差距,label平滑可以减小过拟合。所以,适当调整label,让两端的极值往中间凑凑,可以增加泛化性能。

    5.3 BackBone推理策略

    5.3.1 Mish激活函数

    对激活函数的研究一直没有停止过,ReLU还是统治着深度学习的激活函数,不过,这种情况有可能会被Mish改变。Mish是另一个与ReLUSwish非常相似的激活函数。正如论文所宣称的那样,Mish可以在不同数据集的许多深度网络中胜过它们。公式如下:

                                                                                                        \large y= x\ast tanh(ln(1+e^{x})

    Mish是一个平滑的曲线,平滑的激活函数允许更好的信息深入神经网络,从而得到更好的准确性和泛化;在负值的时候并不是完全截断,允许比较小的负梯度流入。实验中,随着层深的增加,ReLU激活函数精度迅速下降,而Mish激活函数在训练稳定性、平均准确率(1%-2.8%)、峰值准确率(1.2% - 3.6%)等方面都有全面的提高。如下图:

    Mish论文: https://arxiv.org/pdf/1908.08681.pdf

    5.3.2 MiWRC策略

    MiWRC是Multi-input weighted residual connections的简称, 在BiFPN中,提出了用MiWRC来执行标尺度级重加权,添加不同尺度的特征映射。我们已经讨论了FPN和PAN作为例子。下面的图(d)显示了另一种被称为BiFPN的neck设计,根据BiFPN的论文,该设计具有更好的准确性和效率权衡。
     

    上图中 (a)FPN引入自顶向下的路径,将多尺度特征从3级融合到7级(P3-P7);(b)PANET在FPN之上增加一个额外的自下而上的路径;(c)NAS-FPN使用神经网络搜索找到一个不规则的特征拓扑网络,然后重复应用同一块拓扑结构;(d)是这里的BiFPN,具有更好的准确性和效率权衡。将该neck放到整个整个网络的连接中如下图:

    上图采用EfficientNet作为骨干网络,BiFPN作为特征网络,共享class/box预测网络。 基于不同的资源约束,BiFPN层和类/盒网层都被重复多次。

    BiFPN论文: https://arxiv.org/pdf/1911.09070.pdf

    5.4 检测头训练策略

    5.4.1 CIoU-loss


    损失函数给出了如何调整权重以降低loss。所以在我们做出错误预测的情况下,我们期望它能给我们指明前进的方向。但如果使用IoU,考虑两个预测都不与ground truth重叠,那么IoU损失函数不能告诉哪一个是更好的,或者哪个更接近ground truth。这里顺带看下常用的几种loss的形式,如下:

    1、经典IoU loss:

    IoU算法是使用最广泛的算法,大部分的检测算法都是使用的这个算法。

    可以看到IOU的loss其实很简单,主要是交集/并集,但其实也存在两个问题。 

    问题1:即状态1的情况,当预测框和目标框不相交时,IOU=0,无法反应两个框距离的远近,此时损失函数不可导,IOU_Loss无法优化两个框不相交的情况。

    问题2:即状态2和状态3的情况,当两个预测框大小相同,两个IOU也相同,IOU_Loss无法区分两者相交情况的不同。

    因此2019年出现了GIOU_Loss来进行改进。

    2、GIoU:Generalized IoU

    GIoU考虑到,当检测框和真实框没有出现重叠的时候IoU的loss都是一样的,因此GIoU就加入了C检测框(C检测框是包含了检测框和真实框的最小矩形框),这样就可以解决检测框和真实框没有重叠的问题。其中,C是指能包含predict box和Ground Truth box的最小box。

    可以看到上图GIOU_Loss中,增加了相交尺度的衡量方式,缓解了单纯IOU_Loss时的尴尬。但为什么仅仅说缓解呢?因为还存在一种不足

    问题:状态1、2、3都是预测框在目标框内部且预测框大小一致的情况,这时预测框和目标框的差集都是相同的,因此这三种状态的GIOU值也都是相同的,这时GIOU退化成了IOU,无法区分相对位置关系。
    基于这个问题,2020年的AAAI又提出了DIOU_Loss

    3、DIoU:Distance IoU

    好的目标框回归函数应该考虑三个重要几何因素:重叠面积、中心点距离,长宽比。针对IOU和GIOU存在的问题,作者从两个方面进行考虑

    (1):如何最小化预测框和目标框之间的归一化距离?

    (2):如何在预测框和目标框重叠时,回归的更准确?

    针对第一个问题,提出了DIOU_Loss(Distance_IOU_Loss)

    DIOU_Loss考虑了重叠面积中心点距离,当目标框包裹预测框的时候,直接度量2个框的距离,因此DIOU_Loss收敛的更快。

    但就像前面好的目标框回归函数所说的,没有考虑到长宽比。

    比如上面三种情况,目标框包裹预测框,本来DIOU_Loss可以起作用。但预测框的中心点的位置都是一样的,因此按照DIOU_Loss的计算公式,三者的值都是相同的。

    针对这个问题,又提出了CIOU_Loss,不对不说,科学总是在解决问题中,不断进步!!

    4、CIOU_Loss

    CIOU_Loss和DIOU_Loss前面的公式都是一样的,不过在此基础上还增加了一个影响因子,将预测框和目标框的长宽比都考虑了进去。

     其中v是衡量长宽比一致性的参数,我们也可以定义为:

    这样CIOU_Loss就将目标框回归函数应该考虑三个重要几何因素:重叠面积、中心点距离,长宽比全都考虑进去了。

    再来综合的看下各个Loss函数的不同点:

    IOU_Loss:主要考虑检测框和目标框重叠面积。

    GIOU_Loss:在IOU的基础上,解决边界框不重合时的问题。

    DIOU_Loss:在IOU和GIOU的基础上,考虑边界框中心点距离的信息。

    CIOU_Loss:在DIOU的基础上,考虑边界框宽高比的尺度信息。

    YOLOv4中采用了CIOU_Loss的回归方式,使得预测框回归的速度和精度更高一些。

    5.4.2 CmBN策略

    BN就是仅仅利用当前迭代时刻信息进行norm,而CBN在计算当前时刻统计量时候会考虑前k个时刻统计量,从而实现扩大batch size操作。同时作者指出CBN操作不会引入比较大的内存开销,训练速度不会影响很多,但是训练时候会慢一些,比GN还慢。

    CmBN是CBN的改进版本,其把大batch内部的4个mini batch当做一个整体,对外隔离。CBN在第t时刻,也会考虑前3个时刻的统计量进行汇合,而CmBN操作不会,不再滑动cross,其仅仅在mini batch内部进行汇合操作,保持BN一个batch更新一次可训练参数。

    BN:无论每个batch被分割为多少个mini batch,其算法就是在每个mini batch前向传播后统计当前的BN数据(即每个神经元的期望和方差)并进行Nomalization,BN数据与其他mini batch的数据无关。CBN:每次iteration中的BN数据是其之前n次数据和当前数据的和(对非当前batch统计的数据进行了补偿再参与计算),用该累加值对当前的batch进行Nomalization。好处在于每个batch可以设置较小的size。CmBN:只在每个Batch内部使用CBN的方法,个人理解如果每个Batch被分割为一个mini batch,则其效果与BN一致;若分割为多个mini batch,则与CBN类似,只是把mini batch当作batch进行计算,其区别在于权重更新时间点不同,同一个batch内权重参数一样,因此计算不需要进行补偿。

    5.4.3 自对抗训练(SAT)

    SAT为一种新型数据增强方式。在第一阶段,神经网络改变原始图像而不是网络权值。通过这种方式,神经网络对其自身进行一种对抗式的攻击,改变原始图像,制造图像上没有目标的假象。在第二阶段,训练神经网络对修改后的图像进行正常的目标检测。

    Self-Adversarial Training是在一定程度上抵抗对抗攻击的数据增强技术。CNN计算出Loss, 然后通过反向传播改变图片信息,形成图片上没有目标的假象,然后对修改后的图像进行正常的目标检测。需要注意的是在SAT的反向传播的过程中,是不需要改变网络权值的。 使用对抗生成可以改善学习的决策边界中的薄弱环节,提高模型的鲁棒性。因此这种数据增强方式被越来越多的对象检测框架运用。

    5.4.4 消除网格敏感度

    对于\large b_{x}=c_{x}\large b_{x}=c_{x}+1的情况,我们需要\large t_{x}分别具有很大的负值和正值。但我们可以将\large \sigma与一个比例因子(>1.0)相乘,从而更轻松地实现这一目标

    5.4.5 余弦模拟退火

    余弦调度会根据一个余弦函数来调整学习率。首先,较大的学习率会以较慢的速度减小。然后在中途时,学习的减小速度会变快,最后学习率的减小速度又会变得很慢。

    这张图展示了学习率衰减的方式(下图中还应用了学习率预热)及其对mAP的影响。可能看起来并不明显,这种新的调度方法的进展更为稳定,而不是在停滞一段时间后又取得进展。

    余弦模拟退火论文: https://arxiv.org/pdf/1608.03983.pdf 

    5.5 检测头推理策略

    5.5.1 SAM模块

    注意力机制在DL设计中被广泛采用。在SAM中,最大值池化和平均池化分别用于输入feature map,创建两组feature map。结果被输入到一个卷积层,接着是一个Sigmoid函数来创建空间注意力。

     将空间注意掩模应用于输入特征,输出精细的特征图。

     在YOLOv4中,使用修改后的SAM而不应用最大值池化和平均池化。

    YOLOv4中,FPN概念逐渐被实现/替换为经过修改的SPPPANPAN

    5.5.2 DIoU-NMS 

    NMS过滤掉预测相同对象的其他边界框,并保留具有最高可信度的边界框。

     DIoU(前面讨论过的) 被用作非最大值抑制(NMS)的一个因素。该方法在抑制冗余框的同时,采用IoU和两个边界盒中心点之间的距离。这使得它在有遮挡的情况下更加健壮。

    六、YOLOv5

    YOLOv4出现之后不久,YOLOv5横空出世。YOLOv5在YOLOv4算法的基础上做了进一步的改进,检测性能得到进一步的提升。虽然YOLOv5算法并没有与YOLOv4算法进行性能比较与分析,但是YOLOv5在COCO数据集上面的测试效果还是挺不错的。大家对YOLOv5算法的创新性半信半疑,有的人对其持肯定态度,有的人对其持否定态度。在我看来,YOLOv5检测算法中还是存在很多可以学习的地方,虽然这些改进思路看来比较简单或者创新点不足,但是它们确定可以提升检测算法的性能。其实工业界往往更喜欢使用这些方法,而不是利用一个超级复杂的算法来获得较高的检测精度。

    6.1 YOLOv5算法简介

    YOLOv5是一种单阶段目标检测算法,该算法在YOLOv4的基础上添加了一些新的改进思路,使其速度与精度都得到了极大的性能提升。主要的改进思路如下所示:

    • 输入端:在模型训练阶段,提出了一些改进思路,主要包括Mosaic数据增强、自适应锚框计算、自适应图片缩放;
    • 基准网络:融合其它检测算法中的一些新思路,主要包括:Focus结构与CSP结构;
    • Neck网络:目标检测网络在BackBone与最后的Head输出层之间往往会插入一些层,Yolov5中添加了FPN+PAN结构;
    • Head输出层:输出层的锚框机制与YOLOv4相同,主要改进的是训练时的损失函数GIOU_Loss,以及预测框筛选的DIOU_nms。

    6.2 YOLOv5算法详解

    6.2.1 YOLOv5网络架构

    上图展示了YOLOv5目标检测算法的整体框图。对于一个目标检测算法而言,我们通常可以将其划分为4个通用的模块,具体包括:输入端、基准网络、Neck网络与Head输出端,对应于上图中的4个红色模块。YOLOv5算法具有4个版本,具体包括:YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x四种,本文重点讲解YOLOv5s,其它的版本都在该版本的基础上对网络进行加深与加宽。

    • 输入端-输入端表示输入的图片。该网络的输入图像大小为608*608,该阶段通常包含一个图像预处理阶段,即将输入图像缩放到网络的输入大小,并进行归一化等操作。在网络训练阶段,YOLOv5使用Mosaic数据增强操作提升模型的训练速度和网络的精度;并提出了一种自适应锚框计算与自适应图片缩放方法。
    • 基准网络-基准网络通常是一些性能优异的分类器种的网络,该模块用来提取一些通用的特征表示。YOLOv5中不仅使用了CSPDarknet53结构,而且使用了Focus结构作为基准网络。
    • Neck网络-Neck网络通常位于基准网络和头网络的中间位置,利用它可以进一步提升特征的多样性及鲁棒性。虽然YOLOv5同样用到了SPP模块、FPN+PAN模块,但是实现的细节有些不同。
    • Head输出端-Head用来完成目标检测结果的输出。针对不同的检测算法,输出端的分支个数不尽相同,通常包含一个分类分支和一个回归分支。YOLOv4利用GIOU_Loss来代替Smooth L1 Loss函数,从而进一步提升算法的检测精度。

    6.2.2 YOLOv5基础组件

    • CBL-CBL模块由Conv+BN+Leaky_relu激活函数组成,如上图中的模块1所示。
    • Res unit-借鉴ResNet网络中的残差结构,用来构建深层网络,CBM是残差模块中的子模块,如上图中的模块2所示。
    • CSP1_X-借鉴CSPNet网络结构,该模块由CBL模块、Res unint模块以及卷积层、Concate组成而成,如上图中的模块3所示。
    • CSP2_X-借鉴CSPNet网络结构,该模块由卷积层和X个Res unint模块Concate组成而成,如上图中的模块4所示。
    • Focus-如上图中的模块5所示,Focus结构首先将多个slice结果Concat起来,然后将其送入CBL模块中。
    • SPP-采用1×1、5×5、9×9和13×13的最大池化方式,进行多尺度特征融合,如上图中的模块6所示。

    6.2.3  输入端细节详解

    • Mosaic数据增强-YOLOv5中在训练模型阶段仍然使用了Mosaic数据增强方法,该算法是在CutMix数据增强方法的基础上改进而来的。CutMix仅仅利用了两张图片进行拼接,而Mosaic数据增强方法则采用了4张图片,并且按照随机缩放、随机裁剪和随机排布的方式进行拼接而成,具体的效果如下图所示。这种增强方法可以将几张图片组合成一张,这样不仅可以丰富数据集的同时极大的提升网络的训练速度,而且可以降低模型的内存需求。

    • 自适应锚框计算-在YOLOv5系列算法中,针对不同的数据集,都需要设定特定长宽的锚点框。在网络训练阶段,模型在初始锚点框的基础上输出对应的预测框,计算其与GT框之间的差距,并执行反向更新操作,从而更新整个网络的参数,因此设定初始锚点框也是比较关键的一环。在YOLOv3和YOLOv4检测算法中,训练不同的数据集时,都是通过单独的程序运行来获得初始锚点框。YOLOv5中将此功能嵌入到代码中,每次训练时,根据数据集的名称自适应的计算出最佳的锚点框,用户可以根据自己的需求将功能关闭或者打开,具体的指令为parser.add_argument(’–noautoanchor’, action=‘store_ true’, help=‘disable autoanchor check’),如果需要打开,只需要在训练代码时增加–noautoanch or选项即可。
    • 自适应图片缩放-针对不同的目标检测算法而言,我们通常需要执行图片缩放操作,即将原始的输入图片缩放到一个固定的尺寸,再将其送入检测网络中。YOLO系列算法中常用的尺寸包括416*416,608 *608等尺寸。原始的缩放方法存在着一些问题,由于在实际的使用中的很多图片的长宽比不同,因此缩放填充之后,两端的黑边大小都不相同,然而如果填充的过多,则会存在大量的信息冗余,从而影响整个算法的推理速度。为了进一步提升YOLOv5算法的推理速度,该算法提出一种方法能够自适应的添加最少的黑边到缩放之后的图片中。

    6.2.4  基准网络细节详解

    • Focus结构-该结构的主要思想是通过slice操作来对输入图片进行裁剪。如下图所示,原始输入图片大小为608*608*3,经过Slice与Concat操作之后输出一个304*304*12的特征映射;接着经过一个通道个数为32的Conv层(该通道个数仅仅针对的是YOLOv5s结构,其它结构会有相应的变化),输出一个304*304*32大小的特征映射。

    • CSP结构-YOLOv4网络结构中,借鉴了CSPNet的设计思路,仅仅在主干网络中设计了CSP结构。而YOLOv5中设计了两种CSP结构,以YOLOv5s网络为例,CSP1_X结构应用于Backbone主干网络中,另一种CSP2_X结构则应用于Neck网络中。CSP1_X与CSP2_X模块的实现细节如3.1所示。

    6.2.5 Neck网络细节详解

    • FPN+PAN-YOLOv5的Neck网络仍然使用了FPN+PAN结构,但是在它的基础上做了一些改进操作,YOLOv4的Neck结构中,采用的都是普通的卷积操作。而YOLOv5的Neck网络中,采用借鉴CSPnet设计的CSP2结构,从而加强网络特征融合能力。下图展示了YOLOv4与YOLOv5的Neck网络的具体细节,通过比较我们可以发现:(1)灰色区域表示第1个不同点,YOLOv5不仅利用CSP2_\1结构代替部分CBL模块,而且去掉了下方的CBL模块;(2)绿色区域表示第2个不同点,YOLOv5不仅将Concat操作之后的CBL模块更换为CSP2_1模块,而且更换了另外一个CBL模块的位置;(3)蓝色区域表示第3个不同点,YOLOv5中将原始的CBL模块更换为CSP2_1模块。

     

    参考文献:

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

    https://blog.csdn.net/x454045816/article/details/109759989

    https://blog.csdn.net/x454045816/article/details/109759989

    https://zhuanlan.zhihu.com/p/172121380

    https://zhuanlan.zhihu.com/p/143747206?from=timeline

    https://blog.csdn.net/App_12062011/article/details/77554288

    https://zhuanlan.zhihu.com/p/161083602

    展开全文
  • YoloV2学习小总结

    2022-02-26 17:53:37
    首先,yolov2比yolov1改进的地方有许多,使得yolov2在性能指标上有很大的改进。 速度方面更快 召回率更高 下图是yolov2采用各种改进方法的mAP指标。 相比于yolov1的改进 1. Better 1. Batch Normalization ...
  • 目标检测:YOLOV2

    千次阅读 2022-04-25 10:22:43
    1)加入了BN层:YOLOv2的第二个改进是在网络中加入了Batch Normalization,使用Batch Normalization对网络进行优化,让网络提高了收敛性,同时还消除了对其他形式的正则化(regularization)的依赖。有了BN便可以去掉...
  • YOLO系列:YOLOv1,YOLOv2,YOLOv3,YOLOv4,YOLOv5简介

    万次阅读 多人点赞 2020-09-21 09:09:36
    YOLO系列:YOLOv1,YOLOv2,YOLOv3,YOLOv4,YOLOv5简介YOLO系列是基于深度学习的回归方法。RCNN, Fast-RCNN,Faster-RCNN是基于深度学习的分类方法。YOLO官网:https://github.com/pjreddie/darknet​github.comYOLO v...
  • 通过组合多种有效改进,将PP-YOLO在COCO2017 test-dev数据上的性能从45.9%mAP提升到了49.5%mAP,并将所得到的模型称之为PP-YOLOv2。在推理速度方面,PP-YOLOv2可以达到68.9FPS@ 输入尺寸;采用Paddle推理引擎+...
  • YOLO深度卷积神经网络已经经过原作者Joseph Redmon经过了3代4个经典版本(含YOLOv2和YOLO9000),后因为自己的研究成果被用于军事而道德不安,故放弃更新。 俄罗斯的AlexeyAB接下接力棒,完成了第4版迭代YOLOV4,并...
  • YOLOv2损失函数

    千次阅读 2022-01-09 14:46:51
    YOLOv2损失函数 第一行:负责检测物体的bbox的置信度误差:越小越好 第二行:预测框与Anchor位置误差 第三至第五行:预测框负责预测物体误差 第三行:定位误差 第四行:置信度误差 第五行:分类误差 LOSS=L...
  • 前言在前面的一篇文章中,我们详细介绍了 YOLOv1 的原理以及实现过程。这篇文章接着介绍YOLOv2 的原理以及实现,YOLOv2 的论文全名为 YOLO90
  • 史上最通俗易懂的YOLOv2讲解

    万次阅读 多人点赞 2018-12-03 20:25:14
    博主本来想自己写一篇关于YOLOv2的论文笔记的,在找资料的过程中看到这篇天秀的博客,就“据为己用”了。不得不出,很多大佬写的都太深刻了,还是转载比较舒服点~~~~~~ 本文转自目标检测|YOLOv2原理与实现(附YOLOv3)...
  • 浅谈YOLOV2与YOLOV3

    千次阅读 2019-06-24 14:54:49
    最近要做目标跟踪,经过调研发现,YOLOv3的速度与精度喜人,超过了同时代的(Faster-R-cnn、SSD、YOLOv2),达到了 art-to-state水平,但是在阅读过程中,尽管我曾经看过v1和v2但是在了解v3的时候还是有点困难,因此...
  • yolo yolov2 重点 (Top highlight)PP-YOLO evaluation metrics show improved performance over YOLOv4, the incumbent state of the art object detection model. Yet, the Baidu authors write: PP-YOLO评估指标...
  • 目标检测yolov2和yolov3的权重文件,并且有基于voc数据集训练好的权重。
  • 目标检测|YOLOv2原理与实现(附YOLOv3)

    千次阅读 2018-06-05 15:15:17
    转发:...这篇文章接着介绍YOLOv2的原理以及实现,YOLOv2的论文全名为YOLO9000: Better, Faster, Stronger,它斩获了CVPR 2017 Best Paper Honorable Mention。在这篇文章中,作者首先在Y...
  • YOLOv2相比于yolov1的改进

    千次阅读 2019-08-30 17:36:46
    1.Batch Normalization ...在YOLOv2中,每个卷积层后面都添加了Batch Normalization层,并且不再使用droput。使用Batch Normalization后,YOLOv2的mAP提升了2.4%。 2.High Resolution Classifie...
  • 3、tiny yolov2 训练

    千次阅读 2019-12-18 12:57:32
    1、上官网下载yolov2-tiny.weights,或者先不下载,在虚拟机下下载 https://pjreddie.com/darknet/yolo/ https://pjreddie.com/media/files/yolov2-tiny.weights 2、在虚拟几下安装darknet git clone ...
  • Yolov2就是YOLO9000,之所以命名YOLO9000是因为yolov2相对v1版本,在继续保持处理速度的基础上,从预测更准确(Better),速度更快(Faster),识别对象更多(Stronger)这三个方面进行了改进。其中识别更多对象也...
  • Caffe(12)--实现YOLOv2目标检测

    万次阅读 2018-10-11 14:13:24
    DarkNet转Caffe中有很多潜在的问题,在YOLOv1、v2、v3几个网络中有一些特殊的层。要在Caffe中跑YOLO,就得在Caffe中源码实现这些层。...YOLOv2 route层 用concat层替换 reorg层 源码实现 ...
  • 兴趣尝试,训练一下自己的数据集做图像识别。 darknet网络下载 下载地址:https://pjreddie.com/darknet/yolov2/ ..../darknet detector test cfg/voc.data cfg/yolov2-tiny-voc.cfg yolov2-tiny-voc.weights da

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 58,078
精华内容 23,231
关键字:

yolov2