darknet-yolov3目标识别的训练与使用

本文使用的darknet均基于ubuntu系统,既可以在电脑上使用,也可以在jetson nano等高级嵌入式主控板上使用,两者操作系统均为ubuntu系统,安装流程基本一样。本文主要针对电脑上的使用。

一、基本环境配置(jetson nano可以跳过)

首先要在电脑上安装ubuntu系统,还不会安装的小伙伴可以参见我之前发布的博客:

Ubuntu20.04+anaconda+ros2-foxy安装_zst1406217的博客-CSDN博客_ubuntu安装foxy

随后需要安装显卡驱动。

首先查看有没有安装显卡驱动,终端输入:

nvidia-smi

若提示command not found,则说明没有安装,然后终端输入,查看本机显卡类型和驱动:

ubuntu-drivers devices

然后终端输入:

sudo ubuntu-drivers autoinstall

完成后系统重启,开机后打开终端再次输入:

nvidia-smi

如果出现一个方形表,里面出现显卡信息,则说明安装成功。

打开终端,输入:

gedit ~/.bashrc

在文件末尾加上:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-xx.x/lib64
export PATH=$PATH:/usr/local/cuda-xx.x/bin
export CUDA_HOME=$CUDA_HOME:/usr/local/cuda-xx.x

其中cuda-xx.x需要替换成自己的版本号,然后保存,关闭,在终端输入:

source ~/.bashrc

然后检验是否成功安装nvcc,终端输入:

nvcc -V

如果出现版本号信息,则安装成功。

最后安装cudnn(此步骤可以跳过,安装成功的好处是可以大幅度减少识别时间,当然原本识别时间也不长)。

首先按需求下载cudnn的安装文件:https://developer.nvidia.com/rdp/cudnn-download

然后按照官网上的安装步骤安装即可。

若到此安装有问题,可以参考:

Ubuntu20.04下CUDA、cuDNN的详细安装与配置过程(图文)_嵌入式技术的博客-CSDN博客_ubuntu安装cudnn

等博客,最后需要完成nvidia-smi、nvcc、cudnn(可选)的安装(部分操作可能需要科学上网)。jetson nano的官方镜像内已经预装了这些驱动,因此可以省去这些步骤。

二、源码包和标注软件下载

下载源码包:

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

标注软件(附带拍照、数据增强和模型训练预处理代码):

git clone https://github.com/zst1406217/visionAI.git

三、源码编译

修改配置文件Makefile:

GPU=1 #如果使用GPU设置为1,CPU设置为0
CUDNN=1  #如果使用CUDNN设置为1,否则为0
OPENCV=0 #如果调用摄像头,还需要设置OPENCV为1,否则为0
OPENMP=0  #如果使用OPENMP设置为1,否则为0
DEBUG=0  #如果使用DEBUG设置为1,否则为0

这里只要根据自己有没有安装cudnn来改第二行即可,其他直接和上述保持一致。

随后在确保终端目录为darknet,然后输入:

make -j8

四、检验安装是否成功

终端输入:

wget https://pjreddie.com/media/files/yolov3.weights
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg

如果没有报错并给出识别结果,则说明安装成功。(如果第一步下载不成功,可能需要科学上网)

五、拍摄自己的数据集

原始数据拍摄

首先找到前面visionAI文件夹,打开paizhao.py,更改文件夹路径和数据集命名,运行该程序,则实现了一次拍十张的操作。每拍一次,将index加10再拍,如此往复直至拍摄完全数据集。

数据增强

这步是非常关键的一步,目的是让十张一样的照片处理成从暗到亮,模拟在不同光线下的情形。通过这个操作,可以大大提高模型的鲁棒性。打开process.py,修改代码内的路径为自己数据集存放的路径,然后运行程序即可。

六、模型训练预处理

建立数据存放的文件夹

在darknet目录下创建myData文件夹,目录结构如下,将之前标注好的图片和xml文件放到对应目录下:

myData
  ...JPEGImages#存放图像
 
  ...Annotations#存放图像对应的xml文件
 
  ...ImageSets/Main # 存放训练/验证图像的名字(格式如 000001.jpg或者000001),里面包括train.txt。这里给出的格式是: 000000,因为下面的代码中给出了图像的格式。

将自己的数据集图片拷贝到JPEGImages目录下。

数据标注

打开labelImg软件,首先单击Open Dir,将目录改为JPEGImages文件夹所在位置;然后单击Change Save Dir,将目录改为Annotations所在文件夹。

