学习YOLO系列的个人总结

编程入门 行业动态 更新时间:2024-10-19 01:22:25

学习YOLO<a href=https://www.elefans.com/category/jswz/34/1770787.html style=系列的个人总结"/>

学习YOLO系列的个人总结

最近这段时间学习了YOLO系列原理,也跑了pytorch_yolov4、darknet框架yolov4、pytorch_yolov3、dakrnet框架yolov3等模型。这里要感谢网上大佬们的博文,没有你们,自己要走很多弯路。

本篇博客主要是记录自己学习YOLO系列的历程,方便以后自己需要时及时地查询与巩固,内容包括YOLO的原理、windows系统下的yolo模型搭建、用yolov3和yolov4训练自己的数据集去检测目标以及网上我认为不错的博文。

推荐一个CV领域的相关论文下载网址:

内容

  • 一.简单的背景介绍
  • 二.YOLO的原理介绍
    • 1.个人认为比较好的博文
    • 2.相关补充与理解
    • 3.yolov3中关于darknet的配置文件yolov3.cfg剖析
    • 4.yolov3的源代码
    • 5.简述yolov3的预测过程
    • 6.yolov4
  • 三.搭建Yolo平台
    • 1.Pytorch——yolov4(GPU)
    • 2.Darknet——yolov4(GPU)
    • 3.Darknet——yolov3(CPU)
    • 4.Pytorch——yolov3(GPU)
  • 四.遇到的问题及解决办法
    • 1.关于给数据集打标签
    • 2.实测Pytorch_yolov3输出.pt权重转.weights权重
  • PS:提问

一.简单的背景介绍

在YOLO出来之前,常见的目标检测算法:
1.滑窗检测算法

①将目标检测的问题转化为图像识别的问题
②物体的位置是根据滑窗的位置确定的
③缺点:a.从图上可以看出,滑窗之间存在着很大部分的重叠,即存在大量的冗余,导致该方法效率低下。
b.滑窗算法最大的问题是只能看到滑窗部分里面的内容,不能看到整个目标。
这里推荐一篇论文,虽然时间比较早,但很经典,论文的下载可以去最上面的CV领域相关论文下载的网址。
为了解决滑窗算法的低效,引入了卷积神经网络

2.区域检测算法:采用某些算法,先从图像中找出可能存在目标的区域,然后只对这些区域进行目标检测。如select search

3.理解下神经网络解决对象分类和定位问题——边界框(bounding box)

4.目标检测进阶一(窗口滑动卷积算法)

二.YOLO的原理介绍

1.个人认为比较好的博文

(Yolo算法)

YOLOv1

YOLO v1深入理解

一文看懂YOLO v2

一文看懂YOLO v3

2.相关补充与理解

1.其中在YOLO中有好几种框,分别是:

2.对于目标的框选,也有几种框选的方式,如下:
①AABB——轴对齐的边界框
②RBOX——带旋转角度的边界框
③QUAD——圆形框

3.边界框的位置表示方式
绝对坐标:缺点:当图像进行缩放之后,绝对坐标便不起作用了。
尺度归一化:将坐标压缩到0——1之间,即使图像缩放也能表示目标的位置。
4.YOLO:将目标检测的问题当成回归来做(object detection -> regression),像之前的Fast-CNN采用的是将目标检测的问题转化为分类。
5.Yolov1

对上述图片中的中间部分进一步分析,如下:

①将图像分成7×7、13×13或S×S,判断每个格子中是否有要检测的目标,假设是7×7,则有49个格子,相比于滑窗中的大量重叠,明显这种效率高了许多。缺点:对于一些很小的目标,不能很好的识别出来,这也是YOLO v1的一个缺陷。
②如何知道哪个格子判断哪个目标?
假设以狗为例,以狗的中心点格子,判断这是狗(中心点是用来训练的),训练的过程中,物体的中心点落在哪个格子中就由哪个中心点预测,中心点的确定是由我们训练集中的标签决定的,这是设定好了的,由ground truth(格子的真值)生成,即训练时,只有中心的格子才有标签真值。
但到了测试集预测阶段中,就没有这种限制了,每个格子都有其他目标的可能性,上述图片展示的是测试推断的过程,而不是训练过程,所以看上去每个格子似乎都预测了东西,预测后出来的一个值,就是结果,该结果不需要ground truth再进行比较了。上述操作完成后,再进行NMS处理,最终得到结果。
6.在YOLOv1中,神经网络最后是全连接层,之后YOLO就改成了全卷积层 (FCN)

