YOLO v1,YOLO v2,YOLO9000算法总结与源码解析

YOLO出自2016 CVPR 《You Only Look Once:Unified, Real-Time Object Detection》。YOLO将目标区域定位于目标类别预测整合于单个神经网络模型中,实现了在准确率较高的情况下快速目标检测与识别,YOLO达到了45帧每秒,Fast YOLO达到了155帧每秒,适用于实时的目标检测。

图1

YOLO利用单个卷积神经网络,将目标检测问题转换为直接从图像中提取bounding boxes和类别概率的回归问题。整个检测过程分为3个阶段:
(1)将图像缩放到448*448
(2)通过神经网格进行检测和分类
(3)NMS抑制,输出最终结果
具体地,YOLO首先将图像分为S*S的格子(grid cell)。如果一个目标的中心落入格子,则该格子就负责检测该目标(如下图)。每个格子(grid cell)预测B个边界盒(bounding box)和C类判别属性(最终输出S*S*(B*5+C)维向量)。每一个边界盒包含5个值:x,y,w,h(分别为边界盒中心点横、纵坐标,宽,高)和边界盒包含目标的置信值confidence。置信值为格子包含目标的概率与IOU的乘积。每个格子预测包含某一类目标的条件概率值。每个bounding box通过对应格子的类别概率和box置信度相乘得到该类别的置信分数。这个分数衡量了该类别出现在box中的概率以及该box与目标的吻合程度。

在VOC上训练中,S=7,B=2,C=20,最终输出7*7*(2*5+20)维度的信息。

YOLO v1缺陷:
1.YOLO对相互靠的很近的物体(挨在一起且中点都落在同一个格子上的情况),还有很小的群体 检测效果不好,这是因为一个网格中只预测了两个框,并且只属于一类。
2.测试图像中,当同一类物体出现的不常见的长宽比和其他情况时泛化能力偏弱。
3.由于损失函数的问题,定位误差是影响检测效果的主要原因,尤其是大小
物体的处理上,还有待加强。

2.YOLO v2简介
YOLO相对于目前最好的目标检测系统存在的问题是精确度不够。相对于Fast R-CNN,YOLO在目标定位方面错误率较高。YOLO v2是YOLO的升级版,作者采用了一系列的方法优化了YOLO的模型结构,产生了YOLO v2,在快速检测的同时准确率达到了state of the art,并且增强了定位精确度。

2.1为了达到更精确(Better)的目的,YOLO v2主要做了如下改进:

1 Batch normalization
神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的
分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度。
解决办法之一是对数据做一个归一化预处理。YOLOv2网络通过在每一个
卷积层后添加batch normalization,极大的改善了收敛速度同时减少了对其它regularization方法的依赖(舍弃了dropout优化后依然没有过拟合),使得mAP获得了2%的提升。

2 High Resolution Classifier
YOLOv2首先修改预训练分类网络的分辨率为448*448,在ImageNet数据
集上训练10轮(10 epochs)。这个过程让网络有足够的时间调整filter去适应高分辨率的输入。然后fine tune为检测网络,mAP获得了4%的提升。

3 Convolutional With Anchor Boxes
YOLO(v1)使用全连接层数据进行bounding box预测(将全连接层转换为S*S*(B*5+20)维的特征),这会丢失较多的空间信息,导致定位不准。
YOLOv2借鉴了Faster R-CNN中的anchor思想: 简单理解为卷积特征图上进行滑窗采样,每个中心预测9种不同大小和比例的建议框。由于都是卷积不需要reshape,很好的保留了空间信息,最终特征图的每个特征点和原图的每个cell一一对应。而且用预测相对偏移(offset)取代直接预测坐标简化了问题,方便网络学习。总的来说就是移除全连接层(以获得更多空间信息)使用 anchor boxes去预测 bounding boxes。并且,YOLOv2将预测类别的机制从空间位置(cell)中解耦,由anchor box同时预测类别和坐标(YOLO是由每个cell来负责预测类别,每个cell对应的2个bounding负责预测坐标)。

