alexeyab darknet 编译_【目标检测实战】Darknet—yolov3模型训练(VOC数据集)

2210fae3f5a1fcafcec71f0046c45ea1.png

原文发表在:语雀文档

0.前言

本文为Darknet框架下,利用官方VOC数据集的yolov3模型训练,训练环境为:Ubuntu18.04下的GPU训练,cuda版本10.0;cudnn版本7.6.5。经过一晚上的训练,模型20个类别的mAP达到74%+。

主要模块:

  • 概述
  • 源码编译
  • 功能测试
  • 模型训练
  • 模型验证

【概述】主要介绍yolo系列模型和darknet框架的关系、资源网站和数据集下载

【源码编译】主要是用官方源码和make命令编译出Linux下可执行文件,包括cuda+cudnn的设置

【功能测试】主要是用官网给出的demo和与训练模型来进行图片测试

【模型训练】主要是用darknet+yolov3模型训练VOC图像数据集(VOC2007+VOC2012) 【模型验证】即用训练好的模型,检测模型训练效果.


1.概述

官网:https://pjreddie.com/

a442b7574ccabfdde7b9fb23e59d00f7.png

1.1 Yolo

Yolo系列模型(v1~v3)在近年些来的目标检测领域,非常火热!Yolo为:You only look once的缩写,同时也表明了其特点,只需要一次即可完成从图像分割到检测,故其被称为one-stage系列模型的鼻祖。

two-stage类目标检测模型如Fast R-CNN、Faster R-CNN

6522f7dddede2922e81310538c0757a5.png

1.2 Darknet

yolo系列就是深度学习领域中用于目标检测的模型(yolov1~v3),那么darknet是什么?两者关系如何? darknet是作者用c和cuda编写的用于深度学习模型训练的框架,支持CPU和GPU训练,是个非常简单轻量级框架,就和Tensorflow,Mxnet,Pytorch,Caffe一样,虽然功能没有它们多,不过小也有小的优势,如果你会c语言,可以对其进行充分地利用和改造,或者读读源码看一下其实现,也会收货满满! So,总结一下:Darknet是深度学习框架,yolov1~v3是yolo系列的目标检测模型

1.3 资源下载

官网

https://pjreddie.com/

源码

Darknet源码: https://github.com/pjreddie/darknet

Darknet是用纯c和cuda编写的,要想用darknet来训练模型,最好用Linux/Unix系统,官方也提供了python的接口,如果是Windows系统,可以利用网友开源实现:https://github.com/AlexeyAB/darknet

可以直接下载zip包darknet-master.zip也可直接执行

git clonehttps://github.com/pjreddie/darknet将源码下载到本地

权重文件

yolov3-tiny.weights

yolov2.weights

yolov3.weights

darknet53.conv.74

VOC数据集

VOCtrainval_11-May-2012.tar

VOCtrainval_06-Nov-2007.tar

VOCtest_06-Nov-2007.tar

其他:

YOLO-V3可视化训练过程中的参数,绘制loss、IOU、avg Recall等的曲线图

AlexyAB大神总结的优化经验

2.源码编译

2.1 编辑Makefile

指定是否使用GPU 在执行make指令编译之前,需要编辑一下makefile,来指定是否需要用GPU(cuda),如果用cuda,是否需要用cudnn加速;是否需要用opencv等。我这里是用GPU且需要用CUDNN加速的,不使用OpenCV。 Makefile的前5行如下,这5项内容0表示不启用,1表示启用,可根据需求自己配置。

  • GPU 是否启用GPU1
  • CUDNN 是否启用CUDNN加速,若GPU = 1则CUDNN可选1或0;GPU=0则CUDNN=0
  • OPENCV 是否启用OpenCV,启用的话需先编译安装好,启用可支持对视频和图像流文件处理
  • OPENMP 是否启动多核CPU来加速Yolo,如果是用CPU训练,建议开启=1
  • DEBUG 表示编译的Yolo版本为是否为DEBUG版

0753ba5c6ea4f4b787ffda6881c111ca.png