YOLOv1的缺点:
①与基于区域检测的方法相比,召回率相对较低;
②大量的定位错误;
7.YOLO v3的多尺度问题

上图图解:
①图中的数字指的是当前层的序号
②假设输入图像是3×608×608,先将其缩小至原图的1/32,608/32 = 19
③④表示上采样,即放大图像,这里的上采样用的是最近邻插值
⑤通过上采样扩大尺度,将其缩小至原图的/16
⑥通过上采样扩大尺度,将其缩小至原图的/8
可以发现,随着层数的增加,划分图像的格子越来越小

8.YOLOv3一共使用了9个anchor的框,它分了3个不同的尺度,每个尺度上又分了3个不同的框,(如YOLO v3的多尺度问题,分别缩小至原图的1/32、1/16、1/8)。

上图中的anchor是作者通过他的数据集聚类得到的anchor大小,具有一定的通用性,我们训练自己的模型时,可以通过自己的数据集Kmeans聚类得出属于适合自己数据集的anchor大小。
9.Yolov3原论文中有一个图

上图中的Cx,Cy那里表达不清楚,容易产生误解,这里的Cx,Cy是从图像的左上角顶点开始的,改成如下这种就行了,且Cx,Cy是根据网格的个数决定的,这里的值是1。

相对于网格单元:

换成上面这张图可以更好的理解,这里的Cx和Cy的大小为3。σ(tx)和σ(ty)通过σ(sigmoid)函数将预测到的点控制在那个小格子中,比如假设这里预测到的位置是(0.5,0.7),则该点的实际坐标是(3.5,3.7)。(预测的点、预测的黑色框是根据anchor的位置和大小决定的。)

3.yolov3中关于darknet的配置文件yolov3.cfg剖析

1.yolov3.cfg
Darknet构建网络架构不是通过代码直接堆叠,而是通过解析cfg文件进行生成的。
2.在yolov3.cfg文件中,一些参数的解释(配合yolov3的网络体系结构图理解)

下图表示网络结构图中的卷积层

下图表示网络结构图中的yolo层,即对应②⑤⑥操作

参数解释
mask:因为anchor有9个,所以编号为0——8,这里的6,7,8表示的是第7、8、9个anchor,对应上图中的②,3、4、5anchor对应图中的⑤,0、1、2对应图中的⑥
anchors:对应图上的②⑤⑥操作,每次需要3个anchor,且这里9个anchor的大小是由Kmeans聚类得到的
classes:表示你要检测的目标种类
num:表示anchor的数量
jitter:用来数据增强时候的参数
ignore_thresh:在做交并比的时候用来判断你的anchor是正样本还是负样本,IOU的阈值
表示特征融合层

其中①:layers = -4 表示将前面的第4层带过来,如果layers有1层表示将那1层引过来
其中②:layers = -1,36表示将前面1层和后面的第36层融合起来,如果layers有两层表示将那两层相加
表示上采样层

4.yolov3的源代码


(这个版本的yolov3源码比较贴切于原论文)

(该代码虽然是yolov3的,但其中有些部分已经做了改动,初学yolo源码的话不建议看这个,这会和论文中的很多地方对不上)

5.简述yolov3的预测过程

比如:下图中的一个个小格子是用来划分责任的,即表示这个格子到底用来划分什么物体,真正的看到的东西是anchor。每个格子中都会放anchor,anchor是我们的样本,

步骤一:anchor是通过聚类得到的,首先为Anchor分配GT(ground truth)