4 Dimension Clusters(维度聚类)
在使用anchor时,Faster-RCNN中anchor boxes的个数和宽高维度往往是手动精选的先验框(hand-picked priors),如果能够一开始就选择了更好的、更有代表性的先验boxes维度,那么网络就应该更容易学到准确的预测位置。YOLOv2中利用K-means聚类方法,通过对数据集中的ground truth box做聚类,找到ground truth box的统计规律。以聚类个数k为anchor boxes个数,以k个聚类中心box的宽高维度为anchor box的维度。

5 Direct location prediction
使用anchor boxes的另一个问题是模型不稳定,尤其是在早期迭代的时候。大部分的不稳定现象出现在预测box的(x,y)坐标时。YOLOv2中预测相对于grid cell的坐标位置,同时把ground truth限制在0到1之间,解决了模型随机初始化之后将需要很长一段时间才能稳定预测敏感的物体偏移的问题。

使用Dimension Clusters和Direct location prediction这两项anchor boxes改进方法,mAP获得了5%的提升。

6 Fine-Grained Features(细粒度特征)
YOLOv2使用了一种不同的方法,简单添加一个 passthrough layer,把浅层特征图(分辨率为26*26)连接到深层特征图。
passthroughlaye把高低分辨率的特征图做连结,叠加相邻特征到不同通道(而非空间位置),类似于Resnet中的identity mappings。这个方法把26*26*512的特征图叠加成13*13*2048的特征图,与原生的深层特征图相连接。
YOLOv2的检测器使用的就是经过扩展后的的特征图,它可以使用细粒度特征,使得模型的性能获得了1%的提升。

7 Multi-ScaleTraining
原始YOLO网络使用固定的448*448的图片作为输入,加入anchor boxes后输入变成416*416,由于网络只用到了卷积层和池化层,就可以进行动态调整(检测任意大小图片)。为了让YOLOv2对不同尺寸图片的具有鲁棒性,在训练的时候也考虑了这一点。
不同于固定网络输入图片尺寸的方法,每经过10批训练(10 batches)就会随机选择新的图片尺寸。网络使用的降采样参数为32,于是使用32的倍数{320,352,…,608},最小的尺寸为320*320,最大的尺寸为608*608。 调整网络到相应维度然后继续进行训练。
这种机制使得网络可以更好地预测不同尺寸的图片,同一个网络可以进行不同分辨率的检测任务,在小尺寸图片上YOLOv2运行更快,在速度和精度上达到了平衡。
在低分辨率图片检测中,YOLOv2是检测速度快(计算消耗低),精度较高的检测器。输入为228*228的时候,帧率达到90FPS,mAP几乎和Faster R-CNN的水准相同。使得其更加适用于低性能GPU、高帧率视频和多路视频
场景。
在高分辨率图片检测中,YOLOv2达到了先进水平(state-of-the-art)。

2.2为了达到更快速(Faster)的目的,YOLO v2主要做了如下改进:

1. Darknet-19
为了精度与速度并重,YOLOv2使用了一个新的分类网络作为特征提取部分,参考了前人的工作经验。类似于VGG,网络使用了较多的3*3卷积核,在每一次池化操作后把通道数翻倍。借鉴了network in network的思想,网络使用了全局平均池化(global average pooling)做预测,把1*1的卷积核置于3*3的卷积核之间,用来压缩特征。使用batch normalization稳定模型训练,加速收敛,正则化模型。最终得出的基础模型就是Darknet-19,包含19个卷积层、5个最大值池化层(max pooling layers )。

2. Training for classifier
作者使用Darknet-19在标准1000类的ImageNet上训练了160次,用随机
梯度下降法,starting learning rate 为0.1,polynomial rate decay 为4,weight decay为0.0005 ,momentum 为0.9。训练的时候仍然使用了很多常见的数据扩充方法(data augmentation),包括random crops, rotations, and hue, saturation, and exposure shifts。(参数都是基于作者的darknet框架)初始的224*224训练后把分辨率上调到了448*448,使用同样的参数又训练了10次,学习率调整到了10的-3次方。高分辨率下训练的分类网络top-1准确率76.5%,top-5准确率93.3%。

