yolov3_yolov3 手机 - CSDN
精华内容
参与话题
  • 购课后可加入白勇老师课程学习交流QQ群:957519975除本课程《YOLOv3目标检测实战:训练自己的数据集》外,本人推出了有关YOLOv3目标检测的系列课程,请持续关注该系列的其它课程视频,包括:《YOLOv3目标检测实战:...
  • yolo系列之yolo v3【深度解析】

    万次阅读 多人点赞 2018-09-12 16:24:48
    看过yolov3论文的应该都知道,这篇论文写得很随意,很多亮点都被作者都是草草描述。很多骚年入手yolo算法都是从v3才开始,这是不可能掌握yolo精髓的,因为v3很多东西是保留v2甚至v1的东西,而且v3的论文写得很随心。...

    版权申明:转载和引用图片,都必须经过书面同意。获得留言同意即可
    本文使用图片多为本人所画,需要高清图片可以留言联系我,先点赞后取图
    这篇博文比较推荐的yolo v3代码是qwe的keras版本,复现比较容易,代码相对来说比较容易理解。同学们可以结合代码和博文共同理解v3的精髓。
    github地址:https://github.com/qqwweee/keras-yolo3


    前言

    前言就是唠唠嗑,想直接看干货可以跳过前言,直接看Yolo v3。
    yolo_v3是我最近一段时间主攻的算法,写下博客,以作分享交流。
    看过yolov3论文的应该都知道,这篇论文写得很随意,很多亮点都被作者都是草草描述。很多骚年入手yolo算法都是从v3才开始,这是不可能掌握yolo精髓的,因为v3很多东西是保留v2甚至v1的东西,而且v3的论文写得很随心。想深入了解yolo_v3算法,是有必要先了解v1和v2的。以下是我关于v1和v2算法解析所写的文章:
    v1算法解析:《yolo系列之yolo v1
    v2算法解析:《yolo系列之yolo v2
    yolo_v3作为yolo系列目前最新的算法,对之前的算法既有保留又有改进。先分析一下yolo_v3上保留的东西:

    1. “分而治之”,从yolo_v1开始,yolo算法就是通过划分单元格来做检测,只是划分的数量不一样。
    2. 采用"leaky ReLU"作为激活函数。
    3. 端到端进行训练。一个loss function搞定训练,只需关注输入端和输出端。
    4. 从yolo_v2开始,yolo就用batch normalization作为正则化、加速收敛和避免过拟合的方法,把BN层和leaky relu层接到每一层卷积层之后。
    5. 多尺度训练。在速度和准确率之间tradeoff。想速度快点,可以牺牲准确率;想准确率高点儿,可以牺牲一点速度。

    yolo每一代的提升很大一部分决定于backbone网络的提升,从v2的darknet-19到v3的darknet-53。yolo_v3还提供替换backbone——tiny darknet。要想性能牛叉,backbone可以用Darknet-53,要想轻量高速,可以用tiny-darknet。总之,yolo就是天生“灵活”,所以特别适合作为工程算法。
    当然,yolo_v3在之前的算法上保留的点不可能只有上述几点。由于本文章主要针对yolo_v3进行剖析,不便跑题,下面切入正题。


    YOLO v3

    网上关于yolo v3算法分析的文章一大堆,但大部分看着都不爽,为什么呢?因为他们没有这个玩意儿:

    图1. yolo_v3结构图
    yolo系列里面,作者只在v1的论文里给出了结构图,而v2和v3的论文里都没有结构图,这使得读者对后两代yolo结构的理解变得比较难。but,对于yolo学习者来说,脑子里没有一个清晰的结构图,就别说自己懂yolo了。上图是我根据官方代码和官方论文以及模型结构可视化工具等经过好几个小时画出来的,修订过几个版本。所以,上图的准确性是可以保证的

    这里推荐的模型结构可视化工具是Netron
    netron方便好用,可以直观看到yolo_v3的实际计算结构,精细到卷积层。But,要进一步在人性化的角度分析v3的结构图,还需要结合论文和代码。对此,我是下了不少功夫。
    上图表示了yolo_v3整个yolo_body的结构,没有包括把输出解析整理成咱要的[box, class, score]。对于把输出张量包装成[box, class, score]那种形式,还需要写一些脚本,但这已经在神经网络结构之外了(我后面会详细解释这波操作)。
    为了让yolo_v3结构图更好理解,我对图1做一些补充解释:
    DBL: 如图1左下角所示,也就是代码中的Darknetconv2d_BN_Leaky,是yolo_v3的基本组件。就是卷积+BN+Leaky relu。对于v3来说,BN和leaky relu已经是和卷积层不可分离的部分了(最后一层卷积除外),共同构成了最小组件。
    resn:n代表数字,有res1,res2, … ,res8等等,表示这个res_block里含有多少个res_unit。这是yolo_v3的大组件,yolo_v3开始借鉴了ResNet的残差结构,使用这种结构可以让网络结构更深(从v2的darknet-19上升到v3的darknet-53,前者没有残差结构)。对于res_block的解释,可以在图1的右下角直观看到,其基本组件也是DBL。
    concat:张量拼接。将darknet中间层和后面的某一层的上采样进行拼接。拼接的操作和残差层add的操作是不一样的,拼接会扩充张量的维度,而add只是直接相加不会导致张量维度的改变。

    我们可以借鉴netron来分析网络层,整个yolo_v3_body包含252层,组成如下:
    layers

    表0. yolo_v3_layers
    根据表0可以得出,对于代码层面的layers数量一共有252层,包括add层23层(主要用于res_block的构成,每个res_unit需要一个add层,一共有1+2+8+8+4=23层)。除此之外,BN层和LeakyReLU层数量完全一样(72层),在网络结构中的表现为:每一层BN后面都会接一层LeakyReLU。卷积层一共有75层,其中有72层后面都会接BN+LeakyReLU的组合构成基本组件DBL。看结构图,可以发现上采样和concat都有2次,和表格分析中对应上。每个res_block都会用上一个零填充,一共有5个res_block。

    1. backbone

    整个v3结构里面,是没有池化层和全连接层的。前向传播过程中,张量的尺寸变换是通过改变卷积核的步长来实现的,比如stride=(2, 2),这就等于将图像边长缩小了一半(即面积缩小到原来的1/4)。在yolo_v2中,要经历5次缩小,会将特征图缩小到原输入尺寸的1/251/2^5,即1/32。输入为416x416,则输出为13x13(416/32=13)。
    yolo_v3也和v2一样,backbone都会将输出特征图缩小到输入的1/32。所以,通常都要求输入图片是32的倍数。可以对比v2和v3的backbone看看:(DarkNet-19 与 DarkNet-53)

    图2. darknet-19 vs darknet-53
    yolo_v2中对于前向过程中张量尺寸变换,都是通过最大池化来进行,一共有5次。而v3是通过卷积核增大步长来进行,也是5次。(darknet-53最后面有一个全局平均池化,在yolo-v3里面没有这一层,所以张量维度变化只考虑前面那5次)。
    这也是416x416输入得到13x13输出的原因。从图2可以看出,darknet-19是不存在残差结构(resblock,从resnet上借鉴过来)的,和VGG是同类型的backbone(属于上一代CNN结构),而darknet-53是可以和resnet-152正面刚的backbone,看下表:

    这里写图片描述

    表1. backbone对比图
    从上表也可以看出,darknet-19在速度上仍然占据很大的优势。其实在其他细节也可以看出(比如bounding box prior采用k=9),yolo_v3并没有那么追求速度,而是在保证实时性(fps>36)的基础上追求performance。不过前面也说了,你要想更快,还有一个tiny-darknet作为backbone可以替代darknet-53,在官方代码里用一行代码就可以实现切换backbone。搭用tiny-darknet的yolo,也就是tiny-yolo在轻量和高速两个特点上,显然是state of the art级别,tiny-darknet是和squeezeNet正面刚的网络,详情可以看下表:
    表2. 轻量级对比图
    所以,有了yolo v3,就真的用不着yolo v2了,更用不着yolo v1了。这也是[yolo官方网站](https://pjreddie.com/darknet/),在v3出来以后,就没提供v1和v2代码下载链接的原因了。

    2. Output

    对于图1而言,更值得关注的是输出张量:

    yolo v3输出了3个不同尺度的feature map,如上图所示的y1, y2, y3。这也是v3论文中提到的为数不多的改进点:predictions across scales
    这个借鉴了FPN(feature pyramid networks),采用多尺度来对不同size的目标进行检测,越精细的grid cell就可以检测出越精细的物体。
    y1,y2和y3的深度都是255,边长的规律是13:26:52
    对于COCO类别而言,有80个种类,所以每个box应该对每个种类都输出一个概率。
    yolo v3设定的是每个网格单元预测3个box,所以每个box需要有(x, y, w, h, confidence)五个基本参数,然后还要有80个类别的概率。所以3*(5 + 80) = 255。这个255就是这么来的。(还记得yolo v1的输出张量吗? 7x7x30,只能识别20类物体,而且每个cell只能预测2个box,和v3比起来就像老人机和iphoneX一样)
    v3用上采样的方法来实现这种多尺度的feature map,可以结合图1和图2右边来看,图1中concat连接的两个张量是具有一样尺度的(两处拼接分别是26x26尺度拼接和52x52尺度拼接,通过(2, 2)上采样来保证concat拼接的张量尺度相同)。作者并没有像SSD那样直接采用backbone中间层的处理结果作为feature map的输出,而是和后面网络层的上采样结果进行一个拼接之后的处理结果作为feature map。为什么这么做呢? 我感觉是有点玄学在里面,一方面避免和其他算法做法重合,另一方面这也许是试验之后并且结果证明更好的选择,再者有可能就是因为这么做比较节省模型size的。这点的数学原理不用去管,知道作者是这么做的就对了。


    3. some tricks

    上文把yolo_v3的结构讨论了一下,下文将对yolo v3的若干细节进行剖析。
    Bounding Box Prediction
    b-box预测手段是v3论文中提到的又一个亮点。先回忆一下v2的b-box预测:想借鉴faster R-CNN RPN中的anchor机制,但不屑于手动设定anchor prior(模板框),于是用维度聚类的方法来确定anchor box prior(模板框),最后发现聚类之后确定的prior在k=5也能够又不错的表现,于是就选用k=5。后来呢,v2又嫌弃anchor机制线性回归的不稳定性(因为回归的offset可以使box偏移到图片的任何地方),所以v2最后选用了自己的方法:直接预测相对位置。预测出b-box中心点相对于网格单元左上角的相对坐标。

    公式1

    这里写图片描述
    yolo v2直接predict出(txt_x, tyt_y, twt_w, tht_h, tot_o),并不像RPN中anchor机制那样去遍历每一个pixel。可以从上面的公式看出,b-box的位置大小和confidence都可以通过(txt_x, tyt_y, twt_w, tht_h, tot_o)计算得来,v2相当直接predict出了b-box的位置大小和confidence。box宽和高的预测是受prior影响的,对于v2而言,b-box prior数为5,在论文中并没有说明抛弃anchor机制之后是否抛弃了聚类得到的prior(没看代码,所以我不能确定),如果prior数继续为5,那么v2需要对不同prior预测出twt_wtht_h
    对于v3而言,在prior这里的处理有明确解释:选用的b-box priors 的k=9,对于tiny-yolo的话,k=6。priors都是在数据集上聚类得来的,有确定的数值,如下:

    10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
    

    每个anchor prior(名字叫anchor prior,但并不是用anchor机制)就是两个数字组成的,一个代表高度另一个代表宽度。
    v3对b-box进行预测的时候,采用了logistic regression。这一波操作sao得就像RPN中的线性回归调整b-box。v3每次对b-box进行predict时,输出和v2一样都是(txt_x, tyt_y, twt_w, tht_h, tot_o),然后通过公式1计算出绝对的(x, y, w, h, c)。
    logistic回归用于对anchor包围的部分进行一个目标性评分(objectness score),即这块位置是目标的可能性有多大。这一步是在predict之前进行的,可以去掉不必要anchor,可以减少计算量。作者在论文种的描述如下:

    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 0.5. Unlike [17] our system only assigns one bounding box prior for each ground truth object.

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

    在评论里有同学问我关于输出的问题,看来我在这里没有说的很清楚。了解v3输出的输出是至关重要的。
    
    第一点, 9个anchor会被三个输出张量平分的。根据大中小三种size各自取自己的anchor。
    
    第二点,每个输出y在每个自己的网格都会输出3个预测框,这3个框是9除以3得到的,这是作者设置
    的,我们可以从输出张量的维度来看,13x13x255。255是怎么来的呢,3*(5+80)。80表示80个种类,5表
    示位置信息和置信度,3表示要输出3个prediction。在代码上来看,3*(5+80)中的3是直接由
    num_anchors//3得到的。
    
    第三点,作者使用了logistic回归来对每个anchor包围的内容进行了一个目标性评分(objectness score)。
    根据目标性评分来选择anchor prior进行predict,而不是所有anchor prior都会有输出。
    

    loss function

    对掌握Yolo来讲,loss function不可谓不重要。在v3的论文里没有明确提所用的损失函数,确切地说,yolo系列论文里面只有yolo v1明确提了损失函数的公式。对于yolo这样一种讨喜的目标检测算法,就连损失函数都非常讨喜。在v1中使用了一种叫sum-square error的损失计算方法,就是简单的差方相加而已。想详细了解的可以看我关于v1解释的博文。我们知道,在目标检测任务里,有几个关键信息是需要确定的:(x,y),(w,h),class,confidence (x, y), (w, h), class, confidence
    根据关键信息的特点可以分为上述四类,损失函数应该由各自特点确定。最后加到一起就可以组成最终的loss_function了,也就是一个loss_function搞定端到端的训练。可以从代码分析出v3的损失函数,同样也是对以上四类,不过相比于v1中简单的总方误差,还是有一些调整的:

    xy_loss = object_mask * box_loss_scale * K.binary_crossentropy(raw_true_xy, raw_pred[..., 0:2],
                                                                           from_logits=True)
    wh_loss = object_mask * box_loss_scale * 0.5 * K.square(raw_true_wh - raw_pred[..., 2:4])
    confidence_loss = object_mask * K.binary_crossentropy(object_mask, raw_pred[..., 4:5], from_logits=True) + \
                              (1 - object_mask) * K.binary_crossentropy(object_mask, raw_pred[..., 4:5],
                                                                        from_logits=True) * ignore_mask
    class_loss = object_mask * K.binary_crossentropy(true_class_probs, raw_pred[..., 5:], from_logits=True)
    
    xy_loss = K.sum(xy_loss) / mf
    wh_loss = K.sum(wh_loss) / mf
    confidence_loss = K.sum(confidence_loss) / mf
    class_loss = K.sum(class_loss) / mf
    loss += xy_loss + wh_loss + confidence_loss + class_loss
    

    以上是一段keras框架描述的yolo v3 的loss_function代码。忽略恒定系数不看,可以从上述代码看出:除了w, h的损失函数依然采用总方误差之外,其他部分的损失函数用的是二值交叉熵。最后加到一起。那么这个binary_crossentropy又是个什么玩意儿呢?就是一个最简单的交叉熵而已,一般用于二分类,这里的两种二分类类别可以理解为"对和不对"这两种。关于binary_crossentropy的公式详情可参考博文《常见的损失函数》。


    总结

    v3毫无疑问现在成为了工程界首选的检测算法之一了,结构清晰,实时性好。这是我十分安利的目标检测算法,更值得赞扬的是,yolo_v3给了近乎白痴的复现教程,这种气量在顶层算法研究者中并不常见。你可以很快的用上v3,但你不能很快地懂v3,我花了近一个月的时间才对v3有一个清晰的了解(可能是我悟性不够哈哈哈)。在算法学习的过程中,去一些浮躁,好好理解算法比只会用算法难得很多。

    展开全文
  • 一文看懂YOLO v3

    万次阅读 多人点赞 2019-03-31 09:58:05
    论文:YOLOv3: An Incremental Improvement YOLO系列的目标检测算法可以说是目标检测史上的宏篇巨作,接下来我们来详细介绍一下YOLO v3算法内容,v3的算法是在v1和v2的基础上形成的,所以有必要先回忆: 一文看懂...

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

    YOLO系列的目标检测算法可以说是目标检测史上的宏篇巨作,接下来我们来详细介绍一下YOLO v3算法内容,v3的算法是在v1和v2的基础上形成的,所以有必要先回忆: 一文看懂YOLO v1一文看懂YOLO v2

    网络结构

    这儿盗了张图,这张图很好的总结了YOLOV3的结构,让我们对YOLO有更加直观的理解。在这里插入图片描述
    DBL:代码中的Darknetconv2d_BN_Leaky,是yolo_v3的基本组件。就是卷积+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强多了,网络层数也比他们少。
    在这里插入图片描述

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

    为了加强算法对小目标检测的精确度,YOLO v3中采用类似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。yolo v3设定的是每个网格单元预测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倍降采样后的特征,但深层特征的大小太小,因此yolo_v3使用了步长为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的特征也是类似的过程。

    在这里插入图片描述在这里插入图片描述在这里插入图片描述
    从图中,我们可以看出y1,y2,y3的由来。

    Bounding Box

    YOLO v3的Bounding Box由YOLOV2又做出了更好的改进。在yolo_v2和yolo_v3中,都采用了对图像中的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。
    YOLO v3现在对图像中检测到的对象执行多标签分类。

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

    如果模板框不是最佳的即使它超过我们设定的阈值,我们还是不会对它进行predict。
    不同于faster R-CNN的是,yolo_v3只会对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框架描述的yolo v3 的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。

    参考文章:
    https://towardsdatascience.com/yolo-v3-object-detection-53fb7d3bfe6b
    https://blog.csdn.net/yanzi6969/article/details/80505421
    https://blog.csdn.net/chandanyan8568/article/details/81089083
    https://blog.csdn.net/leviopku/article/details/82660381
    https://blog.csdn.net/u014380165/article/details/80202337

    展开全文
  • YOLOv3目标检测:原理与源码解析

    千人学习 2019-06-07 22:10:10
    Linux创始人Linus Torvalds有一句名言:Talk is cheap, Show me ... 建议先学习课程《YOLOv3目标检测实战:训练自己的数据集》或课程《YOLOv3目标检测实战:交通标志识别》,对YOLOv3的使用方法了解以后再学习本课程。
  • YOLO_V3 原理以及训练说明

    万次阅读 多人点赞 2018-07-17 21:50:32
    yolo_v3目标检测原理 Darknet 训练测试说明   yolo_v3  主要从三个方面来说明,网络的输入、结构、输出。  (1)网络输入:原论文中提到的大小320*320,416*416,608*608。这个大小必须是32的整数倍数,yolo_v3...
    • yolo_v3目标检测原理
    • Darknet 训练测试说明

     

    1. yolo_v3

      主要从三个方面来说明,网络的输入、结构、输出。

      (1)网络输入:原论文中提到的大小320*320,416*416,608*608。这个大小必须是32的整数倍数,yolo_v3有5次下采样,每次采样步长为2,所以网络的最大步幅(步幅指层的输入大小除以输出)为2^5=32。

      (2)网络结构:作者首先训练了一个darknet-53,训练这个主要是为了主要有两个目的:a.这个网路结构能在ImageNet有好的分类结果,从而说明这个网路能学习到好的特征(设计新的网络结构,这个相当于调参,具体参数怎么调,就是炼丹了),b.为后续检测模型做初始化。作者在ImageNet上实验发现这个darknet-53,的确很强,相对于ResNet-152和ResNet-101,darknet-53不仅在分类精度上差不多,计算速度还比ResNet-152和ResNet-101强多了,网络层数也比他们少。

                         图一  darknet-53网络结构

     

                       图二  darknet-53的性能测试

    Darknet-53采用了ResNet这种跳层连接方式,性能完全比ResNet-152和ResNet-101这两种深层网络好,这里作者并没有给出原因,可能的原因:a.网络的基本单元的差异,b.网络层数越少,参数少。需要的计算量少。

                 图三  两种结构基本单元比较

    Yolo_v3网路就是使用了darknet-53的前面的52层(没有全连接层),直接拿过来,yolo_v3这个网络是一个全卷积网络,大量使用残差的跳层连接。之前的工作中,采样一般都是使用size为2*2,步长(stride)为2的max-pooling或者average-pooling进行降采样。但在这个网络结构中,使用的是步长为2的卷积来进行降采样。同时,网络中使用了上采样、route操作,还在一个网络结构中进行3次检测(有点盗用SSD的思想)

     使用残差的结构的好处:(1)深度模型一个关键的点就是能否正常收敛,残差这种结构能保证网络结构在很深的情况下,仍能收敛,模型能训练下去。(2)网络越深,表达的特征越好,分类+检测的效果都会提升。(3)残差中的1*1卷积,使用network in network的想法,大量的减少了每次卷积的channel,一方面减少了参数量(参数量越大,保存的模型越大),另一方面在一定程度上减少了计算量

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

     Yolo_v3通过上采样的方式很好的使16倍降采样和8倍降采样使用深层特征,但进行4次下采样和3次下采样得到的浅层feature map大小是一样的。Yolo_v3想把这些浅层特征也利用起来,就有了route层。把16倍降采样得到的feature map和四次下采样得到的层拼接在一起,在channel那个维度进行拼接。这样拼接的好处:让网络同时学习深层和浅层特征,表达效果更好。8倍降采样同样也是这样的操作,把三次下采样的feature map拼接在一起。

    (箭头没画好,箭头从up-sample指向detection,代表把feature map的大小上升一倍)

    (3)网络输出:

    a.首先先确定网络输出特征层的大小。比如输入为320*320时,则输出为320/32=10,因此输出为10*10大小的特征层(feature map),此时有10*10=100个cell;同理当输入为416*416时输出的特征层为13*13大小的特征层,13*13=169个cell;输入为608*608时,输出的feature map大小为19*19,cell有19*19=361个。进行每进行一次up-sample时,输出特征层扩大一倍。

    b. Anchor box的确定。这个先验框不同于之前Faster-Rcnn和SSD那样人工设定,在yolo_v2和yolo_v3中,都采用了对图像中的object采用k-means聚类。在yolo_v3中作者是这样描述的:We still use k-means clustering to determine our bounding box priors. We just sort of chose 9 clusters and 3 scales arbitrarily and then divide up the clusters evenly across scales. On the COCO dataset the 9 clusters were:(10,13); (16,30); (33,23); (30,61); (62,45); (59,119); (116 ,90); (156 ,198); (373 ,326). 这个地方,作者有一个地方没有说清楚,这个框的大小是在什么输入大小的图像下确定的,比如你在608*608作为输入图像中object的大小和在320*320大小图像中的object大小肯定不同,对这两种输入聚类的结果肯定不同。但查看作者提供的yolo_v3网络配置文件,这个聚类结果应该是在416*416大小的图像下聚类得到的结果

                                    图四  Yolo_v3部分网络配置文件

    c. feature map中的每一个cell都会预测3个边界框(bounding box) ,每个bounding 
    box都会预测三个东西:(1)每个框的位置(4个值,中心坐标tx和ty,,框的高度bh和宽度bw),(2)一个objectness prediction ,(3)N个类别,coco数据集80类,voc20类。因此对于coco数据集,在网络输入为416*416时,网络的输出大小为13*13(3*(4+1+80))=43095

                               图五   bounding box

    对于上图的几点说明:

    中心坐标(tx和ty)

    Yolo_v3使用 sigmoid 函数进行中心坐标预测。这使得输出值在 0 和 1 之间。正常

    情况下,YOLO 不会预测边界框中心的确切坐标。它预测的是:与预测目标的网格单元左上角相关的偏移;并且使用feature map中的cell大小进行归一化。

    当输入图像为416*416,如果中心的预测是 (0.4, 0.7),则第二个cell在 13 x 13 特征图上的相对坐标是 (1.4, 1.7),具体的位置x坐标还需要1.4乘以cell的宽,y坐标为1.7乘以cell的高。

    Bounding box的宽度bw和高度bh

    Yolo_v3得出的预测 bw 和bh 使用图像的高和宽进行归一化,框的预测 bx 和 by 是 (0.3, 0.8),那么 13 x 13 特征图的实际宽和高是 (13 x 0.3, 13 x 0.8)。

    d. 三次检测,每次对应的感受野不同,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。

                                                  图六 打印出10647个proposal box

    展开全文
  • 深入浅出Yolo系列之Yolov5核心基础知识完整讲解 作者 | 江大白 转自: https://zhuanlan.zhihu.com/p/172121380 对Yolov4的相关基础知识做了比较系统的梳理,但Yolov4后不久,又出现了Yolov5,虽然作者没有放上...

    深入浅出Yolo系列之Yolov5核心基础知识完整讲解

    作者 | 江大白

    转自:

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

     

    Yolov4的相关基础知识做了比较系统的梳理,但Yolov4后不久,又出现了Yolov5,虽然作者没有放上和Yolov4的直接测试对比,但在COCO数据集的测试效果还是很可观的。

    很多人考虑到Yolov5创新性不足,对算法是否能够进化,称得上Yolov5而议论纷纷。

    但既然称之为Yolov5,也有很多非常不错的地方值得我们学习。不过因为Yolov5的网络结构和Yolov3Yolov4相比,不好可视化,导致很多同学看Yolov5看的云里雾里。

    因此本文,大白主要对Yolov5四种网络结构的各个细节做一个深入浅出的分析总结,和大家一些探讨学习。

    版权申明:本文包含图片,都为大白使用PPT所绘制的,如需网络结构高清图模型权重,可点击查看下载

    本文目录

    1 Yolov5 四种网络模型
    1.1 Yolov5网络结构图
    1.2 网络结构可视化
    1.2.1 Yolov5s网络结构
    1.2.2 Yolov5m网络结构
    1.2.3 Yolov5l网络结构
    1.2.4 Yolov5x网络结构
    2 核心基础内容
    2.1 Yolov3&Yolov4网络结构图
    2.2 Yolov5核心基础内容
    2.2.1 输入端
    2.2.2 Backbone
    2.2.3 Neck
    2.2.4 输出端
    2.3 Yolov5四种网络结构的不同点
    2.3.1 四种结构的参数
    2.3.2 Yolov5网络结构
    2.3.3 Yolov5四种网络的深度
    2.3.4 Yolov5四种网络的宽度
    3 Yolov5相关论文及代码
    4 小目标分割检测
    5 后语

    1 Yolov5四种网络模型

    Yolov5官方代码中,给出的目标检测网络中一共有4个版本,分别是Yolov5s、Yolov5m、Yolov5l、Yolov5x四个模型。

    学习一个新的算法,最好在脑海中对算法网络的整体架构有一个清晰的理解。

    但比较尴尬的是,Yolov5代码中给出的网络文件是yaml格式,和原本Yolov3、Yolov4中的cfg不同。

    因此无法用netron工具直接可视化的查看网络结构,造成有的同学不知道如何去学习这样的网络。

    比如下载了Yolov5的四个pt格式的权重模型:

    大白在《深入浅出Yolo系列之Yolov3&Yolov4核心基础完整讲解》中讲到,可以使用netron工具打开网络模型。

    但因为netron对pt格式的文件兼容性并不好,直接使用netron工具打开,会发现,根本无法显示全部网络。

    因此可以采用pt->onnx->netron的折中方式,先使用Yolov5代码中models/export.py脚本将pt文件转换为onnx格式,再用netron工具打开,这样就可以看全网络的整体架构了。

    如果有同学对netron工具还不是很熟悉,这里还是放上安装netron工具的详解,如果需要安装,可以移步大白的另一篇文章:《网络可视化工具netron详细安装流程》

    如需下载Yolov5整体的4个网络pt文件及onnx文件,也可点击链接查看下载,便于直观的学习。

    1.1 Yolov5网络结构图

    安装好netron工具,就可以可视化的打开Yolov5的网络结构。

    这里大白也和之前讲解Yolov3&Yolov4同样的方式,绘制了Yolov5s整体的网络结构图,配合netron的可视化网络结构查看,脑海中的架构会更加清晰。

    本文也会以Yolov5s的网络结构为主线,讲解与其他三个模型(Yolov5m、Yolov5l、Yolov5x)的不同点,让大家对于Yolov5有一个深入浅出的了解。

    1.2 网络结构可视化

    将四种模型pt文件的转换成对应的onnx文件后,即可使用netron工具查看。
    但是,有些同学可能不方便,使用脚本转换查看。
    因此,大白也上传了每个网络结构图的图片,也可以直接点击查看。
    虽然没有netron工具更直观,但是也可以学习了解。

    1.2.1 Yolov5s网络结构

    Yolov5s网络是Yolov5系列中深度最小,特征图的宽度最小的网络。后面的3种都是在此基础上不断加深,不断加宽。

    上图绘制出的网络结构图也是Yolov5s的结构,大家也可直接点击查看,Yolov5s的网络结构可视化的图片。

    1.2.2 Yolov5m网络结构

    此处也放上netron打开的Yolov5m网络结构可视图,点击即可查看,后面第二版块会详细说明不同模型的不同点。

    1.2.3 Yolov5l网络结构

    此处也放上netronx打开的Yolov5l网络结构可视图,点击即可查看

    1.2.4 Yolov5x网络结构

    此处也放上netronx打开的Yolov5x网络结构可视图,点击即可查看

    2 核心基础内容

    2.1 Yolov3&Yolov4网络结构图

    2.1.1 Yolov3网络结构图

    Yolov3的网络结构是比较经典的one-stage结构,分为输入端、Backbone、Neck和Prediction四个部分。

    大白在之前的《深入浅出Yolo系列之Yolov3&Yolov4核心基础知识完整讲解》中讲了很多,这里不多说,还是放上绘制的Yolov3的网络结构图

    2.1.2 Yolov4网络结构图

    Yolov4在Yolov3的基础上进行了很多的创新。
    比如输入端采用mosaic数据增强,
    Backbone上采用了CSPDarknet53、Mish激活函数、Dropblock等方式,
    Neck中采用了SPP、FPN+PAN的结构,
    输出端则采用CIOU_Loss、DIOU_nms操作。

    因此Yolov4对Yolov3的各个部分都进行了很多的整合创新,关于Yolov4详细的讲解还是可以参照大白之前写的《深入浅出Yolo系列之Yolov3&Yolov4核心基础知识完整讲解》,写的比较详细。

    2.2 Yolov5核心基础内容

    Yolov5的结构和Yolov4很相似,但也有一些不同,大白还是按照从整体到细节的方式,对每个板块进行讲解。

    上图即Yolov5的网络结构图,可以看出,还是分为输入端、Backbone、Neck、Prediction四个部分。

    大家可能对Yolov3比较熟悉,因此大白列举它和Yolov3的一些主要的不同点,并和Yolov4进行比较。

    (1)输入端:Mosaic数据增强、自适应锚框计算、自适应图片缩放
    (2)Backbone:Focus结构,CSP结构
    (3)Neck:FPN+PAN结构
    (4)Prediction:GIOU_Loss

    下面丢上Yolov5作者的算法性能测试图:

    Yolov5作者也是在COCO数据集上进行的测试,大白在之前的文章讲过,COCO数据集的小目标占比,因此最终的四种网络结构,性能上来说各有千秋。

    Yolov5s网络最小,速度最少,AP精度也最低。但如果检测的以大目标为主,追求速度,倒也是个不错的选择。

    其他的三种网络,在此基础上,不断加深加宽网络,AP精度也不断提升,但速度的消耗也在不断增加。

    2.2.1 输入端

    (1)Mosaic数据增强

    Yolov5的输入端采用了和Yolov4一样的Mosaic数据增强的方式。

    Mosaic数据增强提出的作者也是来自Yolov5团队的成员,不过,随机缩放随机裁剪随机排布的方式进行拼接,对于小目标的检测效果还是很不错的。

    Mosaic数据增强的内容在之前《深入浅出Yolo系列之Yolov3&Yolov4核心基础知识完整讲解》文章中写的很详细,详情可以查看之前的内容。

    (2) 自适应锚框计算

    在Yolo算法中,针对不同的数据集,都会有初始设定长宽的锚框

    在网络训练中,网络在初始锚框的基础上输出预测框,进而和真实框groundtruth进行比对,计算两者差距,再反向更新,迭代网络参数

    因此初始锚框也是比较重要的一部分,比如Yolov5在Coco数据集上初始设定的锚框:

    在Yolov3、Yolov4中,训练不同的数据集时,计算初始锚框的值是通过单独的程序运行的。

    但Yolov5中将此功能嵌入到代码中,每次训练时,自适应的计算不同训练集中的最佳锚框值。

    当然,如果觉得计算的锚框效果不是很好,也可以在代码中将自动计算锚框功能关闭

    控制的代码即train.py中上面一行代码,设置成False,每次训练时,不会自动计算。

    (3)自适应图片缩放

    在常用的目标检测算法中,不同的图片长宽都不相同,因此常用的方式是将原始图片统一缩放到一个标准尺寸,再送入检测网络中。

    比如Yolo算法中常用416*416,608*608等尺寸,比如对下面800*600的图像进行缩放。

    Yolov5代码中对此进行了改进,也是Yolov5推理速度能够很快的一个不错的trick。

    作者认为,在项目实际使用时,很多图片的长宽比不同,因此缩放填充后,两端的黑边大小都不同,而如果填充的比较多,则存在信息冗余,影响推理速度。

    因此在Yolov5的代码中datasets.py的letterbox函数中进行了修改,对原始图像自适应的添加最少的黑边

    图像高度上两端的黑边变少了,在推理时,计算量也会减少,即目标检测速度会得到提升。

    这种方式在之前github上Yolov3中也进行了讨论:https://github.com/ultralytics/yolov3/issues/232

    在讨论中,通过这种简单的改进,推理速度得到了37%的提升,可以说效果很明显。

    但是有的同学可能会有大大的问号??如何进行计算的呢?大白按照Yolov5中的思路详细的讲解一下,在datasets.py的letterbox函数中也有详细的代码。

    第一步:计算缩放比例

    原始缩放尺寸是416*416,都除以原始图像的尺寸后,可以得到0.52,和0.69两个缩放系数,选择小的缩放系数。

    第二步:计算缩放后的尺寸

    原始图片的长宽都乘以最小的缩放系数0.52,宽变成了416,而高变成了312。

    第三步:计算黑边填充数值

    将416-312=104,得到原本需要填充的高度。再采用numpy中np.mod取余数的方式,得到40个像素,再除以2,即得到图片高度两端需要填充的数值。

    此外,需要注意的是:

    a.这里大白填充的是黑色,即(0,0,0),而Yolov5中填充的是灰色,即(114,114,114),都是一样的效果。

    b.训练时没有采用缩减黑边的方式,还是采用传统填充的方式,即缩放到416*416大小。只是在测试,使用模型推理时,才采用缩减黑边的方式,提高目标检测,推理的速度。

    2.2.2 Backbone

    (1)Focus结构

    Focus结构,在Yolov3&Yolov4中并没有这个结构,其中比较关键是切片操作。

    比如右图的切片示意图,4*4*3的图像切片后变成2*2*12的特征图。

    以Yolov5s的结构为例,原始608*608*3的图像输入Focus结构,采用切片操作,先变成304*304*12的特征图,再经过一次32个卷积核的卷积操作,最终变成304*304*32的特征图。

    需要注意的是:Yolov5s的Focus结构最后使用了32个卷积核,而其他三种结构,使用的数量有所增加,先注意下,后面会讲解到四种结构的不同点。

    (2)CSP结构

    Yolov4网络结构中,借鉴了CSPNet的设计思路,在主干网络中设计了CSP结构。

    Yolov5与Yolov4不同点在于,Yolov4中只有主干网络使用了CSP结构。

    而Yolov5中设计了两种CSP结构,以Yolov5s网络为例,CSP1_X结构应用于Backbone主干网络,另一种CSP2_X结构则应用于Neck中。

    这里关于CSPNet的内容,也可以查看大白之前的《深入浅出Yolo系列之Yolov3&Yolov4核心基础完整讲解》

    2.2.3 Neck

    Yolov5现在的Neck和Yolov4中一样,都采用FPN+PAN的结构,但在Yolov5刚出来时,只使用了FPN结构,后面才增加了PAN结构,此外网络中其他部分也进行了调整。

    因此,大白在Yolov5刚提出时,画的很多结构图,又都重新进行了调整。

    这里关于FPN+PAN的结构,大白在《深入浅出Yolo系列之Yolov3&Yolov4核心基础知识完整讲解》中,讲的很多,大家应该都有理解。

    但如上面CSPNet结构中讲到,Yolov5和Yolov4的不同点在于,

    Yolov4的Neck结构中,采用的都是普通的卷积操作。而Yolov5的Neck结构中,采用借鉴CSPnet设计的CSP2结构,加强网络特征融合的能力。

    2.2.4 输出端

    (1)Bounding box损失函数

    《深入浅出Yolo系列之Yolov3&Yolov4核心基础知识完整讲解》中,大白详细的讲解了IOU_Loss,以及进化版的GIOU_Loss,DIOU_Loss,以及CIOU_Loss。

    Yolov5中采用其中的GIOU_Loss做Bounding box的损失函数。

    而Yolov4中采用CIOU_Loss作为目标Bounding box的损失。

    (2)nms非极大值抑制

    在目标检测的后处理过程中,针对很多目标框的筛选,通常需要nms操作。

    因为CIOU_Loss中包含影响因子v,涉及groudtruth的信息,而测试推理时,是没有groundtruth的。

    所以Yolov4在DIOU_Loss的基础上采用DIOU_nms的方式,而Yolov5中采用加权nms的方式。

    可以看出,采用DIOU_nms,下方中间箭头的黄色部分,原本被遮挡的摩托车也可以检出。

    大白在项目中,也采用了DIOU_nms的方式,在同样的参数情况下,将nms中IOU修改成DIOU_nms。对于一些遮挡重叠的目标,确实会有一些改进。

    比如下面黄色箭头部分,原本两个人重叠的部分,在参数和普通的IOU_nms一致的情况下,修改成DIOU_nms,可以将两个目标检出。

    虽然大多数状态下效果差不多,但在不增加计算成本的情况下,有稍微的改进也是好的。

    2.3 Yolov5四种网络结构的不同点

    Yolov5代码中的四种网络,和之前的Yolov3,Yolov4中的cfg文件不同,都是以yaml的形式来呈现。

    而且四个文件的内容基本上都是一样的,只有最上方的depth_multiplewidth_multiple两个参数不同,很多同学看的一脸懵逼,不知道只通过两个参数是如何控制四种结构的?

    2.3.1 四种结构的参数

    大白先取出Yolov5代码中,每个网络结构的两个参数:

    (1)Yolov5s.yaml

    (2)Yolov5m.yaml

    (3)Yolov5l.yaml

    (4)Yolov5x.yaml

    四种结构就是通过上面的两个参数,来进行控制网络的深度宽度。其中depth_multiple控制网络的深度width_multiple控制网络的宽度

    2.3.2 Yolov5网络结构

    四种结构的yaml文件中,下方的网络架构代码都是一样的。

    为了便于讲解,大白将其中的Backbone部分提取出来,讲解如何控制网络的宽度和深度,yaml文件中的Head部分也是同样的原理。

    在对网络结构进行解析时,yolo.py中下方的这一行代码将四种结构的depth_multiplewidth_multiple提取出,赋值给gd,gw。后面主要对这gd,gw这两个参数进行讲解。

    下面再细致的剖析下,看是如何控制每种结构,深度和宽度的。

    2.3.3 Yolov5四种网络的深度

    (1)不同网络的深度

    在上图中,大白画了两种CSP结构,CSP1和CSP2,其中CSP1结构主要应用于Backbone中,CSP2结构主要应用于Neck中。

    需要注意的是,四种网络结构中每个CSP结构的深度都是不同的。

    a.以yolov5s为例,第一个CSP1中,使用了1个残差组件,因此是CSP1_1。而在Yolov5m中,则增加了网络的深度,在第一个CSP1中,使用了2个残差组件,因此是CSP1_2

    而Yolov5l中,同样的位置,则使用了3个残差组件,Yolov5x中,使用了4个残差组件

    其余的第二个CSP1和第三个CSP1也是同样的原理。

    b.在第二种CSP2结构中也是同样的方式,以第一个CSP2结构为例,Yolov5s组件中使用了2*1=2组卷积,因此是CSP2_1

    而Yolov5m中使用了2,Yolov5l中使用了3,Yolov5x中使用了4组。

    其他的四个CSP2结构,也是同理。

    Yolov5中,网络的不断加深,也在不断增加网络特征提取特征融合的能力。

    (2)控制深度的代码

    控制四种网络结构的核心代码是yolo.py中下面的代码,存在两个变量,n和gd

    我们再将n和gd带入计算,看每种网络的变化结果。

    (3)验证控制深度的有效性

    我们选择最小的yolov5s.yaml和中间的yolov5l.yaml两个网络结构,将gd(height_multiple)系数带入,看是否正确。

    a. yolov5x.yaml

    其中height_multiple=0.33,即gd=0.33,而n则由上面红色框中的信息获得。

    以上面网络框图中的第一个CSP1为例,即上面的第一个红色框。n等于第二个数值3。

    gd=0.33,带入(2)中的计算代码,结果n=1。因此第一个CSP1结构内只有1个残差组件,即CSP1_1。

    第二个CSP1结构中,n等于第二个数值9,而gd=0.33,带入(2)中计算,结果n=3,因此第二个CSP1结构中有3个残差组件,即CSP1_3。

    第三个CSP1结构也是同理,这里不多说。

    b. yolov5l.xml

    其中height_multiple=1,即gd=1

    和上面的计算方式相同,第一个CSP1结构中,n=1,带入代码中,结果n=3,因此为CSP1_3。

    下面第二个CSP1和第三个CSP1结构都是同样的原理。

    2.3.4 Yolov5四种网络的宽度

    (1)不同网络的宽度:

    如上图表格中所示,四种yolov5结构在不同阶段的卷积核的数量都是不一样的,因此也直接影响卷积后特征图的第三维度,即厚度,大白这里表示为网络的宽度

    a.以Yolov5s结构为例,第一个Focus结构中,最后卷积操作时,卷积核的数量是32个,因此经过Focus结构,特征图的大小变成304*304*32

    而yolov5m的Focus结构中的卷积操作使用了48个卷积核,因此Focus结构后的特征图变成304*304*48。yolov5l,yolov5x也是同样的原理。

    b. 第二个卷积操作时,yolov5s使用了64个卷积核,因此得到的特征图是152*152*64。而yolov5m使用96个特征图,因此得到的特征图是152*152*96。yolov5l,yolov5x也是同理。

    c. 后面三个卷积下采样操作也是同样的原理,这样大白不过多讲解。

    四种不同结构的卷积核的数量不同,这也直接影响网络中,比如CSP1,CSP2等结构,以及各个普通卷积,卷积操作时的卷积核数量也同步在调整,影响整体网络的计算量。

    大家最好可以将结构图和前面第一部分四个网络的特征图链接,对应查看,思路会更加清晰。

    当然卷积核的数量越多,特征图的厚度,即宽度越宽,网络提取特征的学习能力也越强

    (2)控制宽度的代码

    在yolov5的代码中,控制宽度的核心代码是yolo.py文件里面的这一行:

    它所调用的子函数make_divisible的功能是:

    (3)验证控制宽度的有效性

    我们还是选择最小的yolov5s中间的yolov5l两个网络结构,将width_multiple系数带入,看是否正确。

    a. yolov5x.yaml

    其中width_multiple=0.5,即gw=0.5

    以第一个卷积下采样为例,即Focus结构中下面的卷积操作。

    按照上面Backbone的信息,我们知道Focus中,标准的c2=64,而gw=0.5,代入(2)中的计算公式,最后的结果=32。即Yolov5s的Focus结构中,卷积下采样操作的卷积核数量为32个。

    再计算后面的第二个卷积下采样操作,标准c2的值=128,gw=0.5,代入(2)中公式,最后的结果=64,也是正确的。

    b. yolov5l.yaml

    其中width_multiple=1,即gw=1,而标准的c2=64,代入上面(2)的计算公式中,可以得到Yolov5l的Focus结构中,卷积下采样操作的卷积核的数量为64个,而第二个卷积下采样的卷积核数量是128个。

    另外的三个卷积下采样操作,以及yolov5m,yolov5x结构也是同样的计算方式,大白这里不过多解释。

    3 Yolov5相关论文及代码

    3.1 代码

    Yolov5的作者并没有发表论文,因此只能从代码角度进行分析。

    Yolov5代码:https://github.com/ultralytics/yolov5

    大家可以根据网页的说明,下载训练,及测试,流程还是比较简单的。

    3.2 相关论文

    另外一篇论文,PP-Yolo,在Yolov3的原理上,采用了很多的tricks调参方式,也挺有意思。

    感兴趣的话可以参照另一个博主的文章:点击查看

    4 小目标分割检测

    目标检测发展很快,但对于小目标的检测还是有一定的瓶颈,特别是大分辨率图像小目标检测。比如7920*2160,甚至16000*16000的图像。

    图像的分辨率很大,但又有很多小的目标需要检测。但是如果直接输入检测网络,比如yolov3,检出效果并不好。

    主要原因是:

    (1)小目标尺寸

    以网络的输入608*608为例,yolov3、yolov4,yolov5中下采样都使用了5次,因此最后的特征图大小是19*19,38*38,76*76。

    三个特征图中,最大的76*76负责检测小目标,而对应到608*608上,每格特征图的感受野是608/76=8*8大小。

    再将608*608对应到7680*2160上,以最长边7680为例,7680/608*8=101。

    即如果原始图像中目标的宽或高小于101像素,网络很难学习到目标的特征信息。

    (PS:这里忽略多尺度训练的因素及增加网络检测分支的情况)

    (2)高分辨率

    而在很多遥感图像中,长宽比的分辨率比7680*2160更大,比如上面的16000*16000,如果采用直接输入原图的方式,很多小目标都无法检测出。

    (3)显卡爆炸

    很多图像分辨率很大,如果简单的进行下采样,下采样的倍数太大,容易丢失数据信息。

    但是倍数太小,网络前向传播需要在内存中保存大量的特征图,极大耗尽GPU资源,很容易发生显存爆炸,无法正常的训练及推理。

    因此可以借鉴2018年YOLT算法的方式,改变一下思维,对大分辨率图片先进行分割,变成一张张小图,再进行检测。

    需要注意的是:

    为了避免两张小图之间,一些目标正好被分割截断,所以两个小图之间设置overlap重叠区域,比如分割的小图是960*960像素大小,则overlap可以设置为960*20%=192像素。

    每个小图检测完成后,再将所有的框放到大图上,对大图整体做一次nms操作,将重叠区域的很多重复框去除。

    这样操作,可以将很多小目标检出,比如16000*16000像素的遥感图像。

    无人机视角下,也有很多小的目标。大白也进行了测试,效果还是不错的。

    比如下图是将原始大图->416*416大小,直接使用目标检测网络输出的效果:

    可以看到中间黄色框区域,很多汽车检测漏掉。

    再使用分割的方式,将大图先分割成小图再对每个小图检测,可以看出中间区域很多的汽车都被检测出来:

    不过这样的方式有优点也有缺点:

    优点:

    (1)准确性

    分割后的小图,再输入目标检测网络中,对于最小目标像素的下限会大大降低。

    比如分割成608*608大小,送入输入图像大小608*608的网络中,按照上面的计算方式,原始图片上,长宽大于8个像素的小目标都可以学习到特征。

    (2)检测方式

    在大分辨率图像,比如遥感图像,或者无人机图像,如果无需考虑实时性的检测,且对小目标检测也有需求的项目,可以尝试此种方式。

    缺点:

    (1)增加计算量

    比如原本7680*2160的图像,如果使用直接大图检测的方式,一次即可检测完。

    但采用分割的方式,切分成N张608*608大小的图像,再进行N次检测,会大大增加检测时间。

    借鉴Yolov5的四种网络方式,我们可以采用尽量轻的网络,比如Yolov5s网络结构或者更轻的网络。

    当然Yolov4和Yolov5的网络各有优势,我们也可以借鉴Yolov5的设计方式,对Yolov4进行轻量化改造,或者进行剪枝

    5 后语

    综合而言,在实际测试中,Yolov4的准确性有不错的优势,但Yolov5的多种网络结构使用起来更加灵活,我们可以根据不同的项目需求,取长补短,发挥不同检测网络的优势。

    希望在人工智能的道路上,和大家共同进步

    展开全文
  • 深入浅出Yolo系列之Yolov3&Yolov4&Yolov5核心基础知识完整讲解1.论文汇总2.YoloV3核心基础内容2.1 网络结构可视化2.2 网络结构图2.3核心基础内容3.YoloV3相关代码3.1 python代码3.2 C++代码3.3 python版本的...
  • 干货|深入浅出YOLOv5

    2020-10-18 22:40:00
    AI编辑:我是小将本文作者:江大白https://zhuanlan.zhihu.com/p/172121380本文已由原作者授权,不得擅自二次转载如果你想进一步学习YOLOV5,可以关注...
  • Yolov5x可视化网络结构图

    千次阅读 2020-07-29 11:06:10
    Yolov5共有四种网络结构,每种网络深度和宽度上都不相同。 (1) Yolov5s可视化网络结构图:点击查看 (2) Yolov5m可视化网络结构图:点击查看 (3) Yolov5l可视化网络结构图:点击查看 (4) Yolov5x可视化网络结构图:...
  • YOLO v3详解

    万次阅读 2019-01-29 21:53:14
    YOLO v3是YOLO和YOLO v2之后的YOLO系列的又一篇目标检测算法,是基于YOLO v2的一个改进,速度更快,精度更高!   1、YOLO v3的网络结构图 ...DBL:如图1左下角所示,也就是代码中的Darknetconv2d_BN_Leaky,是...
  • YOLO v3算法详解

    万次阅读 2019-03-25 23:44:21
    论文地址:YOLOv3: An Incremental Improvement YOLO算法详解,YOLO v2算法详解 1.The Deal 接下来,从头梳理整个网络,如果对YOLO和YOLO v2不熟悉,可以看一下我之前的博客。 1.1 Bounding Box Prediction ...
  • YOLO v3算法笔记

    万次阅读 多人点赞 2018-05-05 08:22:51
    论文:YOLOv3: An Incremental Improvement 论文地址:https://pjreddie.com/media/files/papers/YOLOv3.pdf YOLO系列的目标检测算法真的非常赞!这篇博客就来介绍YOLO v3算法的内容,因为涉及到v1和v2的一些思想...
  • 目标检测:YOLOv3: 训练自己的数据

    万次阅读 多人点赞 2018-03-26 10:59:02
    ------------------------------ 本文仅供学习交流,如有错误,望交流指教 ------------------------------ windows 版本:请参考:https://github.com/AlexeyAB/darknet linux 版本:请参考本文与...
  • YOLOV3

    千次阅读 2019-03-21 21:39:23
    YOLOV3 YOLO v3网络优点 相比于YOLO v2网络,在保持速度优势的前提下,提升了预测精度,尤其是加强了对小物体的识别能力。 YOLO v3对相对于v1和v2的改进 将多个好的方案融合到YOLO里面 基于Darknet-53网络结构 ...
  • yolov3

    万次阅读 多人点赞 2018-05-16 12:23:56
    yolov3延续了yolov2的anchor策略,基本没有变化。 边框的表示方式通过框的中心坐标bx,by,和框的宽bw,高bh这4个变量来表示。实际预测的值为tx,ty,tw,th。 由tx,ty,tw,th得到bx,by,bw,bh的详细公式如上图,其中, ...
  • 从YOLOv1到YOLOv3,目标检测的进化之路

    万次阅读 多人点赞 2018-06-04 18:11:14
    本文来自 CSDN 网站,作者 EasonApp。作者专栏: http://dwz.cn/7ZGrifYOLOv1这是继 RCNN,fast-RCNN 和 faster-...
  • YoLov3训练自己的数据集(小白手册)

    万次阅读 多人点赞 2018-08-02 11:00:12
    工具:labelimg、MobaXterm 1.标注自己的数据集。用labelimg进行标注,保存后会生成与所标注图片文件名相同...2.下载yolov3项目工程。按照YoLo官网下载 git clone https://github.com/pjreddie/darknet cd darkn...
  • YOLOV3训练自己的数据集(PyTorch版本)

    万次阅读 多人点赞 2019-05-06 15:59:56
    由于这一段时间从事目标检测相关工作,因而接触到yolov3,进行目标检测,具体原理大家可以参考大神的博客目标检测(九)--YOLO v1,v2,v3,我就不细讲了,直接进入正题,如何利用深度学习框架PyTorch对自己的数据进行...
  • YOLOv3

    千次阅读 2019-08-30 20:39:47
    YOLOv3一、训练日志可视化(基于Darknet)1.损失函数和学习率曲线 一、训练日志可视化(基于Darknet) 1.损失函数和学习率曲线 # encoding:utf-8 import matplotlib.pyplot as plt ''' 根据关键词在日志文件...
  • Yolov3+C+++opencv+VS2015成功检测

    万次阅读 多人点赞 2019-03-13 20:35:32
    我的运行环境是C+++opencv+VS2015+yolov3,下面将简单介绍下yolo的一些思想,这些也是我在看了很多博主介绍后,自己做的一些总结和笔记,后面也给大家附上了我写的一些关键代码和解释,关于整个工程由于一些私人原因...
1 2 3 4 5 ... 20
收藏数 21,447
精华内容 8,578
关键字:

yolov3