随后,在右边Use default label前面方框内打上勾,后面输入当前标注种类的名称。

然后鼠标点到图片上,按下键盘w键,鼠标将变为一个十字框,此时从左上到右下框出目标物品所在位置,然后ctrl+s保存,d下一张。如此反复。当需要标别的种类时,只需要改Use default label后面输入框内的内容即可。

全部标注完成后建议检查一遍,很有可能有漏标、错标,这都将大大影响识别的准确度。

数据预处理

首先将visionAI中test.py文件拷贝到myData文件夹下,终端输入python3 test.py运行。

然后将my_labels.py文件拷贝到darknet文件夹下,打开文件,将classes内的内容修改为前面标注时的种类,如classes=["dog","cat","fish"],修改后运行程序。

配置文件修改

找到darknet/cfg目录下的voc.data文件,将其复制并重命名为my_data.data,修改其内容为

classes= 3 ##改为自己的分类个数
##下面都改为自己的路径
train  = /home/XXX/darknet/myData/myData_train.txt  
names = /home/XXX/darknet/myData/myData.names #稍后需要创建这个文件
backup = /home/XXX/darknet/myData/weights
# xxx为自己用户的名字

注意,darknet文件夹有可能也叫darknet-master,需要根据自己下载的版本情况定。

找到darknet/data中的coco.names,将其中内容改为自己标注的种类,一个种类一行,然后将其复制到myData目录下,并重命名为myData.names。

然后在myData目录下创建weights文件夹。

找到darknet/cfg目录下的yolov3-tiny.cfg(一般采用此模型,其他模型同理)文件,打开,ctrl-F搜索yolo,应该能找到两个,将每个[yolo]行上面的filters的值改为(种类数+5)*3,下面的classes改为种类数,总共要改两个filters和两个classes。然后找到文件最上面,修改batch参数为8或16(根据自身显卡显存决定),将max_batches改的大一些(自动停止训练迭代次数,但我们可以手动停止),比如10w次。

下载预训练权重

wget https://pjreddie.com/media/files/darknet53.conv.74

修改权重文件保存策略(可选)

找到darknet/examples目录,修改138行的参数,这就代表第几次迭代会保存weights文件,比如希望每500保存一次,就改为if (i%500 == 0)。为了防止忘记掉停止使得电脑内存溢出(这会导致严重后果),建议改为if (i<=20000 && i%500 == 0),具体参数看情况而定,但需要有一个最大值。

注意修改后需要重新编译。终端进入darknet目录

make clean
make -j8

七、开始训练

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

如果出现core dumped错误,可以考虑是否显是因为存溢出,此时可以将cfg文件中的batch调小,或者将random(ctrl+F搜索)改成0。

此时终端就会跳动目前训练的结果。

我们主要需要关注classes和obj后面的数据,classes代表分类准确度,obj代表框出物体的准确度,当这两个值均为0.95以上并保持一段时间时,代表模型训练效果很好,此时可以停止训练。某些时候可能无法到达,0.9以上也可以接受,视具体情况而定。但如果值非常不合理或者是nan,则需检查前面步骤的正确性。

八、测试

训练完成后,可以在myData/weights中看到保存的weights文件。一般来说,训练效果并不是单调的,会先变好,再变坏(对整个模型而言),这是因为训练次数过多会造成模型过拟合,简单来说就是对数据集里的识别效果很好,但对新拍的照片识别效果变差。因此,在比赛中,我们需要拍摄测试数据集,在训练时不当做训练集训练进去,训练完后测试各个weights看哪个效果最好。

终端输入:

./darknet detect cfg/yolov3-tiny.cfg weights/yolov3-tiny_xxxx.weights 1.jpg

查看结果。

训练完成后我们也可以将weights文件拷贝到别的电脑上,或者电脑上训练完拷贝到jetson nano中,对该设备的照片进行识别。

九、与其他模块整合

实际操作时,我们不可能每次在终端中输入来进行识别。darknet官方代码中的example文件夹下有示例代码,例如python可以通过import darknet来实现。我们在浙江省机器人竞赛中使用的代码使用了另一种方式,同时集成了拍照、识别、判断位置、串口发送数据,可以从以下仓库下载:

git clone https://github.com/zst1406217/Robot_competition.git

(目前仓库尚未开源,有需求者可以联系博主)

看完的朋友们如果觉得有帮助,麻烦给github点个免费的小星星哦~

你可能感兴趣的:(ubuntu,视觉检测,计算机视觉)