如果不使用GPU则GPU=0,CUDNN=0;还有一点需注意,如果在shell执行nvcc找不到命令(没有添加到环境变量),则需要将nvcc命令的全路径写出来 指定cuda的路径 如果不使用GPU,则此步可忽略,如果使用GPU,则需要指定cuda路径。官方的Makefile默认的cuda路径为:/usr/local/cuda,如果你安装了多个cuda,或者cuda路径更改过,则需要指定你的cuda路径,这里需要改两处:51行的COMMON和53行的LDFAGS

a05817325aa56aa7b3ab744545321d0a.png

2.2 执行make

a70f16f2ec8fddfd73b45b16f2cc6ac4.png

执行make编译完成后,在项目主目录下生成可执行的darknet文件。然后我们就可以用这个可执行文件来进行模型训练和测试了!

3.功能测试

将下载好的权重文件放入主目录下,然后cd到该目录下执行:

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

如果你看到如下输出,且在主目录下找到一张predictions.jpg的图片,则执行成功,表明上一步骤中编译的darknet可以正常使用。

1f44da2c52d9ba383afa9ac2f786181c.png

你也可以指定一个阈值,yolo默认输出置信度>0.25的预测框,你也可以自行指定:

./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg -thresh 0.45

-thresh 0.45表示:置信度低于45%的预测框都不会被输出。

除了使用经典的yolov3模型外,你还可以换一个模型尝试,譬如yolov3-tiny.weights

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

当然,也可以通过连接摄像头实现实时视频画面预测。(需要编译时添加opencv)

./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights <video file>

4.模型训练

4.1 数据准备

模型训练前首先准备数据集,我们用VOC数据集,将VOC数据集解压,解压后共同存放在VOCevkit文件夹中,我将VOCevkit放在了darknet主文件夹/data/VOC/下。 cd到/VOC目录下,下载voc_label.py ,并运行:

python voc_label.py
可以将该脚本复制到/scripts下留作备份

文件夹下会生成7个.txt文件:

c5b165514aa33f496465162cb6f9f363.png

如果你的voc_label.py脚本是从官网wget https://pjreddie.com/media/files/voc_label.py下载的,则需要在脚本57行处额外加上如下两行内容:

os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt")
os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")

目的:将2007年的训练和验证图像+2012年的图像都放入了train.txt用于集中训练

4.2 修改配置文件voc.data

配置cfg/voc.data,来确定你需要检测的目标类别数量和名称;修改train和valid的图片资源路径。训练资源指向train.txt测试/验证资源指向2007_test.txt

a3653ce8ec1c3a08bd71e32f63f72378.png

VOC数据集默认的类别数量为20个,名称在data/voc.names中:

b1a4e63e1f933c39f75f1dbed1bc3b49.png

我这里使用默认的20个类别,所以无需修改;如果,你只想检测其中的几个类别,譬如person和car,那么可以设置voc.data中classes=2,names只保留person和car这两种,不过后面相应的需要更改yolov3-voc.cfg里的卷积层配置等。

4.3 修改yolov3-voc.cfg

yolov3-voc.cfg文件定义了yolo的卷积神经网络模型,和超参数配置等。这里需要注意,训练时需要将#Testing区块下的batch和subvisions注释掉;测试和验证时则放开注释,同时注释掉#Training区块下的内容。 训练时,可以根据自己GPU的内存来设置批的大小batch,可设为16、32、64、128 验证时,batch和subvisions同时设为1即可。

a32effe6afe52213bbf86981ed9bac61.png

4.4 开始训练

cd回项目主目录,将darknet53.conv.74权重放入主目录下,运行:

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

如果报错提示cuda内存溢出,可以降低batch,再次运行;运行过程中可以通过nvidia-smi查看显存占用情况:

f1f68698c664c2dbf92a1cbca29f934c.png

训练过程中会持续往backup/下生成权重文件,如:yolov3-voc_100.weights、yolov3-voc_200.weights....

5.模型验证

检验生成的模型权重文件、测试准确率和map等指标。验证前需要将yolov3-voc.cfg中的batch和subdivisions都改成1。然后找到需要测试的权重文件,默认权重文件保存在:项目目录/bakcup/下,我选择这个yolov3-voc_10000.weights,训练大约一个晚上12小时左右,loss在0.6多。

d4810d9427a520552b4e6b9d17adb23f.png

5.1 测试

测试一

我们从VOC数据集中随便找一找图片来测试一下,这里我选取000275.jpg放入主目录下