3. Training for detection
为了把分类网络改成检测网络,去掉原网络最后一个卷积层,增加了三个 3 *3 (1024 filters)的卷积层,并且在每一个卷积层后面跟一个1*1的卷积层,输出维度是检测所需数量。
对于VOC数据集,预测5种boxes,每个box包含5个坐标值和20个类别,所以总共是5*(5+20)= 125个输出维度。
也添加了passthrough layer,从最后3*3*512的卷积层连到倒数第二层,使模型有了细粒度特征。
学习策略是:先以10的-3次方的初始学习率训练了160次,在第60次和
第90次的时候学习率减为原来的十分之一。weight decay为0.0005,momentum为0.9,以及类似于Faster-RCNN和SSD的数据扩充(data augmentation)策略:random crops, color shifting, etc。使用相同的策略在 COCO 和VOC上训练。

3.YOLO9000简介
YOLO9000是在YOLOv2的基础上得到的,相比于YOLO v2,YOLO9000
具有更强大(Stronger)的检测功能,可以检测出更多的类别。作者提出了一种在分类数据集和检测数据集上联合训练的机制。使用检测数据集的图片去学习检测相关的信息,例如bounding box 坐标预测,是否包含物体以及属于各个物体的概率。使用仅有类别标签的分类数据集图片去扩展可以检测的种类。
训练过程中把监测数据和分类数据混合在一起。当网络遇到一张属于检测数据集的图片就基于YOLOv2的全部损失函数(包含分类部分和检测部分)做反向传播。当网络遇到一张属于分类数据集的图片就仅基于分类部分的损失函数做反向传播。 作者最后采用一种不要求互不包含的多标签模型(multi-label model)来整合数据集。这种方法忽略了数据集的结构(例如 COCO数据集的所有类别之间是互不包含的)。

1. Hierarchical classification(层次式分类)
WordNet是一个有向图结构(而非树结构),因为语言是复杂的(例如“dog”既是“canine”又是“domestic animal”),为了简化问题,作者从ImageNet的概念中构建了一个层次树结构(hierarchical tree)来代替图结构方案。最终结果是一颗 WordTree (视觉名词组成的层次结构模型)

2.Dataset combination with WordTree
使用WordTree把多个数据集整合在一起。

3.joint classification and detection(联合训练分类和检测)
使用WordTree整合了数据集之后就可以在数据集(分类-检测数据)上训练联合模型。我们想要训练一个检测类别很大的检测器所以使用COCO检测数据集和全部ImageNet的前9000类创造一个联合数据集。为了评估我们使用的方法,也从ImageNet detection challenge 中向整合数据集添加一些还没有存在于整合数据集的类别。相应的WordTree有9418个类别。由于ImageNet是一个非常大的数据集,所以通过oversampling COCO数据集来保持平衡,使ImageNet:COCO = 4:1。
使用上面的数据集训练YOLO9000。采用基本YOLOv2的结构,anchor box数量由5调整为3用以限制输出大小。
当网络遇到一张检测图片就正常反向传播。其中对于分类损失只在当前及其路径以上对应的节点类别上进行反向传播。当网络遇到一张分类图片仅反向传播分类损失。在该类别对应的所有bounding box中找到一个置信度最高的(作为预测坐标),同样只反向传播该类及其路径以上对应节点的类别损失。反向传播objectness损失基于如下假设:预测box与ground truth box的重叠度至少0.31IOU。
采用这种联合训练,YOLO9000从COCO检测数据集中学习如何在图片中寻找物体,从ImageNet数据集中学习更广泛的物体分类。
作者在ImageNet detection task上评估YOLO9000。ImageNet detection task和COCO有44个物体类别是相同的。这意味着YOLO9000只从大多数测试数据集中看到过分类数据而非检测数据。最终整体精度为19.7mAP,在从未见过的156个物体检测数据类别上精度为16.0mAP。这个结果高于DPM,但是YOLO9000是在不同数据集上进行半监督训练。而且YOLO9000可以同时实时检测9000多种其它物体类别。
作者也分析了YOLO9000在ImageNet上的性能,发现可以学习新的动物表现很好,但是学习衣服和设备这类物体则不行。因为从COCO数据集上动物类别那里学习到的物体预测泛化性很好。但是COCO数据集并没有任何衣服类别的标签数据(只有”人”类别),所以YOLO9000很难对“太阳镜”,“游泳裤”这些类别建模。

