【Darknet版YOLOv3&YOLOv4模型训练】

Darknet版YOLOv3&YOLOv4模型训练

    • 1、`CMake` 是一个跨平台的自动化构建系统 ‍️‍️‍️
    • 2、yolov3搭建
    • 3、`yolov3`自己训练`voc2012`数据集:✍️✍️✍️
    • 4、yolov4搭建 #和v3差不多 ‍️‍️‍️
    • 5、制作VOC数据集 ‍️‍️‍️
    • 6、Keras/Tensorflow+python+yolo3训练自己的数据集 ✍️✍️✍️
    • 7、keras ‍️‍️‍️
    • 8、训练数据集时注意事项 ‍️‍️‍️
    • 9、防止过拟合 ‍️‍️‍️

1、CMake 是一个跨平台的自动化构建系统 ‍️‍️‍️

CMake 是一个跨平台的自动化构建系统,它使用一个名为 CMakeLists.txt 的文件来描述构建过程,可以产生标准的构建文件,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。文件 CMakeLists.txt 需要手工编写,也可以通过编写脚本进行半自动的生成。CMake 提供了比 autoconfig 更简洁的语法。在 linux 平台下使用CMake 生成 Makefile 并编译的流程如下:
1. 编写 CmakeLists.txt。
2. 执行命令 “cmake PATH” 或者 “ccmake PATH” 生成 Makefile ( PATH 是 CMakeLists.txt 所在的目录 )。
3. 使用 make 命令进行编译。
把开发环境转移到Linux下,同时也准备阅读些GitHub上的开源代码,开源项目一般都是用CMake管理的。CMake所做的事其实就是告诉编译器如何去编译链接源代码。你也许想问不是有makefile吗,为什么还要它?这里就牵涉到跨平台问题。在Windows平台下是通过project文件去管理这些的,如果不用CMake,那我们为Windows和Linux系统就要写对应的project文件和makefile文件,这无疑是一件繁琐的事,而我们只要编写一次CMake,就可以用在各个平台,而且其语法也简单。目前CMake 3.12.2已经可以下载,在Ubuntu 18.04可以更新到最新的CMake版本。

2、yolov3搭建

darknet官网下载源码(也就是名为darknet的项目文件夹),放入主目录;或者在主目录下打开终端,输入 一下代码进行源码下载。
终端下载及编译步骤如下:

git clone https://github.com/pjreddie/darknet
cd darknet
make

之后下载yolov3.weights权重文件,可以直接在darknet文件夹内打开终端输入
wget https://pjreddie.com/media/files/yolov3.weights 下载,或者打开浏览器 https://pjreddie.com/media/files/yolov3.weights 用链接下载,之后大权重文件放入darknet文件夹内。(都很慢)
下面测试一下!

./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

若要在GPU上跑,要修改一些参数,darknetwen文件夹内的makefile文件修改:

GPU=1
CUDNN=1
OPENCV=# 如果安装了opencv则改为1,在中终端中执行sudo apt-get install libopencv-dev  即可
OPENMP=0
DEBUG=0
...
NVCC=/usr/local/cuda-10.2/bin/nvcc # 原为 NVCC = nvcc,cuda后面的紧跟自己的cuda版本,如cuda-9.0,cuda-10.0等
ARCH= -gencode arch=compute_75,code=sm_75 \   #算力改为75

改完之后再make一下,在测试。(别的电脑上的项目文件一定要重新设置编译)

3、yolov3自己训练voc2012数据集:✍️✍️✍️

步骤如下:
1、把下载好的解压后的VOC数据集文件夹放到项目文件夹下(我是只打算训练voc2012数据集,也可以下载voc2007数据集一块训练),下载后的文件夹名为PascalVOC2012
2、为图片数据集生成txt的标签文件,下载voc_label.py文件并运行,将文件下载到VOCdevkit同级的路径下,生成训练和验证的文件列表 ,如果下载好了darknet项目,在darknet/scripts/目录下也有voc_lable.py,下载voc_lable.py命令并运行如下:

wget https://pjreddie.com/media/files/voc_label.py
python voc_label.py

然后会在PascalVOC2012文件夹下VOCdevkit同级的路径下生成2012_train.txt2012_val.txt,(如何是voc2007数据集会生成2007_train.txt和2007_val.txt和2007_test.txt文件)之后VOCdevkit/VOC2012/labels/可以看到生成的标签文件
3、训练除了07测试集外的所有数据集,需要整合为一个大的训练list,在VOCdevkit同级的路径下执行:

cat 2007_train.txt 2007_val.txt 2012_*.txt > train.txt

就会生成train.txt文件
而我只训练voc2012,所以执行命令:cat 2012_*.txt > train.txt
4、修改 cfg/voc.data:(2、3行改为自己的路径:)

classes= 20
train  = /home/yuhui/下载/darknet-master-1/PascalVOC2012/2012_train.txt
valid  = /home/yuhui/下载/darknet-master-1/PascalVOC2012/2012_val.txt
names = data/voc.names
backup = /home/yuhui/下载/darknet-master-1/backup/    #backup是保存训练权重的文件夹,没有就在项目文件下建一个

