yolo 订阅
YOLO,美语新词,是You Only Live Once的首字母缩略词,意为你只能活一次,应该活在当下,大胆去做。YOLO的寓意是人应该享受人生,即使需要承担风险。就是鼓励人们不怕冒险,想做什么就做什么,享受人生,因为只会活一次。 [1]  词典编纂者Ben Zimmer发现该新词最早起源于YOLO商标,释义为You Only Live Once,现在这一句话常常用在青少年的对话和音乐当中。加拿大饶舌歌手德雷克的《The Motto》使此句普及于网络中;BTS的歌曲《INTRO : O!RUL8,2?》 [2]  和《Go Go》 [3]  分别使用了"You only live once" [4]  和"YOLO" [5]  。2016年该新词首次作为词条收录于牛津词典。2019年中国男子流行演唱组合R1SE在其第二张专辑《炸裂狂想曲》中以柯洁与ALPHAGO人机对战为背景创作的《Never Surrender》中提到“我的格言是YOLO”。 展开全文
YOLO,美语新词,是You Only Live Once的首字母缩略词,意为你只能活一次,应该活在当下,大胆去做。YOLO的寓意是人应该享受人生,即使需要承担风险。就是鼓励人们不怕冒险,想做什么就做什么,享受人生,因为只会活一次。 [1]  词典编纂者Ben Zimmer发现该新词最早起源于YOLO商标,释义为You Only Live Once,现在这一句话常常用在青少年的对话和音乐当中。加拿大饶舌歌手德雷克的《The Motto》使此句普及于网络中;BTS的歌曲《INTRO : O!RUL8,2?》 [2]  和《Go Go》 [3]  分别使用了"You only live once" [4]  和"YOLO" [5]  。2016年该新词首次作为词条收录于牛津词典。2019年中国男子流行演唱组合R1SE在其第二张专辑《炸裂狂想曲》中以柯洁与ALPHAGO人机对战为背景创作的《Never Surrender》中提到“我的格言是YOLO”。
信息
外文名
YOLO
全    拼
You Only Live Once
含    义
你只活一次
yolo来源意义
美国好莱坞著名演员梅·蕙丝(Mae West,1893年8月7日-1980年11月22日)被公认为是最先使用这句话 的,因为她有这样一句台词“You only live once, but if you do it right, once is enough”(你只能活一次,如果活得精彩,一次也就足够了)。1774年,约翰·沃尔夫冈·冯·歌德(Johann Walfgang Van Goethe)在他年的戏剧《柯拉维果》(CLAVIGO)里的“One lives but once in the world(一个人在这世上只活一次);1855年,奥地利著名的作曲家小约翰·施特劳斯(Johann Strauß)将一首圆舞曲命名为Man lebt nur einmal!(德语,意思是你只会活一次)。 [6] 
收起全文
精华内容
参与话题
问答
  • yolo

    千次阅读 2019-10-24 16:06:07
    目标检测:一类基于Region Proposal的R-CNN系算法(R-CNN,Fast R-CNN,Faster R-CNN),它们是two-stage的,需要先使用启发式方法(selective search)...另一类是Yolo,SSD这类one-stage算法,其仅仅使用一个CNN...

    目标检测:一类基于Region Proposal的R-CNN系算法(R-CNN,Fast R-CNN,Faster R-CNN),它们是two-stage的,需要先使用启发式方法(selective search)或者CNN网络(RPN)产生Region Proposal,然后再在Region Proposal上做分类与回归。另一类是Yolo,SSD这类one-stage算法,其仅仅使用一个CNN网络直接预测不同目标的类别与位置。第一类方法是准确度高一些,但是速度慢,但是第二类算法是速度快,但是准确性要低一些。

    参考yoloV1

    Yolo算法的特点:You Only Look Once说的是只需要一次CNN运算Unified指的是一个统一的框架,提供end-to-end的预测,而Real-Time体现是Yolo算法速度快。

    滑动窗口与CNN

    滑动窗口的目标检测算法思路非常简单,它将检测问题转化为了图像分类问题。原理就是采用不同大小和比例(宽高比)的窗口在整张图片上以一定的步长进行滑动,然后对这些窗口对应的区域做图像分类,实现对整张图片的检测。致命的缺点,就是你并不知道要检测的目标大小是什么规模,所以你要设置不同大小和比例的窗口去滑动,而且还要选取合适的步长。

    这样会产生很多的子区域,并且都要经过分类器去做预测,这需要很大的计算量,所以你的分类器不能太复杂,因为要保证速度。解决思路之一就是减少要分类的子区域,这就是R-CNN的一个改进策略,其采用了selective search方法来找到最有可能包含目标的子区域(Region Proposal),其实可以看成采用启发式方法过滤掉很多子区域,这会提升效率

    如果你使用的是CNN分类器,那么滑动窗口是非常耗时的,结合卷积运算的特点,我们可以使用CNN实现更高效的滑动窗口方法。这里要介绍的是一种全卷积的方法,简单来说就是网络中用卷积层代替了全连接层,输入图片大小是16x16,经过一系列卷积操作提取了2x2的特征图,但是这个2x2的图上每个元素都是和原图是一一对应的,如图上蓝色的格子对应蓝色的区域,这不就是相当于在原图上做大小为14x14的窗口滑动,且步长为2,共产生4个字区域。最终输出的通道数为4,可以看成4个类别的预测概率值,这样一次CNN计算就可以实现窗口滑动的所有子区域的分类预测

    使用卷积运算,将16*16*3的图像,得到2*2*4的特征图(包含信息一样),实现滑动窗口的所有子区域的分类预测。

    上面尽管可以减少滑动窗口的计算量,但是只是针对一个固定大小与步长的窗口,这是远远不够的。Yolo算法很好的解决了这个问题,它不再是窗口滑动了,而是直接将原始图片分割成互不重合的小方块,然后通过卷积最后生产这样大小的特征图,基于上面的分析,可以认为特征图的每个元素也是对应原始图片的一个小方块,然后用每个元素来可以预测那些中心点在该小方格内的目标

    YOLOv1

    YOLO算法采用一个单独的CNN模型实现end-to-end的目标检测,整个系统如下图所示:首先将输入图片resize到448x448,然后送入CNN网络,最后处理网络预测结果得到检测的目标

    1. Resize image  2、Run convolutional network 3、Non-max suppression

    YOLO的CNN网络将输入的图片分割成,其中前4个表征边界框的大小与位置,而最后一个值是置信度。

    输入图片被划分为7*7个单元格,每个单元格独立做检测。

    YOLO解决的问题是怎么定位目标、怎么对目标进行分类?

    对于每一个单元格其还要给出预测出边界框 类别 置信度 表征的是该边界框中目标属于各个类别的可能性大小以及边界框匹配目标的好坏。后面会说,一般会根据类别置信度来过滤网络的预测框

    每个单元格需要预测大小的张量。在下面的网络结构中我们会详细讲述每个单元格的预测值的分布位置。

    个网络预测值的依据是什么,或者它根据什么来预测。CNN之后得到图像的特征信息,怎么根据特征信息去定位、分类?

    网络设计

    YOLO采用卷积网络来提取特征,然后使用全连接层(fully connected layer)得到预测值。

    全连接层(fully connected layer):卷积取的是局部特征,全连接就是把以前的局部特征重新通过权值矩阵组装成完整的图。

    因为用到了所有的局部特征,所以叫全连接。

    BatchNormalization layer:批量归一化

    https://blog.csdn.net/myarrow/article/details/51848285

    网络结构参考GooLeNet模型,包含24个卷积层和2个全连接层,如图8所示。对于卷积层,主要使用1x1卷积来做channle reduction,然后紧跟3x3卷积。对于卷积层和全连接层,采用Leaky ReLU激活函数:。但是最后一层却采用线性激活函数。除了上面这个结构,文章还提出了一个轻量级版本Fast Yolo,其仅使用9个卷积层,并且卷积层中使用更少的卷积核

     

    可以看到网络的最后输出为边界框的预测结果,这样提取每个部分是非常方便的,这方面的训练集预测时的计算。Yolov1输出7*7*30的张量,7*7位图像所分的格子数30为 20个类别的概率,box1、box2的置信度,boundingbox(x,y,w,h)。

    Faster R-CNN那种two-stage复杂的网络结构而言,YOLOv1结构相对简单,基本思想:预测框的位置,大小和物体分类都通过CNN暴力预测、输出7*7*30的张量,代表能预测2个框的5个参数和20个种类。S*S(B*5+C)。深度只有30,意味着每个单元格只能预测两个框(而且只认识20类物体),这对于密集型目标检测和小物体都不能很好适用。

    每个小格子怎么判断出该物体呢?换句话说该小格子的特征,怎么能代表整个物体的特征?

    YOLO的做法不是把每个单独的网格作为输入feed到模型,在inference的过程中,网络只是物体中心点位置的划分之用,并不是对图片进行切分,不会让网格脱离整个的关系。(中心点为目标定位,而每个小格子会预测两个boudingbox,得到物体的边界框,这就是目标定位问题

    将原始图像分割成互不重合的小方块,然后通过卷积最后生产这样大小的特征图。特征图的每个元素也是对应原始图片的一个小方块,然后利用每个元素来预测那些中心点在该小方格内的目标。根据什么特征来预测那个元素是中心点的?预测完中心点后wh即boundingbox怎么预测?

    每个cell本身并不知道判断哪个是中心点,而是反过来,根据学习到的特征判断输入网络中图片得到的特征图中哪个元素是 中心点,再根据元素位置找出图像中cell。

    边界框怎么预测?物体怎么类别

    网络训练

    训练之前,先在ImageNet上进行了预训练,其预训练的分类模型采用图8中前20个卷积层,然后添加一个average-pool层和全连接层。预训练之后,在预训练得到的20层卷积层之上加上随机初始化的4个卷积层和2个全连接层。由于检测任务一般需要更高清的图片,所以将网络的输入从224x224增加到了448x448。

    卷积层:采用各种卷积核对输入图片进行卷积处理。(平移不变性)

    池化层(average-pool):降采用。(空间不变性)

    全连接层:一个神经元在作用于整个slice,即filter的尺寸恰好为一个slice的尺寸。

    训练损失函数的分析,Yolo算法将目标检测看成回归问题,所以采用的是均方差损失函数。但是对不同的部分采用了不同的权重值。首先区分定位误差和分类误差。对于定位误差,即边界框坐标预测误差,采用较大的权重。

    yolo是端到端训练,对于预测框的位置、size、种类、置信度(score)等信息的预测都通过一个损失函数来训练。

     

    S表示网格数,这里是7*7。B表示每个单元格预测框的个数,这里是2;

    第一行总方误差(sum-squared error)来当作位置预测的损失函数,第二行用根号总方误差来当作宽度和高度的损失函数第三行和第四行对置信度confidence也用SSE作为损失函数第五行用SSE作类别概率的损失函数。最后将几个损失函数加到一起,当作YOLOv1的损失函数。

    由于每个单元格预测多个边界框。但是其对应类别只有一个。那么在训练时,如果该单元格内确实存在目标,那么只选择与ground truth的IOU最大的那个边界框来负责预测该目标,而其它边界框认为不存在目标。这样设置的一个结果将会使一个单元格对应的边界框更加专业化,其可以分别适用不同大小,不同高宽比的目标,从而提升模型性能

    如果一个单元格内存在多个目标怎么办,其实这时候Yolo算法就只能选择其中一个来训练,这也是Yolo算法的缺点之一

    要注意的一点时,对于不存在对应目标的边界框,其误差项就是只有置信度,左标项误差是没法计算的。而只有当一个单元格内确实存在目标时,才计算分类误差项,否则该项也是无法计算的。

    卷积神经网络相关概念

    激活函数

    根据一些列的输入值,神经元之间连接的权值以及激励规则,刺激神经元。leaky ReLU,相比普通RelU,leaky并不会让负数直接为0,而是乘以一个很小的系数(恒定),保留负数输出,但衰减负数输出;公式如下:

    损失函数

    在训练阶段,用于评估输出结果和实际值的差异。然后用损失函数的值更新每个神经元之间的权重值。卷积神经网络的训练目的就是最小化损失函数值。

    总结

    YOLO优点是采用一个CNN网络来实现检测,是单管道策略,其训练与预测都是end-to-end,所以yolo算法比较简单且速度快。第二点yolo是对整个图片做卷积,所以其在检测目标有更大的视野,它不容易对背景误判。全连接层起到attention的作用。另外,YOLO的泛化能力强,在做迁移时,模型鲁棒性高。

    YOLO缺点:YOLO各个单元格仅仅预测两个边界框,而且属于一个类别。对于小物体,YOLO表现会不如人意。SSD在这方面做了个改进,采用多尺度单元格。Faster R-CNN,采用anchor boxes。YOLO对于物体在宽高比方面泛化率低,无法定位不寻常比例的物体,其定位不准确也是很大的问题。

     

    图解YOLOv3

    图片尺寸:input_shape = [height,width]

    Resize 为256*256并除以255进行归一化;

    标签预处理:boxes转换 为(x,y,w,h,class)格式得到true_box,x,y,w,h除以图像的input_shape进行归一化;

    标签计算:将boxes resize到13*13得到box_output的x,y中心正好落在output的某个grid cell

    Box_output中的每个元素box与所有anchors计算IOU,找到IOU最大值对应的anchor。

    对每张图偏的每个box

     

    展开全文
  • YOLO

    千次阅读 2019-10-15 12:41:34
    YOLO YOLO算法整体来说就是把输入的图片划分为S*S格子,这里是3*3个格子。当被检测的目标的中点落入这个格子时,这个格子负责检测这个目标,如图中的人。我们把这个图片输入到网络中,最后输出的尺寸也是S*S*n(n...

     

    YOLO

    YOLO算法整体来说就是把输入的图片划分为S*S格子,这里是3*3个格子。当被检测的目标的中点落入这个格子时,这个格子负责检测这个目标,如图中的人。我们把这个图片输入到网络中,最后输出的尺寸也是S*S*n(n是通道数),这个输出的S*S与原输入图片S*S相对应(都是3*3)。假如我们网络一共能检测20个类别的目标,那么输出的通道数n=2*(4+1)+20=30。这里的2指的是每个格子有两个标定框(论文指出的),4代表标定框的坐标信息, 1代表标定框的置信度, 20是检测目标的类别数。所以网络最后输出结果的尺寸是S*S*n=3*3*30。

     

    关于标定框

    上面说网络的输出是S x S x (5*B+C) 的一个 tensor(S尺寸,B标定框个数,C检测类别数,5标定框的信息)。

    5分为4+1。4代表标定框的位置信息。坐标的重点x,y,坐标的高宽h,w。如下图,我们和假设图片的左上角是(0,0)

    右下角为(1,1)我们就可以求得标定框的位置信息了。

     这里的1表示每个标定框的置信度以及标定框的准确度信息。公式表示如下,

    左边代表包含这个标定框的格子里是否有目标有1没有0,右边达标标定框的准确程度, 右边的部分是把两个标定框(一个是groundtruth一个是预测的标定框)进行一个IOU操作,即两个标定框的交集比并集,数值越大,即标定框重合越多,越准确。

    同时,我们可以计算出各个边界框类别置信度(class-specific confidence scores):

    边界框类别置信度表征的是该边界框中目标属于各个类别的可能性大小以及边界框匹配目标的好坏。后面会说,一般会根据类别置信度来过滤网络的预测框。

    网络结构

     Yolo采用卷积网络来提取特征,然后使用全连接层来得到预测值。网络结构参考GooLeNet模型,包含24个卷积层和2个全连接层。对于卷积层,主要使用1x1卷积来做channle reduction,然后紧跟3x3卷积。对于卷积层和全连接层,采用Leaky ReLU激活函数。但是最后一层却采用线性激活函数。
     

    网络训练

    1首先我们现在imageNet上预训练20个卷积

    2在预训练模型的基础上+全局平均池化层,之后随机初始化的4个卷积层和2个全连接层。

    3由于检测任务一般需要更高清的图片,所以将网络的输入从224x224增加到了448x448。

    网络结果如下:

    损失函数分析 

    下面是训练损失函数的分析,Yolo算法将目标检测看成回归问题,所以采用的是均方差损失函数。但是对不同的部分采用了不同的权重值。首先区分定位误差和分类误差。对于定位误差,即边界框坐标预测误差,采用较大的权重λcoord=5λcoord=5。然后其区分不包含目标的边界框与含有目标的边界框的置信度,对于前者,采用较小的权重值λnoobj=0.5λnoobj=0.5。其它权重值均设为1。然后采用均方误差,其同等对待大小不同的边界框,但是实际上较小的边界框的坐标误差应该要比较大的边界框要更敏感。为了保证这一点,将网络的边界框的宽与高预测改为对其平方根的预测,即预测值变为
    另外一点时,由于每个单元格预测多个边界框。但是其对应类别只有一个。那么在训练时,如果该单元格内确实存在目标,那么只选择与ground truth的IOU最大的那个边界框来负责预测该目标,而其它边界框认为不存在目标。这样设置的一个结果将会使一个单元格对应的边界框更加专业化,其可以分别适用不同大小,不同高宽比的目标,从而提升模型性能。大家可能会想如果一个单元格内存在多个目标怎么办,其实这时候Yolo算法就只能选择其中一个来训练,这也是Yolo算法的缺点之一。要注意的一点时,对于不存在对应目标的边界框,其误差项就是只有置信度,左标项误差是没法计算的。而只有当一个单元格内确实存在目标时,才计算分类误差项,否则该项也是无法计算的。
    综上讨论,最终的损失函数计算如下:

    其中第一项是边界框中心坐标的误差项,1objij1ijobj指的是第ii个单元格存在目标,且该单元格中的第jj个边界框负责预测该目标。第二项是边界框的高与宽的误差项。第三项是包含目标的边界框的置信度误差项。第四项是不包含目标的边界框的置信度误差项。而最后一项是包含目标的单元格的分类误差项,1obji1iobj指的是第ii个单元格存在目标。
     

    YOLO缺点

    YOLO 对相互靠的很近的物体,还有很小的群体检测效果不好,这是因为一个网格中只预测了两个框,并且只属于一类。

    同一类物体出现的新的不常见的长宽比和其他情况时,泛化能力偏弱。

    由于损失函数的问题,定位误差是影响检测效果的主要原因。尤其是大小物体的处理上,还有待加强。


    YOLOv2

    YOLOv2:代表着目前业界最先进物体检测的水平,它的速度要快过其他检测系统(FasterR-CNN,ResNet,SSD),使用者可以在它的速度与精确度之间进行权衡。

    YOLO9000:这一网络结构可以实时地检测超过 9000 种物体分类,这归功于它使用了 WordTree,通过 WordTree 来混合检测数据集与识别数据集之中的数据。

    YOLOv1虽然检测速度很快,但是在检测精度上却不如R-CNN系检测方法,YOLOv1在物体定位方面(localization)不够准确,并且召回率(recall)较低。下面是YOLOv2改进的各部分。

    1Batch Normalization(提升2.4)

    Batch Normalization可以提升模型收敛速度,而且可以起到一定正则化效果,降低模型的过拟合。在YOLOv2中,每个卷积层后面都添加了Batch Normalization层,并且不再使用droput。

    2High Resolution Classifier

    YOLOv1在采用224×224分类模型预训练后,将分辨率增加至=448×448,并使用这个高分辨率在检测数据集上finetune。但是直接切换分辨率,检测模型可能难以快速适应高分辨率。所以YOLOv2增加了在ImageNet数据集上使用448×448=来finetune分类网络这一中间过程(10 epochs),这可以使得模型在检测数据集上finetune之前已经适用高分辨率输入。使用高分辨率分类器后,YOLOv2的mAP提升了约4%。

    3Convolutional With Anchor Boxes

    我们在YOLO算法中是使用长宽比来表示物体的标定框的大小,但是检测图像中的目标有很多不同的长宽比,因此YOLO算法在精确的定位上是比较困难的。

    YOLO借鉴了Faster-R-CNN网络中的先验框的策略(RPN部分),这个策略可以使模型更容易学习。

    YOLOv2移除了YOLOv1中的全连接层而采用了卷积和anchor boxes来预测边界框。

    YOLOv2中把输入的尺寸调整到416*416的大小,这是为了适应高分辨率。同时416可以整除32,网络正好是32倍下采样率。

    416/32=13,即我们输出的尺寸是13*13,这样特征图恰好只有一个中心位置。对于一些大物体,它们中心点往往落入图片中心位置,此时使用特征图的一个中心点去预测这些物体的边界框相对容易些。

    YOLOv2使用了anchor boxes之后,每个位置的各个anchor box都单独预测一套分类概率值。

     图为Ng网课截图。其中编号2表示使用YOLOv2来检测汽车的输出y。

    4Dimension Clusters

    在Faster R-CNN和SSD中,先验框的维度(长和宽)都是手动设定的,带有一定的主观性。如果选取的先验框维度比较合适,那么模型更容易学习,从而做出更好的预测。因此,YOLOv2采用k-means聚类方法对训练集中的边界框做了聚类分析。

    5New Network: Darknet-19

    YOLOv2采用了一个新的基础模型(特征提取器),称为Darknet-19,包括19个卷积层和5个maxpooling层,

    与VGG网络有着类似的结构,使用大量的3*3和1*1卷积在增加网络深度的同时,把计算量调小。

    6Direct location prediction

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

    因为使用了限制让数值变得参数化,也让网络更容易学习、更稳定。Dimension clusters和Direct location prediction,使 YOLO 比其他使用 Anchor Box 的版本提高了近5%。

    7Fine-Grained Features

    YOLO 修改后的特征图大小为 13*13,这个尺寸对检测图片中尺寸大物体来说足够了,同时使用这种细粒度的特征对定位小物体的位置可能也有好处。Faster-RCNN、SSD 都使用不同尺寸的特征图来取得不同范围的分辨率,而 YOLO 采取了不同的方法,YOLO 加上了一个 Passthrough Layer 来取得之前的某个 26*26 分辨率的层的特征。这个 Passthrough layer 能够把高分辨率特征与低分辨率特征联系在一起,联系起来的方法是把相邻的特征堆积在不同的 Channel 之中,这一方法类似与 Resnet 的 Identity Mapping,从而把 26*26*512 变成 13*13*2048。YOLO 中的检测器位于扩展后(expanded )的特征图的上方,所以他能取得细粒度的特征信息,这提升了 YOLO 1% 的性能。

    8Multi-Scale Training

    区别于之前的补全图片的尺寸的方法,YOLOv2 每迭代几次都会改变网络参数。每 10 个 Batch,网络会随机地选择一个新的图片尺寸,由于使用了下采样参数是  32,所以不同的尺寸大小也选择为 32 的倍数 {320,352…..608},最小 320*320,最大 608*608,网络会自动改变尺寸,并继续训练的过程。


    这一政策让网络在不同的输入尺寸上都能达到一个很好的预测效果,同一网络能在不同分辨率上进行检测。当输入图片尺寸比较小的时候跑的比较快,输入图片尺寸比较大的时候精度高,所以你可以在 YOLOv2 的速度和精度上进行权衡。

     

     

     

     

     

     

     

     

    展开全文
  • yolo系列之yolo v3【深度解析】

    万次阅读 多人点赞 2018-09-12 16:24:48
    yolo_v3是我最近一段时间主攻的算法,写下博客,以作分享交流。 看过yolov3论文的应该都知道,这篇论文写得很随意,很多亮点都被作者都是草草描述。很多骚年入手yolo算法都是从v3才开始,这是不可能掌握yolo精髓的...

    版权申明:转载和引用图片,都必须经过书面同意。获得留言同意即可
    本文使用图片多为本人所画,需要高清图片可以留言联系我,先点赞后取图
    这篇博文比较推荐的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

    千次阅读 2019-06-14 17:29:56
    YoloV1:https://arxiv.org/abs/1506.02640 YoloV2:https://arxiv.org/abs/1612.08242 YoloV3:https://arxiv.org/abs/1804.02767 官网: ... https://pjreddie.com/darknet/yolo/ Yolo...

    YoloV1:https://arxiv.org/abs/1506.02640
    YoloV2:https://arxiv.org/abs/1612.08242
    YoloV3:https://arxiv.org/abs/1804.02767

    官网:
    https://pjreddie.com/darknet/yolov2/
    https://pjreddie.com/darknet/yolo/

    第三方实现:
    https://github.com/eriklindernoren/PyTorch-YOLOv3#train
    https://github.com/wlguan/Stronger-yolo
    https://github.com/TencentYoutuResearch/ObjectDetection-OneStageDet/tree/master/yolo

    YoloV1:You Only Look Once:Unified, Real-Time Object Detection

    0 摘要

    作者提出了一种新的目标检测方法YOLOV1,先前的目标检测算法都是利用分类器进行检测。相反,YoloV1将目标检测当作回归问题进行处理,获取图像上各目标的位置及类别信息。YoloV1使用单个神经网络在一次前向推理中从整幅图像上预测各目标的边界框和类别信息。由于整个检测过程只使用了单个网络,因此可以直接以检测性能为评价标准进行端到端的优化。

    YoloV1的处理速度非常快,基础YoloV1网络处理速度可以达到45 fps,更小版本的网络Fast YoloV1可以达到155 fps,同时mAP仍然是其他实时检测器的两倍。与其他检测算法相比,Yolo的缺点在于定位精度不够、不擅长检测小目标

    1 简介

    当前的目标检测系统一般都是利用分类器来执行目标检测。为了完成检测任务,这些系统缩放测试图像,并对不同位置的图像子块进行分类评估。可变形部件模型(DPM)使用滑动窗口,在整个图像上均匀的采集图像子块并对其进行分类以判别是否包含特定目标。R-CNN使用区域proposal方法首先在图像中生成潜在的边界框,然后在这些建议的框上运行分类器。分类后,使用后处理修正边界框,消除重复检测。RCNN的处理流程复杂、速度慢且难以优化。

    在这里插入图片描述

    作者将目标检测问题当作单个回归问题,使用单个卷积网络一次性从图像像素中回归出边界框坐标和类别概率。整个处理过程简洁明了,如图1所示。YoloV1以整幅图像为输入进行训练并直接优化。其优点有:

    1. 检测速度非常快,基础版本可以达到45fps,快速版本可以达到155fps;
    2. 在进行目标检测时,YoloV1是对输入图像整体进行响应。与滑动窗口和基于区域提议的技术不同,YoloV1在训练和测试时查看整幅图像,因此它隐式编码了图像的全局信息。Fast R-CNN是目前效果最好的目前检测算法,但因为它无法看到更大的目标上下文区域,因此更容易把背景区域误检为目标。与Fast R-CNN相比,YoloV1的误检数更少。
    3. YoloV1学习了目标的泛化表示。基于自然图像集进行模型训练并对艺术品图像进行目标检测时,YoloV1的检测效果大大优于DPM和R-CNN等方法。由于YoloV1具有很高的通用性,因此在应用于新领域的输入图像时,其误检率相对较低。

    YoloV1的缺点:
    YoloV1在准确性方面仍然落后于最先进的检测算法。虽然检测速度快,但它不擅长进行小目标的检测,另外对目标的定位精度也不够

    2 核心思想

    YoloV1将输入图像送入CNN,经过卷积、池化等操作后,得到了大小为S×SS \times S的feature map,该feature map的每一个点就对应于输入图像上的一个子块,相当于把输入图像划分成了S×SS \times S个网格。如果某个目标的中心点位于某网格中,则该网格负责该目标的检测,如图2中,狗的中心点位于(5,2)处,则(5,2)这一网格就负责狗的位置和类别预测。

    每个网格预测B个边界框,这些框的位置大小各不相同,基本可以覆盖整个图像上可能出现的目标。每个框的预测内容包括置信度、类别信息和位置信息

    • 置信度表示该网格中是否包含目标,将置信度定义为Pr(Object)IOUpredtruthPr(Object)* IOU^{truth}_{ pred}。即如果某网格中不包含目标,则置信度为零。如果某网格中包含目标,则其置信度为预测框和真实框之间的IOU。
    • 每个网格还预测C个类别概率Pr(ClassiObject)Pr(Class_i|Object),即在某网格包含目标(置信度大于0)的情况下预测目标的类别,注意只对一个网格预测一组类概率(类别信息对网格内的B个框是共享的)
    • 位置信息包括x,y,w,h四个值,(x,y)表示预测框的中心相对于该网格边界的位置;w和h表示预测框的宽高相对于整个图像宽高的比例。

    在POLCAL VOC数据集上,作者设置S = 7,B = 2。因为PASCAL VOC有20个类,因此C = 20。最终预测值大小为7×7×(5*2 + 20) = 7×7×30的张量。

    通俗来说,YoloV1的处理过程是将一副图像分成S*S个网格,包含目标中心的网格负责对目标进行检测。每个网格只输出一组目标类别置信度,也就是VOC中的20个类别的概率。每个网格预测B个box,每个box包含五个值,分别是x,y,w,h和置信度。置信度为预测的box和真实box之间的IOU,坐标(x,y)为box的中心点相对于该网格的相对位置,w和h为box相对于图像整体宽高的相对比例。

    三个值得注意的细节:

    1. YoloV1没有先验框,而是直接在每个区域预测框的大小和位置,是一个回归问题。这样做能够成功检测的原因在于,网格本身就包含了一定的位置信息,另外被检测物体的尺度在一个可以回归的范围内;
    2. 一个网格中的两个框共用一个类别预测,在训练时会选择和ground-truth IOU更大的那个框,在测试时会选择置信度更大的框,因此每幅图像最多预测7 * 7 = 49个目标;
    3. YoloV1采用了目标类别和置信度分开的预测方法,这点和RCNN系列不同。

    在这里插入图片描述

    2.1 网络设计

    普通Yolo网络有24个卷积层,后面是2个全连接层。每一个网络块都首先使用1×1卷积层缩减输出通道数以减少计算量,后跟3×3卷积层。完整的网络如图3所示。

    在这里插入图片描述
    Fast YOLO使用9个卷积层,并且在这些层中滤波器数量也更少。

    除了网络的大小不同,YOLO和Fast YOLO之间的所有训练和测试参数都是相同的。

    网络的最终预测输出是7×7×30的张量。

    2.2 训练

    网络结构
    作者首先使用ImageNet数据集预训练图3所示网络的前20层,然后在检测数据集上微调网络。前面已经有论文证明了在预训练网络上添加卷积和全连接层可以提高性能。这里作者在预训练模型上添加了四个卷积层和两个全连接层,新添加层随机初始化权重。因为检测通常需要更加细粒度的视觉信息,因此作者将网络的输入分辨率从224×224增加到448×448。

    数据标注
    网络的最后一层预测了目标的类概率和边界框坐标。作者将边界框宽度和高度归一化为和图像宽度和高度的比例,使它们的取值介于0到1之间。我们将边界框x和y坐标参数化为相对于特定网格起始位置的归一化偏移量,因此它们也在0到1之间,也就是预测边界框的中心减去网格的左上角坐标再除以网格宽高之后的值。

    激活函数
    网络的最后一层使用线性激活函数,其他层使用以下leaky relu激活函数:
    在这里插入图片描述
    损失函数
    训练过程中使用下述损失函数:
    在这里插入图片描述
    1iobj1_i^{obj}表示网格i中包含目标的示性函数,1ijobj1_{ij}^{obj}表示网格i中第j个预测框包含目标的示性函数。损失函数中,前两行是包含目标时各box的定位损失;第三行是包含目标时各box的置信度损失;第四行表示某box不包含目标时的损失,此时就只有置信度损失;最后一行表示各网格的类别置信度损失。

    训练的目标是最小化模型输出的误差的平方和。之所以使用求和平方误差,是因为它很容易优化,但它与真正的目标检测指标(最大化mAP)并不完全一致。由于在训练图像中,大部分网格不包含任何目标,如果对定位误差与分类误差相等地加权,会将所有网格的“类别置信度”分数推向零,这可能造成训练不稳定,导致在早期训练过程出现离散。为了解决这个问题,作者增加了边界框坐标预测损失的权重,并减小了不包含对象的box的置信度预测损失的权重。作者使用了两个参数,λcoord和λnoobj来实现这一目的。设置λcoord= 5和λnoobj=0.5。

    损失函数中对大尺度目标和小尺度目标的定位误差进行了相等加权,但同样的偏差对于大目标的影响要比对小目标的影响小,为了解决这个问题,损失函数中预测边界框宽度和高度的平方根,而不是宽度和高度(假设,两个正方形目标,一个尺度是49,另一个尺度是9,定位偏差3对于大目标的影响是3/49,对于小目标的影响是3/9。改成预测目标的尺度的平方根后,对于大目标的影响是3\sqrt{3}/7,对于小目标的影响是3\sqrt{3}/3,改变前后的影响程度比由 49/9 减小为 7/3)。

    YOLO中每个网格预测多个边界框。在训练时,我们根据哪个预测框和真实框之间的IOU最高,将该预测器指定为负责目标的预测。这导致每个预测器具有了对某些大小、宽高比或目标类别的预测偏好,从而提高了整体召回率。

    超参数
    作者在PASCAL VOC 2007和2012的训练和验证数据集上训练了大约135个epoch。训练过程中,batch大小为64,动量为0.9,衰减为0.0005。

    训练过程中的学习率为,第一个epoch,慢慢将学习率从10-3提高到10-2,这是因为如果从高学习速度开始训练,模型通常会因梯度不稳定而发散。后面以10-2进行了75个epoch的训练,然后以10-3进行30个epoch的训练,最后以10-4进行30个epoch的训练。

    为避免过拟合,使用了dropout和大量数据扩充。在第一个连接层之后,drop比例为0.5。
    数据增强,我们引入了高达原始图像大小20%的随机缩放和变换。我们还在HSV颜色空间中随机调整图像的曝光和饱和度将图像扩充了1.5倍。

    2.3 测试

    就像在训练中一样,预测是也只需要一次网络推理。在PASCAL VOC上,网络对每个图像预测98个边界框和每个框的类概率,然后保留置信度最高的49个框用于阈值过滤和NMS处理,得到最终的预测结果。

    每个网格预测B个不同尺度的目标的设计保证了预测的空间多样性。通常很清楚一个目标落入哪个网格单元,并且网络仅为每个对象预测一个框。但是,一些大型目标或靠近多个网格边界的目标可以被多个网格定位,非最大抑制可解决重复检测。NMS将Yolo的mAP增加了2 - 3%。

    2.4 YoloV1的缺点

    YOLOV1对边界框预测施加了强大的空间约束,因为每个网格单元只预测两个框,并且只能有一个类。此空间约束限制了我们的模型可以预测的相邻目标的数量。因此,YoloV1不擅长成群的小目标的检测

    由于我们的模型学习从数据中预测边界框,因此很难对新的或不常见的宽高比和尺度泛化的很好。

    因为网络结构包含了多个下采样层,用于预测的特征的空间尺寸较小,因此目标的定位精度较差。

    YoloV1的损失函数中,大尺度目标的定位损失权重和小尺度目标的定位损失权重是一样的,这会导致同等比例的定位误差,大尺度目标的损失会比小目标大,小尺度目标的损失在总损失中占比较小,会带来定位的不准确。

    Yolo的主要误差是定位误差

    3 实验

    3.1 和其他算法进行效果对比

    比Yolo快的没有它准;比Yolo准的没有它快。
    在这里插入图片描述

    3.2 误差分析

    检测结果类型:

    • 正确:正确分类,IOU > 0.5;
    • 定位错误:正确分类,0.1 < IOU < 0.5;
    • 相似:类别相似,IOU > 0.1;
    • 其他:错误分类,IOU > 0.1;
    • 背景:和任何目标的真实框之间的IOU都小于0.1。

    在这里插入图片描述
    Yolo主要误差是定位误差。Fast R-CNN相比于YoloV1,定位误差更少,但将背景误分类为目标的比例更高。

    4.3 将Fast R-CNN和Yolo结合

    由于Yolo和Fast R-CNN的误差类型不同,将两者结合可以取得更好的结果。作者将Fast R-CNN预测的每一个目标也送入yolo中进行预测,如果两者的预测结果很接近,则增大其为目标的概率。

    YoloV2:YOLO9000:Better, Faster, Stronger

    1 核心思想

    在这里插入图片描述
    与现有最先进的检测系统相比,YOLOV1存在一些缺点。与Fast R-CNN相比,YOLOV1的错误主要是有大量的定位误差。此外,与基于区域提议的方法相比,YOLOV1具有相对较低的召回率。因此,本文在保持分类准确性的情况下主要关注改善召回率和定位精度。

    计算机视觉领域趋向于使用更大、更深的网络,通常通过训练更大的网络或将多个模型集合在一起取得更好的效果。但是YOLOv2是速度很快的更加准确的检测网络。作者不是在YoloV1的基础上扩展网络,而是简化网络,但是却学习到了更加鲁棒的特征。

    YoloV2从网络结构改善、先验框设计和训练技巧3个方面改善了检测效果。

    1.1 网络结构改善

    YoloV2提出了一个全新的网络结构,称为DarkNet。原始的DarkNet拥有19个卷积层和5个池化层,在增加了一个Passthrough层后一共拥有22个卷积层,精度与VGGNet相当,但浮点计算量只有VGGNet的1/5左右,推理速度很快。

    相比于V1版本的网络,网络的主要改进有:
    在这里插入图片描述

    使用了BN层:BN层有助于解决反向传播中的梯度消失和爆炸,可以加速模型的收敛,同时还具有一定的防止过拟合的作用。通过在所有卷积层上添加BN层,mAP提高了2%。因为使用了BN层,所以删除了dropout而没有造成过拟合。

    使用更小的卷积核:YoloV2中起始网络层使用连续的3 * 3 卷积代替YoloV1中的7 * 7卷积,这样既减少了计算量,又增加了网络深度。

    Passthrough层:DarkNet还进行了深浅特征的融合,具体方法是将浅层的26 * 26 * 512的特征映射变换为13 * 13 * 2048的特征映射,然后和深层13 * 13 * 1024的特征在通道方向进行拼接。这种融合后的特征有助于小目标的检测,带来了1%的mAP的提升。

    多阶段训练:最先进的检测算法都使用在ImageNet上预先训练的分类器进行微调。从AlexNet开始,大多数分类器的输入图像都是256×256的图像。YOLOV1输入224×224图像训练分类网络,然后将分辨率提高到448x448训练检测网络。这意味着模型需要在学习如何进行目标检测的同时还要适应输入分辨率的变化。

    因此在YOLOv2中,作者改变了思路,采用了多阶段训练的做法。第一步,使用以224 x 224输入的ImageNet预训练模型;第二步,将ImageNet图像放大到448×448,对分类网络进行10个epoch的微调,让网络首先适应放大后的图像尺度;第三步,对448 x 448输入的分类网络去掉卷积层,在DarkNet上增加PassThrough层及3个卷积层,进行微调实现检测任务。这种多阶段训练方式使检测的mAP增加了近4%。

    单个网格检测多类别目标:YoloV1中是单个网格只有一个分类信息,因此一个网格只能预测一个类型的目标,这造成了其对密集的小目标检测效果不佳。YoloV2改变思路,一个网格预测5个框,但每个框有自己的类别信息,因此每个框输出25个值,分别是类别信息(VOC数据集,20个类别)+4个坐标信息+1个置信度。对于一个网格,共输出了5 * 25 = 125个值,因此DarkNet最后一层为1 * 1 * 125的卷积层,保证了最终feature map的每一点处对应125个输出值。

    1.2 使用先验框

    YOLOV2借鉴了Faster R-CNN中Anchor box的设计,不再使用模型直接预测目标的位置,而是预测目标和anchor box之间的偏差,降低了预测难度。使用anchor box,检测的mAP略有下降,但召回率提升了7%。

    先验框的选择:Faster R-CNN中是手工进行先验框的选择,YOLOV2不是手动选择先验框,而是在训练集的边界框上运行k-means聚类得到先验框的尺度和长宽比信息。如果使用欧式距离作为K-Means的度量标准,那么较大的框比较小的框会产生更大的误差。然而,真正较好的先验框和框的大小无关,而是与目标和先验框之间的IOU正相关。因此,作者提出了下述距离度量标准:

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

    centroid是聚类时被选作中心的先验框,box表示其它候选先验框,d就是两者间的“距离”。候选框和聚类中心框的IOU越大,“距离”越近。

    预选框的数量越多,平均IOU越大,但计算量也会越大,下图2左图给出了预选框数量和平均IOU之间的关系。作者综合考虑计算复杂度和召回率之间的权衡,选择k = 5。聚类结果如图2右图所示,矮宽的box较少、高窄的box较多,与手工设计的Anchor box明显不同。

    在这里插入图片描述
    下图给出了聚类时使用不同聚类中心数和不同度量标准的平均IOU的变化。可以看出,使用IOU作为度量标准时,5个聚类中心的平均IOU和使用欧式距离作为度量标准时的9个聚类中心的平均IOU相当。
    在这里插入图片描述
    直接进行位置预测:将YOLOV2和Anchor Box结合时,作者遇到了训练不稳定的问题,特别是在训练早期。作者分析训练不稳定主要是由于直接预测框的中心点位置(x,y)。在Faster R-CNN中,网络预测值是txt_xtyt_y,中心点坐标(x,y)计算公式如下:

    x=(txwa)+xay=(tyha)+yax = (t_x * w_a) + x_a \\ y = (t_y * h_a) + y_a

    例如,tx = 1时,预测框会向右移动anchor box的宽度,tx = -1时预测框会向左移动anchor box的宽度。

    作者认为上述预测方式没有对预测偏移进行限制,导致预测框可以出现在图像的任何位置,尤其是在训练初始阶段,。一开始的随机初始化使得模型需要很长时间才能稳定以预测合理的偏移。

    我们不是预测偏移,而是遵循YOLO的方法,预测相对于网格位置的位置坐标。这将真值限制在0到1之间。我们使用logistic激活函数来约束网络预测落在此范围内。

    网络对输出特征图中的每个网格预测5个边界框。网络对每一个边界框预测5个坐标,tx,ty,tw,th,tot_x,t_y,t_w,t_h,t_o。预测值的计算公式为:
    在这里插入图片描述在这里插入图片描述

    • cxc_xcyc_y代表目标中心点所在网格的左上角坐标,pwp_wphp_h表示当前先验框的宽高,如图3中的虚线框所示;
    • σ(cx),σ(cy)\sigma(c_x),\sigma(c_y)表示预测框的中心点相对于目标中心点所处网格的左上角的偏移量,加上cxc_xcyc_y就得到了预测框的中心点坐标;
    • twt_wtht_h为预测的宽高偏移量,先验框的宽高乘以指数化后的宽高偏移量,即得到预测框的宽高;
    • σ\sigma函数的作用是将坐标偏移限制在(0,1)之间,这样得到的预测边框的中心坐标(bx,by)(b_x,b_y)会限制在当前网格内,保证一个网格只预测中心点在该网格内的目标,有利于模型收敛;
    • YoloV2将σ(t0)\sigma(t_0)作为置信度的预测值。

    1.3 训练技巧

    多尺度训练:YoloV2训练过程中不是固定输入图像大小,而是每隔几次epoch就改变输入的尺寸。由于网络的下采样倍数为32,因此作者从32倍数中随机选取输入分辨率:{320,352,…,608}。最小的输入分辨率是320×320,最大的输入分辨率是608×608。

    多尺度训练可以迫使网络学习如何在多种输入尺度上进行目标检测,因此单个模型可以对不同分辨率的输入图像进行检测。想要速度快,就减少输入分辨率;想要精度高,就增大输入分辨率。

    YoloV2与其他算法的准确率和效率的对比如图4所示。

    在这里插入图片描述

    2 实验

    表3,4,5为YOLOv2与其他最先进的检测算法的性能对比。
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述

    YoloV3:An Incremental Improvement

    0 摘要

    我们向YOLO提供一些更新!我们做了一些小的设计更改,以使其更好。我们还训练了这个非常庞大的新网络。它比上次有点大,但更准确。它仍然很快,不用担心。在输入为320×320时,YOLOv3以运行22毫秒运行,取得了28.2的mAP,与SSD一样准确,但速度提高了三倍。当我们查看旧的.5 IOU mAP检测指标时,YOLOv3非常好。它在Titan X上以51毫秒内达到57.9 的AP50。相比之下,RetinaNet在198毫秒内达到57.5的AP50,性能相似,但速度提高了3.8倍。

    1 核心内容

    1.1 新网络结构DarkNet53

    YoloV3吸收了其他检测网络的思想,引入了残差网络和特征融合,提出了DarkNet-53这一最新的网络结构。
    在这里插入图片描述
    在这里插入图片描述
    上图引用自:https://zhuanlan.zhihu.com/p/40332004

    • 网络中使用了残差结构,有助于解决深层网络的梯度弥散;
    • 使用了3个尺度的特征分别检测不同尺度的目标;
    • 使用stride为2的卷积层代替池化层,下采样倍数同样为32;
    • 上采样方式是上池化,即采用元素复制扩充的方式扩大feature map,特征结合的时候使用的是通道方向的concatenate,不是逐像素点相加。

    YoloV3的速度没有之前的版本快,而是在保证实时检测的情况下努力提升检测精度。YoloV3还提供了一个tiny-DarkNet网络,用于更快速的目标检测。

    在这里插入图片描述

    1.2 多尺度预测

    如上节所示,YOLOv3预测3种不同尺度的box,做法和FPN类似。但YoloV3中每一个网格预测框的数量是3个,并且默认基于coco数据集进行测试,因此对每个尺度的每个feature map点处预测3个框,每个框的信息有4个位置偏移、1个包含目标的置信度和80个类别得分,因此最终的输出为N×N×[3 *(4 + 1 + 80)] = N x N x 255,所以这也是上图中所有尺度的最后的一个卷积层都是255个channel。

    作者仍然使用k-means聚类来确定先验框。因为现在是3个尺度,所以作者一共预测了9个先验框,每个尺度3个。在COCO数据集上,9个先验框的大小分别为:(10×13),(16×30),(33×23),(30×61),(62×45),(59×119),(116×90),(156×198),(373×326)。前三个对应scale 1,用于预测小目标;中间3个对应scale 2,用于预测中等目标;最后三个对应scale 3,用于预测大目标。

    yolov3的预测结果和YoloV2一致,为:
    bx=σ(tx)+cxby=σ(ty)+cybw=pwetwbh=phethb_x = \sigma(t_x) + c_x \\ b_y = \sigma(t_y) + c_y \\ b_w = p_w e^{t_w} \\ b_h = p_h e^{t_h}

    在训练过程中,作者使用误差的平方和作为损失函数。如果真实坐标是t^\hat t_*,预测值是tt_*,则梯度为t^t\hat t_* - t_*

    YOLOv3使用逻辑回归预测每个边界框是否包含目标的得分。如果一个先验框比其他先验框与某个真实目标的IOU更大,该先验框的类别标注就是1。如果某一个先验框与ground-truth之间的IOU不是最大的,但也超过了设定的IOU阈值,训练过程中应该忽略这个先验框。作者设置IOU阈值为0.5。这个标注标准和Faster R-CNN不同,为每一个真实目标只选择了一个先验框。

    1.3 使用logistic代替softmax进行类别预测

    softmax需要类别是互斥的,而多个logistic回归则没有该要求,可以实现多类别的预测,如一幅图像既属于women类,又属于person类。实验证明,实验多个二分类器代替softmax分类器,并没有降低检测精度。

    2 实验效果

    如表3所示,YoloV3效果很好。 就COCO而言,mAP与SSD相当,但速度快3倍。效果比RetinaNet略差。

    在这里插入图片描述
    原来的Yolo不擅长检测小目标。但是,现在我们看到了这种趋势的逆转。通过新的多尺度预测,我们看到YOLOv3具有相对较高的APs性能。但是,它在中型和大型目标上的性能相对较差。YoloV3的主要缺点依然是定位精度较差。

    AP50-速度的曲线见图5,可以看到YOLOv3与其他检测系统相比具有显著的优势。也就是说,它更快更好。

    在这里插入图片描述

    工程部署

    作者在Yolo的官网提供了320,416,608大小的YoloV3的cfg文件和预训练模型。另外,作者还提供了一个小型的模型,YoloV3-Tiny的cfg文件和预训练模型。YOLOv3-tiny虽然速度进一步提升,但其mAP下降较多。

    工程上可以使用TensorRT进一步优化YoloV3的时间效率。

    使用TensorRT有两条实现路径:

    • 一是直接将draknet版本的yoloV3模型转换为TensorRT的序列化引擎;
    • 二是从mxnet的Gloun获取yoloV3模型,将其转换为mxnet模型,进一步再通过onnx将其转换为TensorRT序列化引擎。

    这里研究第一条路径的实现。参考代码为https://github.com/NVIDIA-AI-IOT/deepstream_reference_apps/tree/master/yolo

    这里的代码主要包含了三部分内容,一是基于TensorRT实现YoloV2/YoloV3,二是将YoloV2/YoloV3做成gstreamer插件,三是将一系列的gstreamer插件组合起来组成deepstream应用。这里重点分析基于TensorRT实现YoloV2/YoloV3的代码。

    主函数为apps/trt-yolo/trt-yolo-app.cpp,核心代码位于lib/文件夹下。

    主函数中首先读取配置文件,使用gflags解析文件获取设置的参数。然后根据设置的网络类型去生成的对象,这里支持YoloV2,YoloV2-tiny,YoloV3,YoloV3-tiny四种网络。

    代码的处理流程为在Yolo构造函数中解析要检测的类别、模型cfg文件,然后依据使用的数据类型创建对应的TensorRT Engine。

    • 在创建TensorRT Engine的过程中,首先读取了预训练.weights模型的权重,然后按照流程创建了TensorRT的logger和network,设置了网络的输入,这里创建了一个和输入数据同样大小值为255.0的常量层,然后使用逐元素相除操作将输入数据的值归一化到了0 - 1之间。因为使用了两种不同的池化(输出和输入相等的池化、普通池化),因此设置了池化层的输出大小。接下来对每一个网络层(包括卷积层、shortcut层、yolo输出层、region层、reorg层、route层、upsample层和maxpool层),都使用了TensorRT的函数进行了实现。

      • 卷积层 :YoloV3中的卷积层由卷积层、BN层实现,使用leaky relu作为激活函数。代码实现过程中首先读取BN层的偏差γ\gamma和权重β\beta,然后读取训练过程中当前层激活值的均值和方差,由于在CNN中使用BN层的时候是针对每一个feature map计算了一组β\betaγ\gamma,对应也是针对每一个feature map计算了一组均值和方差,因此这里读取这些值的时候也是按照feature map的个数也就是滤波器的个数去读取的。然后读取了卷积层的权重,卷积层的偏置全部设置为0,使用network->addConvolution函数和卷积层的权重设置了TensorRT中的卷积层,进一步指定了卷积层的名称、stride、pad等信息。对于BN层,因为其操作就是减均值、除方差的操作,因此是使用network->addScale结合权重系数进行创建的。对于leaky relu激活函数,是使用TensorRT的PRELU插件进行创建的,同时设置负值部分的系数为0.1。这里需要注意的是到目前为止,TensorRT并不支持真正的pRelu操作,需要自己实现pRelu插件。
      • shortcut层:该层就是实现两个尺寸相同的层对应像素直接相加的操作,是通过m_Network->addElementWise层进行实现的。
      • yolo输出层:这是输出检测信息的网络层,YoloV3中进行了多尺度检测,因此共在三个尺度上输出了检测信息。在该层的实现中,首先获取该层的输出大小为gridSize * gridSize * numBBoxes * (5 + numClasses)。该层的实现是通过自定义插件来实现的。
      • route层:route层包括两种,两个输入的route层是两个输入在通道方面的级联,调用了m_Network->addConcatenation函数。单个输入的route层,就是把输入当作了输出。
      • upsample层:完成输入数据的空间上采样操作。代码实现中是通过设计处理矩阵结合network->addMatrixMultiply实现的。
      • maxPool层:是通过network->addPooling函数实现最大池化操作的。

    在将各层通过TensorRT进行实现之后,就调用了m_Builder->buildCudaEngine完成了TensorRT Engine的创建,并将其保存成本地文件。后续再使用该Engine时,如果判断该Engine文件存在则直接读取该文件,并进行反序列化操作得到运行时上下文环境。

    之后就是对输入图像进行推理的过程,首先读取图像,保持长宽比将输入图像的长边变换到模型的预设输入值(例如为608),对于图像的短边,则是添加border使用常量进行扩充使得其大小变成608 * 608。然后进行颜色变换,BGR -> RGB。这里作者提到了一个opencv的变换函数cv::dnn::blobFromImages,可以很方便的完成图像的缩放、中心裁剪、减均值、乘系数的操作,并将最后的结果转换为4维blob。

    对输入图像完成变换之后,可以调用引擎对输入数据进行推理操作。

    推理完成之后,获得了三个尺度的检测框。根据YoloV3的理论,每一个尺度的输出,都是gridSize * gridSize * numBBoxes * (5 + numClasses)的大小。对于每一个网格中的每一个box而言,首先获取其对应的anchor box的大小,然后依次去读取检测框的中心点x,y坐标和宽、高及当前box包含目标的概率等信息。这里由于将各网格的尺寸当作1来处理,所以模型前向运算计算的结果就是当前box的中心点距离其所属的网格的左上角的距离,距离也是归一化到了 0 到 1之间的,也就是对于坐标中心点,模型前向运算的输出就是σ(tx)\sigma(t_x)σ(ty)\sigma(t_y)。对于box的宽高,模型前向运算的输出就是etwe^{t_w}ethe^{t_h}。接着获取当前box中包含的目标的类别概率向量,将当前box包含目标的概率与该目标的类别概率相乘,取其最大值得到当前box包含的目标的类别概率。对于大于指定类别阈值的目标box,将获取的目标坐标乘以stride,进行边界控制,平移、缩放之后得到目标box在原始图像分辨率下的位置信息。

    最后,对三个尺度检测到box按照类别进行NMS处理,消除重复的检测框,从而完成整个的目标检测过程。在YoloV3的实现代码里,充分体现了作者论文中提出的多尺度预测、直接预测bounding box的坐标而不是偏移量、使用了聚类得到的anchor box作为基准,在YoloV3中也使用了darknet53作为特征提取网络,这些点与作者论文中提出的思想完全对应。

    在基于TensorRT实现的YoloV3代码中,还可以通过将float32转换成float16或int8进一步提升推理效率,这部分内容为TensorRT的通用内容,与Yolo关系不大,这里不再赘述。

    展开全文
  • YoLo

    2018-04-17 21:07:29
    yolo的过程非常简单。就是每次输入一整张的图片,文中作者选择resize到了448×448448×448448\times 448。然后输出是147014701470维的向量。其中1470=7×7×(20+2×5)1470=7×7×(20+2×5)1470=7\times...
  • 一文看懂YOLO v3

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

    千次阅读 2019-08-22 22:31:10
    YOLO v1-v3 理论部分推荐博客 yolo-v1 yolo-v2 yolo-v3 yolov3代码理解推荐博客 从零开始用 PyTorch 实现 YOLO (v3) 是什么体验
  • 睿智的目标检测11——Keras搭建yolo3目标检测平台

    万次阅读 多人点赞 2019-11-27 17:33:51
    睿智的目标检测11——Keras搭建yolo3目标检测平台学习前言yolo3实现思路一、预测部分1、主题网络darknet53介绍2、从特征获取预测结果3、预测结果的解码4、在原图上进行绘制二、训练部分计算loss所需参数1、y_pre2、y...
  • YOLO v3网络结构分析

    万次阅读 多人点赞 2018-07-26 12:07:09
    相信阅读了YOLO v3论文的小伙伴们会发现为什么这次的论文篇幅这么少?除去参考文献就四面?Excuse me?我是下了篇假文献吧。读完后感觉内容确实不多,而且总感觉写的不够细致,很多地方都比较模糊,可能是作者想让...
  • YOLO系列之yolo v1

    万次阅读 多人点赞 2018-09-10 13:17:48
    yolo v1发表在CVPR2016上,是经典的one-stage检测算法。 论文标题: 《You Only Look Once: Unified, Real-Time Object Detection》 论文地址:https://arxiv.org/pdf/1506.02640.pdf v1是yolo系列的开山之作...

空空如也

1 2 3 4 5 ... 20
收藏数 12,893
精华内容 5,157
关键字:

yolo