linux下用yolov3训练自己的数据集

参考链接: yolov3讲解以及训练自己的数据 - 知乎.

下载darknet并编译

git clone https://github.com/pjreddie/darknet  #下载darknet
cd darknet #转到darknet目录
vim Makefile #修改Makefile文件

按 i 进入编辑模式,窗口底端会显示 --插入–
linux下用yolov3训练自己的数据集_第1张图片

更改部分语句:

GPU=1 #如果电脑有GPU
CUDNN=1 #如果装了CUDNN
OPENCV=1 #如果装了OPENCV,可调用摄像头
...
...
ARCH= -gencode arch=compute_52,code=[sm_52,compute_52] \ #根据自己的GPU型号调整
#compute_30表示显卡的计算能力是3.0,几款主流GPU的compute capability列表:
#        GTX Titan x : 5.2
#        GTX 980      : 5.2
#        Tesla K80    : 3.7
#        Tesla K40    : 3.5
#        K4200         : 3.0
# 参考链接:http://www.luyixian.cn/news_show_18217.aspx
...
...
NVCC=/usr/local/cuda-10.0/bin/nvcc #路径改为自己的NVCC路径
...
...
# ifeq ($(GPU), 1)语句块下
COMMON+= -DGPU -I/usr/local/cuda-10.0/include/ #改为自己的路径
...
LDFLAGS+= -L/usr/local/cuda-10.0/lib64 -lcuda -lcudart -lcublas -lcurand #改为自己的路径


编辑完成后按 esc 退出编辑模式,输入 :wq! 保存并退出(注:输入法英文模式下才可成功键入,键入字符会显示在窗口底端)
linux下用yolov3训练自己的数据集_第2张图片

Makefile文件修改好后开始编译darknet
(在darknet目录下)

make

编译完成后,测试是否编译成功:

./darknet

如果显示:

usage: ./darknet <function>

则代表编译成功

——————————————————————

用官方提供的权重测试一下

下载官方提供的预训练模型 yolov3.weights

wget https://pjreddie.com/media/files/yolov3.weights

把它放在darknet文件夹下
运行语句测试

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

显示图片则成功
linux下用yolov3训练自己的数据集_第3张图片

————————————————————

处理自己的数据集

这里我用的是labelimg这个数据标注工具,轻量级,使用方便,可直接生成yolo格式的标签(txt文件)
linux下用yolov3训练自己的数据集_第4张图片
GitHub链接: labelimg.

mac系统下安装可见: MacOS深度学习数据标注软件labelimg安装.
————————————————————

准备训练

标注好自己的数据集后,将images文件夹(图片样本)和labels文件夹(所有标签)转移到darknet下的新文件夹mydata

在mydata下新建backup文件夹以存放生成的权重文件

另外需要生成train.txt和test.txt分别存放训练和测试样本的绝对路径
我在网上找了很多这种生成工具都不太适用,加上自己是个不会python的代码小白,投机取巧用mac的excel手动制作了
linux下用yolov3训练自己的数据集_第5张图片
将两个txt文件转移到darknet/mydata下

这里挖了个坑,后面训练时会报错:annot load images
原因是在其他系统下生成的txt文件的换行符有CR和LF
而linux系统的txt文件是只有LF一个换行符的unix格式,需要借助工具进行格式转换
用到的工具是notepad++(win系统)
工具链接: notepad++.
转换格式教程链接: YOLOV3无法加载图片"cannot load image".

将darknet/cfg下的voc.data和voc.names复制到mydata下来

修改voc.data

classes= 2  #类别数
train  = /home/username/darknet/mydata/train.txt #train.txt路径
test  = /home/username/darknet/mydata/test.txt  #test.txt路径
names = /home/username/darknet/mydata/voc.names #voc.names路径
backup = /home/username/darknet/mydata/backup/ 

修改voc.names
改为自己数据的类别名

将darknet/cfg下的yolov3-voc.cfg复制到mydata
修改

[net]
# Testing
# batch=1
# subdivisions=1    
# Training
batch=64            #GPU不够就改小:32、16……
subdivisions=64     #GPU不够就改大:8、16、32、64……
...                 
...
# 一共有三个yolo层,对每个yolo层和它上面的那个conv层进行修改
[convolutional]
size=1
stride=1
pad=1
filters=21         #filters = 3*(classes + 5)
activation=linear