5、使用kmeans.py聚类自己数据集的anchor。更改程序里面的txt训练文件名称,输出自己数据集anchor的txt文件。使用train.py进行训练。需要更改的是类别文件,anchor文件(还没搞明白)
还有一中办法是直接在项目文件下执行如下命令:

./darknet detector calc_anchors cfg/voc.data -num_of_clusters 9 -width 416 -height 416     
#运行上面代码即可得到聚类结果,如果想要更高分辨率的聚类效果,修改width和height即可,一定要是32的整数倍。

执行以上命令后会在项目文件夹下生成anchors.txt,然后用它替换yolov3-voc.cfg中的anchors
6、在项目文件目录下载权重文件:

wget https://pjreddie.com/media/files/darknet53.conv.74    #下载失败了,百度网盘下的,就只要把darknet53.conv.74放项目文件下就好

7、开始训练:

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 -map

#后面可以加-map(应该是为了可视化,或者当你在终端中加上 -map 参数的时候,你就会看到mAP指标)

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg yolov3-voc_last.weights -map   

#中断训练后在原有基础上再次训练(上次训练最后生成的权重文件要放项目文件下)

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 2>1 | tee visualization/train_yolov3.log -map

#可视化中间参数需要用到训练时保存的log文件(命令中的路径根据自己实际修改)(不好使竟然!!!)
于是换一个:

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 >log.txt -map    #训练时保存训练日志,运行此代码

补充:如果想要指定具体的gpu进行训练,可以使用-i来指定,比如我想使用索引为2的gpu进行训练,可以这样写:

./darknet detector train data/voc.data cfg/yolov3-voc.cfg darknet53.conv.74 -i 2 -map    

#指定具体那块gpu训练(从第一块索引0,1,2)

8、测试 #文件中batchsubdivisions两项必须为1。

./darknet detector test  cfg/voc.data cfg/yolov3-voc.cfg weights/yolov3.weights data/dog.jpg    
#权重保存weights文件夹中(根据实际保存目录修改

./darknet detector test  cfg/voc.data cfg/yolov3-voc.cfg weights/yolov3-voc_1000.weights data/dog.jpg   
 #应该是迭代1000次后的权重,测试后发现效果很差劲
./darknet detector test  cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_last.weights data/dog.jpg    
#应该是迭代1000次之后的权重,(但是竟然只迭代1800次后就可以测试,而且识别概率挺高的)

懂了懂了!!!原来是每迭代1000次更新保存一次权重

./darknet detector test  cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_2000.weights data/dog.jpg    #迭代2000次后的权重测试
./darknet detector test  cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_20000.weights    #批量测试图片
./darknet detector demo cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_30000.weights test.mp4 -out_filename xxx.mp4    #保存视频文件不打印结果

9、如何输入检测结果文本,计算recall,map计算,:

./darknet detector valid <data_cfg> <test_cfg> <weights> <out_file>  
  # 生成测试结果,文件中batch和subdivisions两项必须为1。
./darknet detector valid cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_best.weights out_file

结果生成在的results指定的目录下以开头的若干文件中,若没有指定results,那么默认为/results。
v如果出现以下问题,则说明在.data文件里面没有指定valid的路径,添加即可:

Couldn't open file: data/train.list       #报错
./darknet detector map cfg/voc.data cfg/yolov3.cfg backup/yolov3_best.weights    #计算AP值,查看我们模型的训练效果,运行此代码

#darknet-yolo训练数据集时加载不了图片,那很有可能是图片格式不对

4、yolov4搭建 #和v3差不多 ‍️‍️‍️

项目地址:https://github.com/AlexeyAB/darknet #现在下载项目文件(源码,下载完后可放主目录)

yolov4.weights:  权重百度云链接:链接:https://pan.baidu.com/s/1ILfTuUrQxtNBU5DdNw7hoQ  提取码:ffm8
若要在GPU上跑,要修改一些参数,darknetwen文件夹内的makefile文件修改:
GPU=1
CUDNN=1
OPENCV=# 如果安装了opencv则改为1,在中终端中执行sudo apt-get install libopencv-dev  即可
OPENMP=0
DEBUG=0
...
NVCC=/usr/local/cuda-10.2/bin/nvcc # 原为 NVCC = nvcc,cuda后面的紧跟自己的cuda版本,如cuda-9.0,cuda-10.0等
ARCH= -gencode arch=compute_75,code=sm_75 \   #算力改为75

改完之后再make一下,在测试:

./darknet detect cfg/yolov4.cfg yolov4.weights data/dog.jpg    #测试图片
./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights test.mp4    #v3测试视屏文件
./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights test.mp4    #v4测试视屏文件
 -out_filename xxx.mp4 >xxx.txt   # 保存+打印出结果
./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights test.mp4 -out_filename xxx.mp4 >xxx.txt    #保存+打印出结果
./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights test.mp4 -out_filename xxx.mp4    #保存不打印结果

include video_capturing + NMS + drawing_bboxes:

  ./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights test.mp4 -dont_show -ext_output