4.YOLO源码解析

4.1 train 解析
从main()方法(darknet.c中)开始,首先读取参数;
第一个参数是yolo,故跳转到run_yolo函数(yolo.c中);
第二个参数是train,所以跳转到了train_yolo函数(yolo.c中)。
第三个参数是cfg/yolo.train.cfg, 网络架构文件
第四个参数是预训练权重参数weightfile,预训练参数文件

4.1.1相关函数解析
网络参数解析函数:parse_network_cfg
1.首先创建一个list,取名sections,记录一共有多少个section(一个section存储了CNN一层所需参数);
2.然后创建一个node,该node的void类型的指针指向一个新创建的section;该section的char类型指针指向.cfg文件中的某一(line),然后将该section的list指针指向一个新创建的node,该node的void指针指向一个kvp结构体,kvp结构体中的key就是.cfg文件中的关键字(如:batch,subdivisions等),val就是对应的值;如此循环就形成了上述的参数网络图。


注:用矩形表示list,椭圆表示section,圆形表示node,六边形表示kvp,为了表达方便,我就把section和kvp放到了node里面

加载权重函数:load_weights(&net,weightfile)
1.调用load_weights_upto(net, filename, net->n)函数;
2.分别加载每一层的权重;

网络训练函数:train_network(network net, data d)
1.加载训练数据至网络中
2.调用train_network_datum(net, x, y)训练网络
3.调用forward_network(net, state); backward_network(net, state);
4.计算损失

4.2 test 解析
从main()方法(darknet.c中)开始,首先读取参数;
第一个参数是yolo,故跳转到run_yolo函数(yolo.c中);
第二个参数是test,所以跳转到了test_yolo函数(yolo.c中)。
第三个参数是cfg/yolo.cfg
第四个参数是预训练权重参数weightfile
第五个参数是filename,为待测试的图片文件

4.3 YOLO 代码框架总结
关于YOLO代码的框架,大概总结下darknet的优缺点。
优点:
1.代码依赖项少,只有cuda,甚至连opencv都可以不需要,如果在cpu平台,cuda都可以扔了(当然darknet的cup代码并没有做什么优化,跑起来就很慢)。可以较容易得将代码移植到其他平台;
缺点:
1.在darknet中,所有层的lr都一样,这对微调造成了很大的困难,因为微调需要把前面几层的lr都设置的很小很小,然后主要训练最后一层的权重
2.总的来说就是darknet的接口确实很差,如果想把网络改成inception或者resnet的构架,需要改大量的代码,这对于验证模型可行性来说,非常浪费时间。

补充:

YOLO v1训练流程:
1.输入图片,接受输入维度为([None, 448, 448, 3]);
2.随机初始化网络权重(若是基于已有的网络模型,则在已有的模型上进行微调);
3.根据各层初始化的权重,得到输出bounding box的初始位置(x,y,w,h),置信度(confidence),类别概率C,对于一张输入图片,输出为S*S*(5*B+C)维的向量,其中B=2,C=20,输出维度为输出维度为([None,1470]);
4.根据输出向量计算损失值(detection 层才有cost);根据损失值指导权重更新;
5.当达到最大迭代次数时结束训练;

YOLO v1测试流程:
1.输入测试图片;
2.根据网络模型计算输出向量,即为图片的cell预测的bounding box位置、置信度信息及类别概率信息;
3.每个网格预测的类别概率信息和每个bounding box预测的confidence信息相乘,得到每个bounding box属于某一类的置信得分(class-specific confidence score);对每一个网格预测的每一个bbox执行同样的操作:7*7*2=98 bbox(每个bbox既有对应的class信息又有坐标信息);

4.得到每个bbox的class-specific confidence score以后,设置阈值,滤掉得分低的boxes,对保留的boxes进行NMS处理,就得到最终的检测结果;

里写自定义目录标题)

欢迎使用Markdown编辑器

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