fa588399c49ba230b18ebb7ddec5e59f.png

运行:

./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_10000.weights 000275.jpg

5fd5e3ae1d862a219766fb3418c0f163.png

运行结束会在控制台打印出标注出的目标类别以及置信度、同时会在目录下生成一张标注图片:predictions.jpg **

635d2620d02c58097c79109c5b173e4a.png

测试二

再随便找一张图片试试

./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_10000.weights data/person.jpg

d88c9bcfdbcfebfd3fd2b7d5fb6756b5.png

9a170244d3d99e9bcd4227893c4e1e18.png

5.2 验证

测试只能一张张地直观感受下模型的训练效果,看看标注出的目标是否正确,通过验证才能确定模型的整体训练效果,验证时会用模型对所有的4952张测试集图片进行预测,同时与正确结果进行比对,得出一个模型预测准确率。

验证测试集

可以运行以下脚本进行验证:

./darknet detector valid cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_10000.weights

验证完会在results文件夹下生成20个类别的验证结果txt文件

de0f4640673bd36482048bac5dda2985.png

默认的文件命名规则是:'comp4_det_test_' + '类别名称' + .txt,如bird类生成comp4_det_test_bird.txt文件。

b7ce3d6184121dbcd4611217f0d66d54.png

如图,第一列000053表示图像编号;第二列为置信度;后4列为检测出的目标框坐标

计算map

计算map,我们需要两个python文件:

  • voc_eval.py
  • compute_mAP.py

其中voc_eval.py是github上开源项目的代码voc_eval.py;compute_mAP.py需要我们自己编写


voc_eval.py 我们为了适配darknet中voc数据集的验证,需要对源码做几处修改: a.源码第9行:import cPickle 改为:

import _pickle as cPickle

因为源码是python2.x版本,如果python3.x版本的运行会报错,故需要修改。

b.源码103行: imagenames ``=`` [x.strip() ``for`` x ``in`` lines]改为:

imagenames = [x.strip().split('/')[-1].split('.')[0] for x in lines]

这个主要是为了方便适配2007_test.txt,因为我们验证时采用的是2007_test.txt中的测试集图片,文件中存放的是图片的全路径,而imagenames需要用的是文件名、所以需要将全路径做个转换,截取到文件名。

c.115行with`` ``open``(cachefile, ``'w'``) ``as`` f:和 119行with`` ``open``(cachefile, ``'r'``) ``as f:改成:

with open(cachefile, 'wb') as f:
with open(cachefile, 'rb') as f:

如果不修改成‘wb’和‘rb’存储二进制格式,运行时会报错

compute_mAP.py 新建compute_mAP.py文件,用于调用voc_eval.py,内容如下:

from voc_eval import voc_eval
import os
map_ = 0
# classnames填写训练模型时定义的类别名称
classnames = ['aeroplane','bicycle','bird','boat','bottle','bus','car','cat','chair','cow','diningtable','dog','horse','motorbike','person','pottedplant','sheep','sofa','train','tvmonitor']
for classname in classnames:ap = voc_eval('../results/{}.txt', '../data/VOC/VOCdevkit/VOC2007/Annotations/{}.xml', '../data/VOC/2007_test.txt', classname, '.')map_ += ap#print ('%-20s' % (classname + '_ap:')+'%s' % ap)print ('%s' % (classname + '_ap:')+'%s' % ap)
# 删除临时的dump文件
if(os.path.exists("annots.pkl")):os.remove("annots.pkl")print("cache file:annots.pkl has been removed!")
# 打印map
map = map_/len(classnames)
#print ('%-20s' % 'map:' + '%s' % map)
print ('map:%s' % map)

我这里在项目主目录下新建了一个【yolo-compute-util】文件夹,将两个.py文件放在文件夹中,cd /yolo-compute-util,然后运行:python compute_mAP.py即可根据results中的验证结果统计出各个类别的ap,以及汇总的map。

2826188f7cadb3735a9a2f79b974a8a3.png

可以看见,经过1晚上的训练,我们的模型——yolov3-voc_10000.weights的mAP是0.740,虽然没有达到yolov2系列76.8+的水平,不过一晚上的训练能达到如此程度,也是挺高了。