[yolo]
mask = 0,1,2
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=2          #修改类别数
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1           

下载预训练模型darknet53.conv.74

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

放入mydata文件夹
————————————————————

开始训练

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


训练errors汇总

shared libraries

报错

./darknet: error while loading shared libraries: libhello.so.1: cannot open shared object file: No such file or directory

需要把/usr/local/cuda-10.0/lib64中的部分文件复制到/usr/local/lib目录下
执行语句

sudo cp /usr/local/cuda-10.0/lib64/libcudart.so.10.0/usr/local/lib/libcudart.so.10.0 && sudo ldconfig

sudo cp /usr/local/cuda-10.0/lib64/libcublas.so.10.0/usr/local/lib/libcublas.so.10.0 && sudo ldconfig

sudo cp /usr/local/cuda-10.0/lib64/libcurand.so.10.0/usr/local/lib/libcurand.so.10.0 && sudo ldconfig

如果还是有同样问题,比如缺失libcudnn.so.7,就将上面语句中的libcudart.so.10.0等文件替换为libcudnn.so.7,进行同样的操作

annot load images

"annot load image "/home/.../XXX.jpg

上面提到的换行符问题,用notepad++修改后问题解决

out of memory

修改yolov3-voc.cfg
减小batch
增大subdivision
(cpu不要被其他程序占用)

file exists

报错

    0 Cuda malloc failed
: File exists
darknet: ./src/utils.c:256: error: Assertion `0' failed.
已放弃 (核心已转储)

找了好久,只找到一篇文章有这个错误
链接: YOLO3+GPU(gtx1060).
感谢这位大佬救我于水火
修改yolov3-voc.cfg,把其中的batch和subdvisions值调小,并且要保证batch是subdivisions的整数倍,我之前的设置是16和64,然后都改成了64,成功


开始测试

1.单张图片测试

./darknet detector test ./mydata/voc.data ./mydata/yolov3-voc.cfg ./mydata/backup/yolov3-voc_final.weights ./test.jpg

成功后得到prediction结果图片文件存在darknet文件夹下,并在终端显示类名和置信度

2.批量图片测试

参考链接: YOLOv3批量测试图片并保存在自定义文件夹下.
按照链接中的代码(也可以直接复制替换)修改/darknet/examples下的detector.c文件
修改void test_detector函数,注意替换三处路径
在前面添加GetFilename函数,注意修改注释行中的6为自己的测试集样本文件名字符数(不含扩展名)
修改后重新编译,在/darknet下执行

make clean    //任何涉及到修改examples文件夹下的.c文件,修改后都要重新编译才会生效
make

编译完成后执行

./darknet detector test mydata/voc.data mydata/yolov3-voc.cfg ./mydata/backup/yolov3-voc_final.weights

权重加载完毕后会跳出“Enter Image Path:”,在后面输入测试样本绝对路径汇总的test.txt里,也就是mydata/voc.data文件里valid的路径
输入完成后回车,程序开始载入测试样本并输出结果,完成后就可以在你设定的输出文件夹里查看检测结果了

errors

1

STB Reason: can't fopen

将Makefile内的OPENCV值改成1,解决

2

create file bag failed!!

先在目标路径建好输出文件夹,解决

3

cannot load image".../xxx.jpg"

这里我烦恼了好几天最后终于发现是我text.txt文件的每一行结尾都多了一个“\”…

总结一下训练和测试时报错“cannot load image”的可能情况:

(1)
在win或mac系统下生成的txt文件转移到linux系统需要修改格式(因为换行符不统一)
可以使用notepad++这个软件来进行文档格式转换
也可以用vim编辑器:

sudo vim xxx.jpg
:set fileformat=unix
:set ff? //检查文件格式,如果显示fileformat=unix则表示转换完成
:wq!

(2)
测试样本的文件名后缀为.JPG,需要用文件转换器改为.jpg

(3)
test.txt里的绝对路径一定要仔细检查,不能有中文格式下的符号

结束!

你可能感兴趣的:(深度学习,linux)