新的改变

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. 全新的界面设计 ,将会带来全新的写作体验;
  2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
  3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
  4. 全新的 KaTeX数学公式 语法;
  5. 增加了支持甘特图的mermaid语法1 功能;
  6. 增加了 多屏幕编辑 Markdown文章功能;
  7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
  8. 增加了 检查列表 功能。

功能快捷键

撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G

合理的创建标题,有助于目录的生成

直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

插入链接与图片

链接: link.

图片: Alt

带尺寸的图片: Alt

居中的图片: Alt

居中并且带尺寸的图片: Alt

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

如何插入一段漂亮的代码片

博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
var foo = 'bar';

生成一个适合你的列表

  • 项目
    • 项目
      • 项目
  1. 项目1
  2. 项目2
  3. 项目3
  • 计划任务
  • 完成任务

创建一个表格

一个简单的表格是这么创建的:

项目Value
电脑$1600
手机$12
导管$1

设定内容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列第二列第三列
第一列文本居中第二列文本居右第三列文本居左

SmartyPants

SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPEASCIIHTML
Single backticks'Isn't this fun?'‘Isn’t this fun?’
Quotes"Isn't this fun?"“Isn’t this fun?”
Dashes-- is en-dash, --- is em-dash– is en-dash, — is em-dash

创建一个自定义列表

Markdown
Text-to- HTML conversion tool
Authors
John
Luke

如何创建一个注脚

一个具有注脚的文本。2

注释也是必不可少的

Markdown将文本转换为 HTML

KaTeX数学公式

您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

你可以找到更多关于的信息 LaTeX 数学表达式here.

新的甘特图功能,丰富你的文章

Mon 06 Mon 13 Mon 20 已完成 进行中 计划一 计划二 现有任务 Adding GANTT diagram functionality to mermaid
  • 关于 甘特图 语法,参考 这儿,

UML 图表

可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:

张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

这将产生一个流程图。:

链接
长方形
圆角长方形
菱形
  • 关于 Mermaid 语法,参考 这儿,

FLowchart流程图

我们依旧会支持flowchart的流程图:

Created with Raphaël 2.2.0 开始 我的操作 确认? 结束 yes no
  • 关于 Flowchart流程图 语法,参考 这儿.

导出与导入

导出

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。


  1. mermaid语法说明 ↩︎

  2. 注脚的解释 ↩︎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
需要学习Windows系统YOLOv4的同学请前往《Windows版YOLOv4目标检测实战:原理与源码解析》,课程链接 https://edu.csdn.net/course/detail/29865【为什么要学习这门课】 Linux创始人Linus Torvalds有一句名言:Talk is cheap. Show me the code. 冗谈不够,放码过来!  代码阅读是从基础到提高的必由之路。尤其对深度学习,许多框架隐藏了神经网络底层的实现,只能在上层调包使用,对其内部原理很难认识清晰,不利于进一步优化和创新。YOLOv4是最近推出的基于深度学习的端到端实时目标检测方法。YOLOv4的实现darknet是使用C语言开发的轻型开源深度学习框架,依赖少,可移植性好,可以作为很好的代码阅读案例,让我们深入探究其实现原理。【课程内容与收获】 本课程将解析YOLOv4的实现原理和源码,具体内容包括:- YOLOv4目标检测原理- 神经网络及darknet的C语言实现,尤其是反向传播的梯度求解和误差计算- 代码阅读工具及方法- 深度学习计算的利器:BLAS和GEMM- GPU的CUDA编程方法及在darknet的应用- YOLOv4的程序流程- YOLOv4各层及关键技术的源码解析本课程将提供注释后的darknet的源码程序文件。【相关课程】 除本课程《YOLOv4目标检测:原理与源码解析》外,本人推出了有关YOLOv4目标检测的系列课程,包括:《YOLOv4目标检测实战:训练自己的数据集》《YOLOv4-tiny目标检测实战:训练自己的数据集》《YOLOv4目标检测实战:人脸口罩佩戴检测》《YOLOv4目标检测实战:中国交通标志识别》建议先学习一门YOLOv4实战课程,对YOLOv4的使用方法了解以后再学习本课程。【YOLOv4网络模型架构图】 下图由白勇老师绘制  

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值