19a9b3a8815230813739a3553bc2758f.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html字符串转svg,【SVG】如何操作SVG Text

上周我们学习了如何使用元素创建SVG文本。在实例中我们设置了x和y坐标来定位文本&#xff0c;也尝试了给SVG文本中的每个字符定位。关于元素还有很多内容。在处理SVG文本时&#xff0c;不要局限于x和y属性。元素还有几个可以添加的属性&#xff0c;现在我们开始讨论吧。dx和dy属…

C++ 面试考点(三)

点击蓝字关注我们21、构造函数和析构函数可以调用虚函数吗&#xff0c;为什么在C中&#xff0c;提倡不在构造函数和析构函数中调用虚函数&#xff1b;在构造函数和析构函数调用的所有函数(包括虚函数)都是编译时确定的, 虚函数将运行该类中的版本.因为父类对象会在子类之前进行…

用终端访问路由器设置端口开发_serial for mac(终端管理软件)v2.0.3

原标题&#xff1a;serial for mac(终端管理软件)v2.0.3serial for mac是应用在Mac上的一款终端管理软件&#xff0c;可以帮助您连接和控制串行设备&#xff0c;如服务器&#xff0c;路由器或调制解调器等网络设备&#xff0c;PBX系统等。好消息是Serial为大多数串行设备提供了…

大神级的C++性能优化,你能看懂吗?

点击蓝字关注我们一、前言性能优化不管是从方法论还是从实践上都有很多东西&#xff0c;文章会从C语言本身入手&#xff0c;介绍一些性能优化的方法&#xff0c;希望能做到简洁实用。二、实例1在开始本文的内容之前&#xff0c;让我们看段小程序&#xff1a;// 获取一个整数对应…

钢笔墨水能否代替打印机墨水_LAMY钢笔应该如何选择墨水?

其实墨水世面上基本是有两种&#xff1a;碳素墨水和非碳素。碳素墨水相对比较堵笔&#xff0c;碳素墨水对钢笔本身腐蚀性不大&#xff0c;腐蚀性大的那是染料/颜料墨水。碳素墨水写字非常容易有笔锋&#xff0c;而非碳素墨水就显得略微柔和了。有人说&#xff0c;字写得好的人用…

html ctf查找,Web CTF 解题思路总结—南京邮电大学攻防平台writeup

1、直接查看源代码例&#xff1a;签到题(50)2、PHP的特性(1)MD5 碰撞例&#xff1a;md5 collision(50)md5碰撞&#xff1a;MD5摘要算法可以从多个字节组成的串中计算出由32个字节构成的“特征串”&#xff0c;对于超过32字节的串来说&#xff0c;MD5计算得出的值必然是其一个子…

java 1.8新增功能_睡觉时:新增的Java 8新增功能

java 1.8新增功能自Java 8推出以来&#xff0c;最有趣的功能是什么&#xff1f; Java 8最近庆祝了它的第一个生日&#xff0c;其主要版本已经在一年多以前了。 这当然值得庆祝。 自从最初的Java 8版本问世以来&#xff0c;已经发布了六个更新。 这些更新中的某些元素是次要的…

C++ 为什么不加入垃圾回收机制