#官方给出的视屏检测命令,-dont_show是在训练中图像显示给隐藏了,,其中-ext_output是输出目标检测的坐标,后边写的test.mp4就是输入视频文件
exclude video_capturing + NMS + drawing_bboxes:

./darknet detector demo cfg/coco.data cfg/yolov4.cfg yolov4.weights test.mp4 -benchmark

yolov4的复现其实个v3没有什么区别,这就是大佬的厉害之处,yolov3可以完美对接上yolov4,如果你还想用yolov3来检测,那么同样只需要准备好v3的权重文件,然后将上面的命令改成v3即可运行:

./darknet detect cfg/yolov3.cfg yolov3.weights data/person.jpg

5、制作VOC数据集 ‍️‍️‍️

1.图片数据准备 ✍️✍️✍️
图片数据的获取可以自己用高清摄像机采集视频,然后对其进行抽帧,获得图片数据集视频>>图片;因为xml文件序号要与图片编号一一对应,这里文件重命名可以用代码完成序号重命名(00001,00002等)
命名方式

2.标注数据 ✍️✍️✍️
这里用的是比较常用的labelImg标注工具,每标注一张图片都会生成一个xml文件。labelImg可以去浏览器下载,这里给个我当时下载的链接labelImg下载
labelImg使用方法大家直接搜一下就可以了,很简单也很好用的工具,页面大概是这样
首先简单介绍一下这两种工具,labelimg工具主要用于在目标检测,而 labelme工具图像分割领域制作自己的数据集,我们可以用labelimg用于制作自己的数据集训练像YOLOv3和YOLOv4目标检测模型,而用labelme可以自己制作像MaskRCNN模型做图像分割训练需要的数据集。
标注完所有图像之后就可以查看标记结果了,注意这里我们进行标注时有两种标记数据的格式一种是PascalVoc,另外一种是YOLO,这里以常见的VOC数据集格式进行标注,最终得到以xml格式的标注数据。
labelimg标注完数据之后以.xml数据的格式进行保存,只能创建矩形框更加适用于目标检测制作数据集,如YOLO,而labelme以.json文件的数据格式进行保存,可以创建多种类型的边框进行标注,适用于图像分割,如MaskRcnn。

标注数据: ✍️✍️✍️
LabelImg软件下载:https://github.com/tzutalin/labelImg
(解压得到labelImg-master文件夹)
在Anaconda环境中切换到该文件夹目录,并且安装好依赖项:pyqt5和lxml;安装完成执行如下命令即可打开软件使用:

pip install pyqt5
pip install lxml
pyrcc5 -o resources.py resources.qrc
python labelImg.py    #若出现错误ModuleNotFoundError: No module named  'libs.resources',将LabelImg-master中的resources.py复制到libs文件中

Open Dir打开图片文件夹目录,Create RectBox创建标注框,Ctrl-S保存xml文件至Annotations文件夹
标注准则:
1、尽可能把图片中包含的目标都标注完
2、不同类别要分开标注

3.创建VOC文件夹 ✍️✍️✍️
新建文件夹命名VOC2007,并且在VOC2007下新建Annotations,ImageSets和JPEGImages三个文件夹,在ImageSets文件夹下再建一个Main文件夹。Annotations里面放已经标注好的xml文件,JPEGImages里面放自己的图片数据(序号00001,00002,00003…)

对于已经存在于coco数据集80个种类之中的一类,就不要自己训练了,官网权重训练的很好了已经;
对于不存在coco数据集的一种,无视convert.py, 无视.cfg文件,不要预加载官方权重,直接用我的train.py代码进行训练就可以了。你预加载官方权重,再去训练一个全新的物种,个人认为是浪费资源完全没意义的

6、Keras/Tensorflow+python+yolo3训练自己的数据集 ✍️✍️✍️

问题: E tensorflow/core/grappler/optimizers/meta_optimizer.cc:502] remapper failed: Invalid argument: Subshape must have computed start >= end since stride is negative, but is 0 and 2 (computed from start 0 and end 9223372036854775807 over shape with rank 2 and stride-1)

RuntimeError: Attempted to use a closed Session.

如果还是提示“Couldn't open webcam or video”的话,把视频的路径改为完整路径应该就好了

7、keras ‍️‍️‍️

在使用keras时候报错Keyerror ‘acc',这是一个keras版本问题,acc和accuracy本意是一样的,但是不同keras版本使用不同命名,因此需要更换。val_acc也是如此。
pydot出问题时换为pydotplus

8、训练数据集时注意事项 ‍️‍️‍️

由于本人的电脑显存较小,运行时报错了:ResourceExhaustedError
应该可以修改参数,完成,在yolo_v3训练时候,就是通过修改batchsize和epoch来实现。
存在问题:keras v3训练自己数据集,重复训练模型(执行train.py文件),测试时出现识别不出的情况

9、防止过拟合 ‍️‍️‍️

防止过拟合的方法:
提前终止(当验证集上的效果变差的时候)
L1和L2正则化加权
soft weight sharing
dropout

你可能感兴趣的:(模型部署,学习专区,深度学习,人工智能,算法)