上图中,Anchor表示的序号0——4(彩色的方框),黑色的方框表示的是GT(我们自己标的标签)。然后为每个anchor分配GT,即每个anchor要不有一个GT对应,要不就是background,可以根据IOU来判定。
关于IOU的阈值,在yolov3.cfg文件中的ignore_thresh即表示IOU阈值。ignore_thresh设置的越大,留下的anchor越少。(留下来的anchor就是正样本)
以上图为例,计算anchor-0和anchor-1与黑色方框GT的IOU值,可以发现anchor-0小于我们设定的IOU阈值,则判断为background,anchor-1判断为GT。
步骤二:标注每个anchor,根据GT的值,是猫的话就判断为猫,是狗的话就判断为狗,即为每个anchor分类别。
步骤三:计算每个anchor的偏移量,根据下面的图进行逆推

步骤四:以上步骤是设置类别,计算偏移量。注意样本是anchor。这样一来anchor的类别和偏移量都有了,tx’,ty’,tw’,th’。
在yolov3的源码中,关于yolo层即YOLOLayer是预测出来的tx,ty,tw,th。和上面步骤计算出来的tx’,ty’,tw’,th’进行比较,可以计算loss函数,然后就可以使用反向传播了。
推断预测的时候,直接使用YOLOLayer,虽然没有真值GT了,但也是要生成anchor的,因为这里得到的结果是相对于anchor的。

6.yolov4

附上大佬的博文:

非极大抑制NMS与Soft-NMS

YoloV4当中的Mosaic数据增强方法

补充
①因为传统的IOU中计算的是两个方框相交的情况,如果不相交就无法处理,所以引入了GIOU、DIOU。



上图中第二项相当于是惩罚项。

三.搭建Yolo平台

1.Pytorch——yolov4(GPU)

Pytorch的yolov4(力推这个博主,我就是按照他的博文配置成功的):
windows下的torch=1.2.0与CUDA环境配置:

相关资源下载:
链接:
提取码:y0mx
Pytorch搭建YoloV4目标检测平台

配套的视频介绍:
=2

准备过程:
①按照VOC数据集存放图像和xml文件
②运行…yolov4-pytorch-master\VOCdevkit\VOC2007中的voc2yolo4.py文件,然后进入到Image/Main中查看,分成了test.txt,train.txt(并不是所有数据参加训练过程),val.txt,trainval.txt文件
③修改…\yolov4-pytorch-master目录下的voc_annotation.py,将类别classes换成你检测的类别。
运行…\yolov4-pytorch-master目录下的voc_annotation.py,会在此目录下生成2007_test.txt,2007_train.txt,2007_val.txt文件(打开txt文件其中存放的是图像的绝对路径和目标的参数,每个目标有5个参数,前4个是目标的位置,第五个是目标的种类)
④train.py中:先把main中的输入图像大小改成input_shape=608x608
smoooth_label平滑标签改为0.001
classes_path中改为你需要训练的类别
anchors_path中需要kmeans聚类后的先验框大小,运行kmeans_for_anchors.py文件
model_path

2.Darknet——yolov4(GPU)

相关资源下载(里面的步骤很详细):
链接:
提取码:gf4w
配套的视频:
=1183


快速入手YoloV4 编译+使用+训练
视频链接:
yolov4仓库github地址:
关于VS2017、OPENCV的配置: .html

3.Darknet——yolov3(CPU)

这里参考我之前写的博客:

4.Pytorch——yolov3(GPU)

Pytorch搭建yolo3目标检测平台

配套视频:

四.遇到的问题及解决办法

1.关于给数据集打标签

①如果是Pytorch框架的yolo,用xml文件就可以,LabelImage中直接就可以输出PascalVOC格式的标签
②如果是Darknet框架的yolo,是需要txt文件的,更新下LabelImage,就可以直接将打标签的图像转为yolo的形式。
参考博文:
但如果你的xml文件已经有了,若再去打一遍标签,相信肯定会崩溃,有的Darknet框架中提供将xml文件转为txt的程序,有的没有,这里我贴出一个我实测过的xml文件转txt文件的源程序。