点击蓝字关注我们Java的爱好者们经常批评C中没有提供与Java类似的垃圾回收(Gabage Collector)机制(这很正常&#xff0c;正如C的爱好者有时也攻击Java没有这个没有那个&#xff0c;或者这个不行那个不够好)&#xff0c;导致C中对动态存储的官吏称为程序员的噩梦&#xff0c;不是…

c++ 共享内存_Python3.8多进程之共享内存

最近发了个宏愿想写一个做企业金融研究的Python框架。拖出Python一看已经更新到了3.8&#xff0c;于是就发现了Python 3.8里新出现的模块&#xff1a;multiprocessing.shared_memory。随手写了个测试。生成一个240MB大小的pandas.DataFrame&#xff0c;然后转换成numpy.recarra…

计算机主机箱外部介绍图,电脑的主机结构是怎样的 电脑主机结构图【图文】...

在电脑已经普及的今天&#xff0c;基本上每家每户都有电脑了&#xff0c;大家用它来看电影&#xff0c;搜索资料啊&#xff0c;上网啊等等。在我们日常的娱乐方式中&#xff0c;电脑也是我们的娱乐项目之一&#xff0c;至少还是好多人用它看电影和追剧的。但是机器会有故障的时…

C 语言各数据类型的内存映像

点击蓝字关注我们C语言各种数据类型的内存映像&#xff08;32位平台&#xff09;&#xff1a;0 signed char#include <stdio.h> int main() {char min 1<<7;char max (1<<7)-1;for(int imin;i<max;i)if(i<0)printf("%.2X ",(unsigned char…

用java编写一个图书管理系统_手把手教你编写第一个java程序

安装完jdk后我们就可以试着编写第一个java程序了&#xff0c;让我们一起来试试吧&#xff01;第一步点击开始——所有程序——附件——记事本&#xff0c;新建记事本&#xff0c;输入以下代码&#xff1a;class HelloWorld { public static void main(String args[]) { System.…

go micro java_Java Micro Framework:您无法忽略的新趋势

go micro java什么是Java微框架&#xff0c;为什么要使用它们&#xff1f; 每种语言都有权衡。 对于Java&#xff0c;要成为一种安全&#xff0c;经过严格测试&#xff0c;向后兼容的语言&#xff0c;就要在敏捷性和简化方面做出一些牺牲。 无可否认&#xff0c;有些冗长和冗长…

C语言调用C++类成员函数讲解和实例

点击蓝字关注我们1、问题成因C语言与C调用问题原因主要在于C编译器和C编译器的不同。C是过程式语言&#xff0c;C编译器编译后&#xff0c;函数在符号库中就是函数名&#xff0c;没有其他任何附加信息。而C是对象式语言&#xff0c;支持函数重载&#xff0c;C编译器编译后&…

学生命科学要学计算机吗,现在学生物学出路真的有那么不济吗?

最近浏览知乎&#xff0c;看到大规模的生物劝退贴&#xff0c;这些帖子纷纷拿出多个例子&#xff0c;并现身说法&#xff0c;告诫学生物的同学尽早转行&#xff0c;并声称劝退一人胜发7篇CNS。作为网友盛传的天坑之首&#xff0c;生物专业到底有多坑&#xff1f;环球科学曾对北…

java笔试题_Java面试才到笔试就没有然后了?快来签收,高频笔试57题及解答

前言很多人面试之前&#xff0c;可能没有在互联网公司工作过或者说工作过但年头较短&#xff0c;不知道互联网公司技术面试都会问哪些问题&#xff1f; 再加上可能自己准备也不充分&#xff0c;去面试没几个回合就被面试官几个问题打蒙了&#xff0c;甚至笔试都过不了。最后以惨…

java开发错误_每个Java开发人员都必须避免的9个安全错误

java开发错误Checkmarx CxSAST是功能强大的源代码分析&#xff08;SCA&#xff09;解决方案&#xff0c;旨在从根本上识别&#xff0c;跟踪和修复技术和逻辑安全漏洞&#xff1a;源代码。 在这里查看 &#xff01; 自从1995年中期引入Java以来​​&#xff0c;它已经走了很长一…

C语言中常用的标准库函数有哪些?

点击蓝字关注我们标准头文件包括&#xff1a;<asset.h> <ctype.h> <errno.h> <float.h> <limits.h> <locale.h> <math.h> <setjmp.h> <signal.h> <stdarg.h> <…

计算机考试一级考试基础知识,全国计算机等级考试一级msoffice基础知识

全国计算机等级考试一级msoffice基础知识导语&#xff1a;在日常生活中&#xff0c;媒体(Medium &#xff0c;复数形式为Media )是指文字、声音、图像、动画和视频等内容。多媒体(Multimedia )是指能够同时对两种或两种以上媒体进行采集、操作、编辑、存储等综合处理的技术。多…

2008铁路旅客列车时刻表_天津到新沂汽车卧铺大巴车长途汽车发车时刻表

长途大巴网上需要注意什么&#xff01;选择乘坐大巴&#xff0c;是大家出行时的一个好选择&#xff0c;而且长途大巴网上也 很方便&#xff0c;能让大家节省不少的时间&#xff0c;但是网上有许多的要求&#xff0c;可能大家还不清楚。小编就给大家 介绍下长途大巴网上须知。长…