'''xml转txt'''
import os
import sys
import xml.etree.ElementTree as ET
import globdef xml_to_txt(indir,outdir):os.chdir(indir)annotations = os.listdir('.')annotations = glob.glob(str(annotations)+'*.xml')for i, file in enumerate(annotations):file_save = file.split('.')[0]+'.txt'file_txt=os.path.join(outdir,file_save)f_w = open(file_txt,'w')# actual parsingin_file = open(file)tree=ET.parse(in_file)root = tree.getroot()for obj in root.iter('object'):current = list()name = obj.find('name').textxmlbox = obj.find('bndbox')xn = xmlbox.find('xmin').textxx = xmlbox.find('xmax').textyn = xmlbox.find('ymin').textyx = xmlbox.find('ymax').text#print xnf_w.write(xn+' '+yn+' '+xx+' '+yx+' ')f_w.write(str(name.encode("utf-8")+ b"\n"))indir= r'C:\Users\ps\Desktop\transform\Annotations'   #xml目录
outdir= r'C:\Users\ps\Desktop\transform\txt'  #txt目录xml_to_txt(indir,outdir)

③在给xml文件转为txt文件时,我报了一个错,大概意思是除数不能为0,后经过排查,是因为有些xml文件中是这样:

后将这些出错的xml文件重新打标签保存就可以了。

2.实测Pytorch_yolov3输出.pt权重转.weights权重

最近学习Yolo是因为老师布置的一个项目需要,刚开始接手的时候,心里第一想法就是拿刚出来的yolov4网络,因为数据集比较小,分4个类只有700多张数据集,抱着试一试的想法,跑了一下Pytorch搭建的yolov4,随便测试了几张,准确率高达90%,不得不佩服yolov4的强大
起初是想用PyQt做一个交互式界面,最后却发现Pytho的运行速度实在是太低效,于是想到了用C++的QT写界面,然而在调用模型的时候,却总是出错,因为我用Pytorch的yolov4跑出来的权重文件后缀是pth,查了下资料,大概原因是readNetFromDarknet()函数不支持.pth权重的读取

opencv用dnn.readNet加载caffe/torch/darknet/tensorflow的模型和权重

突然发现Opencv中有readNetFromTorch这个函数,但网上搜了之后发现他们调用的文件后缀都是.t7格式,而我自己Pytorch训练出来的是后缀为.pth,

然后我又想到了Darknet框架的yolov4,因为那样跑出来的权重文件后缀是weights,是支持的,一顿操作搭建好了环境,开始跑模型的时候,突然想到,因为yolov4刚出来不久,里面有一些新的网络层,去C++里面调用时,Opencv会不会不支持,请教了师兄,也提出了这样的顾虑,于是我放弃了yolov4,改用yolov3.
PS:windows环境下配darknet的yolov3过程实属曲折,不是这个报错就是那个报错,没办法了试了下Linux系统的环境配置,还是以失败告终。
如果用Pytorch的yolov3跑模型,最终出来的权重文件又是.pth,还是绕不过这个问题。

最后还是师兄给了我一个Pytorch_yolov3的版本,输出.pt格式权重,然后再转为.weights格式权重。
①相关资料下载
链接:
提取码:9f00
②训练过程参考博客
=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
③训练好了之后,先进行预测
在这个文件夹下放待检测的图像:


在这个路径下输出预测的结果:

④.pt转为.weights文件
模型跑完后输出的权重文件在这个路径下,


修改上面两张图的路径

最后输出weights文件
⑤C++、opencv下调用weights权重
源码链接:
链接:
提取码:z6bf

PS:提问

若有大佬在C++、opencv中调用过yolov4或者调用过.pth的权重,望告知,非常感谢!!!

更多推荐

学习YOLO系列的个人总结

本文发布于:2024-02-26 22:02:48,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1704100.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:系列   YOLO

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!